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