STM32+OLED巧妙显示汉字英文
STM32+OLED巧妙显示汉字英文
目标:实现OLED_Print函数,可以在OLED屏幕上显示中英文和符号混合的任意字符串
汉字编码原理
ASCII码显示的原理这里不再说明,一般的OLED例程都有使用方法。下面说一下中文编码的原理。
在keil的环境使用的是GBK或者GB2312的编码方式,GBK编码汉字使用两个字节:
第一个字节为区码,第二个好像叫段码,区码是大于127的,段码不一定。
具体编码方式可以查阅资料:
下面编写一个简单的程序进行验证:
int main(void)
{
char *s = "哈h";
int i;
delay_init(); //延时函数初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200);
OLED_Init();//初始化OLED
OLED_Clear();
while(1)
{
for(i=0;i<strlen(s);i++)
printf("*(s+%d) = 0x%x\r\n", i,*(s+i));
delay_ms(1000);
}
}
串口输出的结果如下:
h
的ASCII值为0x68,那么前面的两个字节则为哈
这个汉字对应的GBK码,即为0xb9fe,使用内码查询软件查询验证:
利用结构体
知道了GBK汉字编码的方式,这么实现汉字的查找呢?答案是利用结构体进行封装。定义一种结构体类型:
成员Index
使用short类型用来存放汉字的GBK码,Msk
数组是char类型用来存放字模数据,因为是OLED所以使用char类型存放数据。
使用PctoLCD软件生成16x16大小的汉字字模数据,字模软件的设置如下:
在字体头文件中定义我们的汉字库数组,在每个字模数据前面加上'x'
,x为字模对应的汉字,类型要用前面创建的结构体类型:
这样这个结构体数组中的数据就会对应到结构体成员中的内码索引Index
和字模数组Msk
成员了,然后通过结构体成员Index的判断就可以实现对汉字的查找,查找到汉字之后就可以使用OLED将字模数据写入显示到屏幕上。
OLED_Print函数
编程思路:
通过对字符串s的取指操作,判断当前字节是否大于127,大于127说明对应的是汉字,将接下来的两个字节取出组合为汉字内码,通过内码查询字模数组中是否包含该字,查找到之后再将数据写入,显示到屏幕上。如果当前的字节小于128,则对应的是英文字符,直接使用例程的OLED_ShowChar函数写数据,就可以显示出来。
注意:这里汉字对应的是16x16大小,英文字符对应1608字体,坐标偏移需要注意。
/*
x:横坐标,0-127
y:0-7(中景园OLED)
*s:要显示的字符(中英文均可,前提是数组中包含的汉字)
*/
void OLED_Print(u8 x, u8 y, char *s)
{
unsigned char i,k,t,length;
unsigned short Index = 0;
length = strlen(s);//取字符串总长
//printf("length = %d\r\n",length);
for(k=0; k<length; k++)
{
//printf("k = %d\r\n",k);
if(*(s+k) <= 127){//小于128是ASCII符号
//printf("ascii\r\n");
OLED_ShowChar(x,y,*(s+k),16);
x += 8;//x坐标右移8
}else if(*(s+k) > 127){//大于127,为汉字,前后两个组成汉字内码
//printf("汉字\r\n");
Index = (*(s+k) << 8) | (*(s+k+1));//取汉字的内码
for(i=0;i<sizeof(CN16_Msk)/34;i++){//查数组
if(Index == CN16_Msk[i].Index){
//查询到这个字
OLED_Set_Pos(x,y);
for(t=0;t<16;t++)
OLED_WR_Byte(CN16_Msk[i].Msk[t],OLED_DATA);//写入字模
OLED_Set_Pos(x,y+1);
for(t=16;t<32;t++)
OLED_WR_Byte(CN16_Msk[i].Msk[t],OLED_DATA);
x += 16;
k += 1; //汉字占2B,跳过一个
}
}
}
}
}
结果
温度单位也是用中文的,但是在字模里不能显示,不用在意:
工程文件(stm32f103c8t6+iic OLED):https://download.csdn.net/download/qq_41790078/12336885
更多推荐
所有评论(0)