目录
学习目标
本节我们需要学习的是汉字显示实验,之前一直只能显示英文和数字,我们今天就来显示一下汉字。其实原理和显示字符差不多,只不过引入了一个字库的概念,好了,就让我们开始吧!
原理
原理和我们的LCD1602是类似的,在此就不再赘述,链接如下。汉字在液晶上的显示其实就是一些点的显示与不显示,这就相当于我们的笔一样,有笔经过的地方就画出来,没经过的地方就不画。所以要显示汉字,我们首先要知道汉字的点阵数据,这些数据可以由专门的软件生成。只要知道了一个汉字点阵的生成方法,那么我们在程序里面可以把这个点阵数据解析成一个汉字。
GBK码
每个GBK码由2个字节组成,第一个字节为0X81~0XFE,第二个自己二分为两部分:0X40~0X7E和0X80~0XFE。
我们把第一个字节代表的意义称为区,GBK里面总共有126个区(0XFE-0X81+1),每个区里面有190个汉字(0XFE-0X80+0X7E-0X40+2),总共就有126×190=23940个汉字。
也就是说:将汉字细分为区,又将区进行排列,然后如果想要获得汉字的点阵数据,就可以先确定汉字所在区、再确定每个汉字所在区里面的顺序。
我们的点阵库只要按照这个编码规则从0X8140开始,逐一建立,每个区的点阵大小为每个汉字所用的字节数×190。这样,我们就可以得到在这个字库里面定位汉字的方法:
当GBKL<0X7F时:Hp=((GBKH-0x81)×190+GBKL-0X40)×(size×2)
当GBKL>0X7F时:Hp=((GBKH-0x81)×190+GBKL-0X41)×(size×2)
其中GBKH、GBKL分别代表GBK的第一个字节和第二个字节,size代表汉字字体的大小(比如16字体、12字体等),Hp则为对应汉字点阵数据在字库里面的起始地址(假设从0开始存放)。
生成字库
通过点阵字库生成器软件就行,注意我们的字体大小为12就行。
配置
存字库
- 做好字库
- 将字库GBK12,GBK16,GBK24依次写入SPI FLASH连续地址:update_font();
- 字库写入完毕之后,做标记:ftinfo.fontok=0XAA;
显示汉字
调用汉字Show_Str—>Show_Font—>Get_HzMat—>解析显示
代码
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "sram.h"
#include "malloc.h"
#include "usmart.h"
#include "sdio_sdcard.h"
#include "malloc.h"
#include "w25qxx.h"
#include "ff.h"
#include "exfuns.h"
#include "fontupd.h"
#include "text.h"
int main(void)
{
u32 fontcnt;
u8 i,j;
u8 fontx[2];//gbk码
u8 key,t;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
LCD_Init(); //LCD初始化
KEY_Init(); //按键初始化
W25QXX_Init(); //初始化W25Q128
usmart_dev.init(168); //初始化USMART
my_mem_init(SRAMIN); //初始化内部内存池
my_mem_init(SRAMCCM); //初始化CCM内存池
exfuns_init(); //为fatfs相关变量申请内存
f_mount(fs[0],"0:",1); //挂载SD卡
f_mount(fs[1],"1:",1); //挂载FLASH.
while(font_init()) //检查字库
{
UPD:
LCD_Clear(WHITE); //清屏
POINT_COLOR=RED; //设置字体为红色
LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
while(SD_Init()) //检测SD卡
{
LCD_ShowString(30,70,200,16,16,"SD Card Failed!");
delay_ms(200);
LCD_Fill(30,70,200+30,70+16,WHITE);
delay_ms(200);
}
LCD_ShowString(30,70,200,16,16,"SD Card OK");
LCD_ShowString(30,90,200,16,16,"Font Updating...");
key=update_font(20,110,16,"0:");//更新字库
while(key)//更新失败
{
LCD_ShowString(30,110,200,16,16,"Font Update Failed!");
delay_ms(200);
LCD_Fill(20,110,200+20,110+16,WHITE);
delay_ms(200);
}
LCD_ShowString(30,110,200,16,16,"Font Update Success! ");
delay_ms(1500);
LCD_Clear(WHITE);//清屏
}
POINT_COLOR=RED;
Show_Str(30,50,200,16,"探索者STM32F407开发板",16,0);
Show_Str(30,70,200,16,"GBK字库测试程序",16,0);
Show_Str(30,90,200,16,"陈怡是憨憨",16,0);
Show_Str(30,110,200,16,"2022年10月23日",16,0);
Show_Str(30,130,200,16,"按KEY0,更新字库",16,0);
POINT_COLOR=BLUE;
Show_Str(30,150,200,16,"内码高字节:",16,0);
Show_Str(30,170,200,16,"内码低字节:",16,0);
Show_Str(30,190,200,16,"汉字计数器:",16,0);
Show_Str(30,220,200,24,"对应汉字为:",24,0);
Show_Str(30,244,200,16,"对应汉字(16*16)为:",16,0);
Show_Str(30,260,200,12,"对应汉字(12*12)为:",12,0);
while(1)
{
fontcnt=0;
for(i=0x81;i<0xff;i++)
{
fontx[0]=i;
LCD_ShowNum(118,150,i,3,16); //显示内码高字节
for(j=0x40;j<0xfe;j++)
{
if(j==0x7f)continue;
fontcnt++;
LCD_ShowNum(118,170,j,3,16); //显示内码低字节
LCD_ShowNum(118,190,fontcnt,5,16);//汉字计数显示
fontx[1]=j;
Show_Font(30+132,220,fontx,24,0);
Show_Font(30+144,244,fontx,16,0);
Show_Font(30+108,260,fontx,12,0);
t=200;
while(t--)//延时,同时扫描按键
{
delay_ms(1);
key=KEY_Scan(0);
if(key==KEY0_PRES)goto UPD;
}
LED0=!LED0;
}
}
}
}
总结
这次实验比较简单,基本知识在51的时候已经学了,所以理解起来比较方便。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/82338.html