上一节初始化了OLED屏,使得它完成了清屏,现在驱动它在屏幕上打印字符串、汉字以及图片。
1.1 STM32+OLED屏初始化(一)
1.2 STM32+OLED屏显示字符串、汉字、图片(二)
1.3 STM32+OLED屏多级菜单显示(三)
1.4 STM32+OLED屏(软件IIC+位带+帧缓冲区)刷新速率优化(四)
1.制作字库
字符集:
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
要想屏幕上显示字符,需要相应的字库,现在先做一个字库。
打开取模软件pctolcd2002完美版,再点击选项,配置如下所选,点击确定。
点阵格式:阴码字体亮,阳码字体不亮
字符走向:逆向低位在前,顺向高位在前(主要看驱动IC的编码格式)、
取模方式:指字模图形的扫描方向
输出数制:生成字模的数的进制
每行显示数据:生成数组的大小,字符的长(页)x字符的宽(如8*16字体,2页*8列 = 16;如12*24字体,3页*12列 = 36;如16*32字体,4页*16列 = 64)
选择字库字体大小,最好选择8的倍数,因为64行已经分为8页(每页8行),如果不是8的倍数,就会显示到其他页去,操作会变得麻烦一些。
自命名字库名称
一个8x16的英文字库就完成了,字符在字库中的存取是二维数组Ascii_8*16[95][16];就拿字符 ' A ' 来说,字符 ' A ' 存在Ascii_8*16[33][0] ~ Ascii_8*16[33][16]之间
生成其他大小的字库
生成12*24的字库,首先要调节字体大小,其次要调节每行显示数据:24/8=3页,3*12=36,所以每行显示数据的点阵设置为36,最后,点击生成字模,复制粘贴到OLED_Fonnt.h文件中
三种大小不同的字库
字库中存取了三种字体,第一个比较特殊(在网上找的,但不完整),自己尝试着生成,发现自己生成的字体显示不清晰,如果有朋友有完整的,请@我分享我一份,其他两个是自己生成的
2.显示一个字符
显示字符串从一个字符开始,字符串只不过是一串字符,完成显示一个字符后再循环多次,就可以完成字符串显示了,字符显示先定义起始光点,再把字库中的数据写入,即可完成。就拿8*16字体来说,8列*16行(2页),所以要写2页(i < 2),字宽写8列(j < 8),第一页设置起始光点写入数据,第二页再设置起光点偏移一位( + i),因为字宽是8,数据再偏移八位( + i*8),完成显示
/**
* @brief OLED显示一个字符
* @param Line 行位置
* @param Column 列位置
* @param Fontsize 字体大小
* @param Char 要显示的一个字符,
* @retval 无
*/
void OLED_ShowChar(uint8_t Line, uint8_t Column, uint16_t Fontsize, char Char)
{
uint8_t i, j;
switch(Fontsize) {
case 8: {
OLED_SetCursor(Line, Column);
for (j=0; j<6; j++) {//字宽为6
OLED_Write_Data(Ascii_6x8[Char-' '][j]);
}
break;
}
case 16: {
for(i=0; i<2; i++) {
OLED_SetCursor(Line+i, Column); //循环2次显示上/下半部分内容
for (j=0; j<8; j++) {//字宽为8
OLED_Write_Data(Ascii_8x16[Char-' '][j+i*8]);
}
}
break;
}
case 24: {
for(i=0; i<3; i++) {
OLED_SetCursor(Line+i, Column); //循环3次显示上/中/下半部分内容
for (j=0; j<12; j++) {//字宽为12
OLED_Write_Data(Ascii_12x24[Char-' '][j+i*12]);
}
}
break;
}
}
}
6*8字体 ' A ', 8*16字体 ' A ', 12*24字体 ' A '
3.显示字符串
字符串的显示较为简单,在显示字符的基础上偏移一个字符的字宽,就可以了。如6*8字体的字宽是6,就偏移 + i*6;8*16字体的字宽是8,就偏移 + i*8;12*24字体的字宽是12,就偏移 + i*12
/**
* @brief OLED显示字符串
* @param Line 行位置
* @param Column 列位置
* @param Fontsize 字体大小
* @param String 显示字符串,
* @retval 无
*/
#include <string.h>
void OLED_ShowString(uint8_t Line, uint8_t Column, uint16_t Fontsize, const char* String)
{
uint8_t i, len;
len = strlen(String);//算出字符串长度
for(i=0; i<len; i++) {
switch(Fontsize) {
case 8:OLED_ShowChar(Line, Column+i*6, Fontsize, String[i]);
break;
case 16:OLED_ShowChar(Line, Column+i*8, Fontsize, String[i]);
break;
case 24:OLED_ShowChar(Line, Column+i*12, Fontsize, String[i]);
break;
}
}
}
6*8字体 " ABCD ", 8*16字体 " ABCD ", 12*24字体 " ABCD "
4.显示汉字
汉字的显示同理,先制作中文字库,但是中文汉字太多了,简单选择几个“ 点个赞吧!”显示即可,首先,制作汉字字库:因为字宽为16*2页 = 32
加入OLED_Font.h,自定义二维数组名称:
显示一个汉字,显示汉字和显示字符同理,只不过汉字的字宽是16,所以字宽写16列(j < 16),后续的数据偏移也自然是16位( + i*16);完成显示
/**
* @brief OLED显示汉字
* @param Line 行位置
* @param Column 列位置
* @param Chinese 显示汉字编号
* @retval 无
*/
void OLED_ShowChinese(uint8_t Line, uint8_t Column, uint8_t Chinese)
{
uint8_t i, j;
for(i=0; i<2; i++) {
OLED_SetCursor(Line+i, Column); //循环2次显示上/下半部分内容
for (j=0; j<16; j++) {//字宽为16
OLED_Write_Data(Chinese_16x16[Chinese][j+i*16]);
}
}
}
显示效果:
5.显示图片
同理,制作图源库,找一张自己喜欢的图片,选择画图工具打开
设置像素大小,进行裁剪
另存为BMP单色位图片
打开取模工具,选择图形模式,再打开刚刚制作的图片,生成字模
保存到OLED_Font.h中,删除所有的大括号,保存为一维数组
写法一样,依次取数
/**
* @brief OLED显示图片
* @param 无
* @retval 无
*/
void OLED_ShowImageBMG(void)
{
uint8_t i, j;
for(i=0; i<8; i++) {
OLED_SetCursor(0+i, 0); //循环8次显示8页内容
for (j=0; j<128; j++) {//字宽为8
OLED_Write_Data(ImageBMG64x128[j+i*128]);
}
}
}
显示效果:
6.编写RTC显示时钟
最后,再编写一个实时时钟完成显示,常规时钟配置就不展示了,直接上最终源码
/**
* @brief OLED显示RTC
* @param 无
* @retval 无
*/
void OLED_ShowRTC(void)
{
char buff[50];
RTC_Get_StdTime(RTC_GetCounter());
sprintf(buff,"%0.2d-%0.2d-%0.2d",RTC_CLOCK.hour, RTC_CLOCK.min, RTC_CLOCK.sec);
OLED_ShowString(4, 10, 24, buff);
sprintf(buff,"Date:%0.4d-%0.2d-%0.2d",RTC_CLOCK.year,RTC_CLOCK.mon,RTC_CLOCK.day);
OLED_ShowString(1, 6, 16, buff);
}
7.主函数
main.c函数
//#include "main.c"
int main(void)
{
OLED_Init();
Usart_Init();
printf("OLED显示字符串、汉字、图片\r\n");
// //显示字符串
// OLED_ShowString(0,0,8,"ABCD");
// OLED_ShowString(1,0,16,"ABCD");
// OLED_ShowString(3,0,24,"ABCD");
//
// //显示汉字
// OLED_ShowChinese(3,16*2,0);// 点
// OLED_ShowChinese(3,16*3,1);// 个
// OLED_ShowChinese(3,16*4,2);// 赞
// OLED_ShowChinese(3,16*5,3);// 吧
// OLED_ShowChinese(3,16*6,4);// !
// //显示图片
// OLED_ShowImageBMG();
//显示时钟
OLED_ShowRTC();
while (1) {
delay_ms(1000);
}
}
总结:历经万险终于完了,虽然最终的效果都实现了,但代码并不健壮。问题在于访问光点缺少越界保护,屏幕的范围在64*128之间,可是起始光点设置的范围却没有限制;除此之外,字符串的一部分超出显示范围没有进行换行换页,这些问题可能在今后造成巨大的错误。
源码分享:文章来源:https://www.toymoban.com/news/detail-816324.html
链接:https://pan.baidu.com/s/1ZpaEZhR0IvtqoiW-65ATKw?pwd=p08k
提取码:p08k文章来源地址https://www.toymoban.com/news/detail-816324.html
到了这里,关于STM32+OLED屏显示字符串、汉字、图片(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!