一、常用汉字编码
1、GB2312
2、GB13000
3、GBK
4、BIG5(繁体)
二、汉字显示原理
汉字在液晶上的显示其实就是一些点的显示与不显示,这就相当于我们的笔一样,有笔经过的地方就画出来,没经过的地方就不画。所以要显示汉字,我们首先要知道汉字的点阵数据,这些数据可以由专门的软件生成。只要知道了一个汉字点阵的生成方法,那么我们在程序里面可以把这个点阵数据解析成一个汉字。
三、字符/汉字显示方法(PCtoLCD2002.exe)

汉字由点构成,点的形成需要有数据支撑,也就是一些数据告诉你所要形成的汉字点阵哪些地方需要加点哪些地方不用点(与像素点类似)。汉字由点构成,常见的是一个16位×8位、16位×16位的矩阵里面的点显示或不显示最终形成汉字。而点生成的顺序也有一定的规律,一个16×8的矩阵,第一列的前8位(一个字节)叫做高位,后8位叫做低位。
比如图中显示“0”,显示“0”的点阵为:0x00、0x00、0x07、0xF0、0x08、0x08、0x10 、0x04 、0x08 、0x08 、0x07、 0xF0 、0x00 、0x00
0x00表示第一列(从左往右)从上往下数八个点都为00000000(0表示没有点),0x00表示第一列从下往上数八个点也不显示。
0x07:00000111表示第二列,从上往下数8个位,这8个位从下往上将00000111依次显示(1表示有点);0xF0:11100000表示第二列,从下往上数8个位,这8个位从上往下将11100000依次显示。
我讲的看起来有点混乱,需要结合上图看一下。
显示“0”的点阵数据:
0x00、0x00、0x07、0xF0、0x08、0x08、0x10 、0x04 、0x08 、0x08 、0x07、 0xF0 、0x00 、0x00(16×8)
显示“开”的点阵数据:
0x01 0x00 0x41 0x01 0x41 0x02 0x41 0x0C 0x7F 0xF0 0x41 0x00 0x41 0x00 0x41 0x00 0x41 0x00 0x41 0x00 0x7F 0xFF 0x41 0x00 0x41 0x00 0x41 0x00 0x01 0x00 0x00 0x00
(16×16)
四、汉字内码(GBK/GB2312)—>查找点阵库—>解析—>显示
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开始存放)
点阵字库生成器:
注意:电脑端的字体大小与我们生成点阵大小关系为:fsize=disize×6/8;其中fsize为电脑端字体大小,disize是点阵大小(12、16、24)。所以16×16点阵大小对应的是12字体(16×16/8=12)
五、汉字显示程序思路
1、存字库(fontupd.c)
1)做好字库
2)将字库GBK12,GBK16,GBK24依次写入SPI FLASH连续地址:update_font();
3)字库写入完毕之后,做标记:ftinfo.fontok=0XAA;
2、显示汉字(text.c)
调用汉字Show_Str—>Show_Font—>Get_HzMat—>解析显示
Show_Font先根据编码取得字库取模,根据编码调用Get_HzMat,然后就取出了点阵数据(上述中显示“0”的数据),取出数据之后就会将其解析,解析之后就会显示在液晶上面。
六、程序部分详情

fontupd.c里面有一个字库初始化函数(main函数会调用):font_init()
- u8 font_init(void)
- {
- u8 t=0;
- W25QXX_Init();
- while(t<10)//连续读取10次,都是错误说明确实有问题,需要更新字库
- {
- t++;
- W25QXX_Read((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo));//读出ftinfo结构体数据
- if(ftinfo.fontok==0XAA) break;
- delay_ms(20);
- }
- if(ftinfo.fontok!=0XAA) return1;
- return 0;
- }
- //返回0字库完好,返回1字库缺失
如果汉字丢失,则去SD卡进行重新加载(初始化SD卡)然后调用update_font去更新字库。
(做汉字显示实验的时候需要将SD卡根目录下面的文件复制到SD卡)
显示一个汉字通过调用Show_Str调用到text.c:先区分中文和字符(如果是字符就调用LCD_ShowChar函数,如果是中文就调用Show_Font函数,Show_Font先根据汉字的编码查找点阵数据(通过Get_HzMat函数查找),Get_HzMat再查找编码,然后将编码解析)