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.h"
int 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.h"
int 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號漢字顯示區別不大,這里就不再介紹了。
評論
查看更多