STM32 ILI9341驱动TFTLCD(十)LCD显示汉字

lcd显示汉字原理和显示字符一样,设置区域初始点,把汉字字模写入显存。但是汉字的数量比较多,以gb2312为例,gb2312 收录简化汉字及符号、字母、日文假名等共 7445 个图形字符,其中汉字占 6763 个,与ascii的总数量128不是在同一个数量级上。如果把汉字字模像ascii一样作为常量保存起来,那将会占用大量的cpu内存。为了节省cpu,这里把汉字字模存入flash中。
对于这么多的汉字,如果按照gb2312的表格来写入字模生成器就比较麻烦了,所以这里用另一个取模软件ts3,可以直接生成整个gb2312的字库。
打开ts3,生成字库步骤和之前生成单个字模的软件类似,这里不再介绍。
对于那么多的汉字,生成字库时间可能会比较长。
生成一个16号字体和一个24号字体的gb2312字库,然后把这两个文件通过双缓冲区接收文件的程序写入flash不常用的地址。flash一共8m,所以把两个文件放在比较靠后的7m地址处,先存储hz_16.dzk文件,hz_16.dzk文件一共255kb,所以直接分配一个扇区给它;hz_24.dzk文件在下一扇区首地址处开始写入,也就是7m+256kb处。
字库文件成功保存到flash后,开始编写显示汉字函数。
编写函数,有必要了解下gb2312的编码规则:
gb2312 规定,习惯上称第一个字节为,第二个字节为。gb2312-80 包含了大部分常用的一、二级汉字,和 9 区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位0xa1-0xfe,低位也是0xa1-0xfe;汉字从0xb0a1开始,结束于 0xf7fe。
gb2312 将代码表分为 94 个区,对应第一字节(0xa1-0xfe);每个区 94 个位(0xa1-0xfe),对应第二字节,两个字节的值分别为区号值和位号值加 32(2oh),因此也称为区位码。01-09 区为符号、数字区,16-87 区为汉字区(0xb0-0xf7),10-15 区、88-94 区是有待进一步标准化的空白区。gb2312 将收录的汉字分成两级:第一级是常用汉字计 3755 个,置于 16-55 区,按汉语拼音字母/笔形顺序排列;第二级汉字是次常用汉字计 3008 个,置于 56-87 区,按部首/笔画顺序排列。故而 gb2312 最多能表示 6763 个汉字。
所以只要有汉字的第一和第二个字节,就能得到所要的汉字在gb2312中的对应区位,然后找到flash中存放地址偏移字模对应区位的地址,读取出字模,就可以了。
//lcd显示16号汉字//ch:要写的汉字//pencolor:字符颜色//bcolor:背景色//mode: 0:填充背景色// 1:不填充背景色void lcd_showchinese_16(u8 x,u8 y,u8 *ch,u16 pencolor,u16 bcolor,u8 mode){ u8 buf[32]={0}; u32 add = 7*1024*1024; //16号汉字存放首地址 u8 i = 0,j = 0; u8 temp = 0; add += 32*(ch[0] - 0xa1)*94 + 32*(ch[1] - 0xa1); //对应汉字字模地址 w25q64_readbytes(add,buf,32); //从flash读取汉字的字模 for(i=0;i< 16;i++) { temp = buf[2*i]; for(j=0;j< 8;j++) //写左半部分 { if(temp & 0x80) { lcd_drawpoint(x,y,pencolor); } else { if(mode == 1) lcd_drawpoint(x,y,bcolor); } x++; temp < <=1; } temp = buf[2*i+1]; for(j=0;j< 8;j++) //写入右半部分 { if(temp & 0x80) { lcd_drawpoint(x,y,pencolor); } else { if(mode == 1) lcd_drawpoint(x,y,bcolor); } x++; temp < <=1; } x -= 16; y++; }}显示16号汉字函数只要在显示24号ascii值 的基础上,添加读取flash中字模部分就可以实现了。
主函数
#include stm32f4xx.h#include core_cm4.h#include ili9341.h#include lcd.h#include stdio.hint main(){ w25q64_init(); lcd_init(); //初始化lcd lcd_showchinese_16(100,100,(u8 *)郭,red,white,1); while(1);}屏幕显示如下
24号汉字函数
//lcd显示24号汉字//ch:要写的汉字//pencolor:字符颜色//bcolor:背景色//mode: 0:填充背景色// 1:不填充背景色void lcd_showchinese_24(u8 x,u8 y,u8 *ch,u16 pencolor,u16 bcolor,u8 mode){ u8 buf[72] = {0}; u32 add = 7*1024*1024 + 256*1024; //24号汉字存放地址 u8 i,j; u8 temp = 0; add += 72*(ch[0] - 0xa1)*94 + 72*(ch[1] - 0xa1); //对应汉字字模地址 w25q64_readbytes(add,buf,72); //从flash读取汉字的字模 for(i=0;i< 24;i++) { temp = buf[3*i]; for(j=0;j< 8;j++) //写入左半部分 { if(temp & 0x80) { lcd_drawpoint(x,y,pencolor); } else { if(mode == 1) lcd_drawpoint(x,y,bcolor); } x++; temp < <=1; } temp = buf[3*i+1]; for(j=0;j< 8;j++) //写入中半部分 { if(temp & 0x80) { lcd_drawpoint(x,y,pencolor); } else { if(mode == 1) lcd_drawpoint(x,y,bcolor); } x++; temp < <=1; } temp = buf[3*i+2]; for(j=0;j< 8;j++) //写入右半部分 { if(temp & 0x80) { lcd_drawpoint(x,y,pencolor); } else { if(mode == 1) lcd_drawpoint(x,y,bcolor); } x++; temp < <=1; } x -= 24; y++; }}主函数
#include stm32f4xx.h#include core_cm4.h#include ili9341.h#include lcd.h#include stdio.hint main(){ w25q64_init(); lcd_init(); //初始化lcd lcd_showchinese_16(100,100,(u8 *)郭,red,white,1); lcd_showchinese_24(90,130,(u8 *)舜,red,white,1); lcd_showchinese_24(105,160,(u8 *)贤,red,white,1); while(1);}屏幕显示如下
24号汉字的显示函数编写与16号汉字显示区别不大,这里就不再介绍了。

解读蓝牙四大解决方案领域最新趋势与预测
替代FR4 PCB的高速连接,有线背板成本与性能的博弈
因事因地制宜建设智慧城市的措施分析
SLA-M-1501B-A气密性检测设备的简单介绍
索尼WF-SP900真无线防水耳机体验 真无线运动耳机百搭更自在
STM32 ILI9341驱动TFTLCD(十)LCD显示汉字
手机测试软件:再一个“然并卵”?
无人机变得越来越受欢迎,美计划加强对消费级和商用无人机的监管
手机的电话簿项目
如何理解网络协议
OCT成像技术可改善青光眼的诊断和治疗
智慧路灯/智慧灯杆产值巨大,运营商如何布局智慧路杆项目
人工智能的发展会毁灭人类吗
钻孔与外型加工制程专业术语
PS5的详细规格曝光,5.5GB/s的SSD搭配AMD Zen 2架构
采用可编程逻辑器件的译码器优化实现方案
自制盆景雾化器,Ultrasonic Nebulizer
基于Au1200无线车载视频监控的设计与实现
独一无二的雷电SAN+NAS解决方案
华为推出基于ARM架构的服务器处理器鲲鹏920