LCD顯示漢字原理和顯示字符一樣,設(shè)置區(qū)域初始點,把漢字字模寫入顯存。但是漢字的數(shù)量比較多,以GB2312為例,GB2312 收錄簡化漢字及符號、字母、日文假名等共 7445 個圖形字符,其中漢字占 6763 個,與ASCII的總數(shù)量128不是在同一個數(shù)量級上。如果把漢字字模像ASCII一樣作為常量保存起來,那將會占用大量的CPU內(nèi)存。為了節(jié)省CPU,這里把漢字字模存入flash中。
對于這么多的漢字,如果按照GB2312的表格來寫入字模生成器就比較麻煩了,所以這里用另一個取模軟件ts3,可以直接生成整個GB2312的字庫。
打開ts3,生成字庫步驟和之前生成單個字模的軟件類似,這里不再介紹。
對于那么多的漢字,生成字庫時間可能會比較長。
生成一個16號字體和一個24號字體的GB2312字庫,然后把這兩個文件通過雙緩沖區(qū)接收文件的程序?qū)懭雈lash不常用的地址。flash一共8M,所以把兩個文件放在比較靠后的7M地址處,先存儲hz_16.DZK文件,hz_16.DZK文件一共255Kb,所以直接分配一個扇區(qū)給它;hz_24.DZK文件在下一扇區(qū)首地址處開始寫入,也就是7M+256Kb處。
字庫文件成功保存到flash后,開始編寫顯示漢字函數(shù)。
編寫函數(shù),有必要了解下GB2312的編碼規(guī)則:
GB2312 規(guī)定<對任意一個圖形字符都采用兩個字節(jié)表示,每個字節(jié)均采用七位編碼表示>,習(xí)慣上稱第一個字節(jié)為<高字節(jié)>,第二個字節(jié)為<低字節(jié)>。GB2312-80 包含了大部分常用的一、二級漢字,和 9 區(qū)的符號。該字符集是幾乎所有的中文系統(tǒng)和國際化的軟件都支持的中文字符集,這也是最基本的中文字符集。其編碼范圍是高位0xa1-0xfe,低位也是0xa1-0xfe;漢字從0xb0a1開始,結(jié)束于 0xf7fe。
GB2312 將代碼表分為 94 個區(qū),對應(yīng)第一字節(jié)(0xa1-0xfe);每個區(qū) 94 個位(0xa1-0xfe),對應(yīng)第二字節(jié),兩個字節(jié)的值分別為區(qū)號值和位號值加 32(2OH),因此也稱為區(qū)位碼。01-09 區(qū)為符號、數(shù)字區(qū),16-87 區(qū)為漢字區(qū)(0xb0-0xf7),10-15 區(qū)、88-94 區(qū)是有待進(jìn)一步標(biāo)準(zhǔn)化的空白區(qū)。GB2312 將收錄的漢字分成兩級:第一級是常用漢字計 3755 個,置于 16-55 區(qū),按漢語拼音字母/筆形順序排列;第二級漢字是次常用漢字計 3008 個,置于 56-87 區(qū),按部首/筆畫順序排列。故而 GB2312 最多能表示 6763 個漢字。
所以只要有漢字的第一和第二個字節(jié),就能得到所要的漢字在GB2312中的對應(yīng)區(qū)位,然后找到flash中存放地址偏移字模對應(yīng)區(qū)位的地址,讀取出字模,就可以了。
//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); //對應(yīng)漢字字模地址
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號漢字函數(shù)只要在顯示24號ASCII值 的基礎(chǔ)上,添加讀取flash中字模部分就可以實現(xiàn)了。
主函數(shù)
#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號漢字函數(shù)
//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); //對應(yīng)漢字字模地址
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++;
}
}
主函數(shù)
#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號漢字的顯示函數(shù)編寫與16號漢字顯示區(qū)別不大,這里就不再介紹了。
評論