TFT彩屏常見漢字取模方式及相關驅動函式
今天在寫智慧燈光的介面,用的是STM32和3.2寸TFT 彩屏。
我們在設計一個顯示介面時,常常需要考慮一下漢字字型的大小,常見的字型有畫素值為16*16、24*24、32*32的,而有時候我們介面用的漢字也不是很多,或者沒有SD卡,沒有儲存相應的漢字字型檔,這時候就可以自己用取模軟體,取相應的幾個漢字即可,我用的下面這款取模軟體
下面就是各個大小字型對應的引數:
16*16:宋體12,即小四,實際大小16*16,剛剛好
24*24:宋體18,即小二,實際大小24*24,剛剛好
32*32:宋體24,即小一,實際大小32*33,所以多出來32個二進位制,即四個位元組,刪去最後面四個位元組即可(因為一般都是零,影響不大)
注意:選擇橫向取模,C51方式取模。
接下來就是相關底層驅動函式的編寫,我們需要將漢字及相應而二進位制編碼存到一個頭檔案中,我是分別命名了以下三個標頭檔案,用來儲存不同字型,hz16x16.h、hz16x16.h、hz16x16.h
具體程式碼如下:
#ifndef HZ16x16_H
#define HZ16x16_H
// ------------------ 漢字字模的資料結構定義 ------------------------ //
struct typFNT_HZ16 // 漢字字模資料結構
{
unsigned char Index[3 ]; // 漢字內碼索引 存放內碼 如"碩" 但是一個字要兩個位元組表示
unsigned char Msk[32]; // 點陣碼資料 存放內碼後對應的 點陣序列 每個字需要32個位元組的點陣序列
};
/////////////////////////////////////////////////////////////////////////
// 漢字字模表 //
// 漢字型檔: 宋體16.dot,橫向取模左高位,資料排列:從左到右從上到下 //
/////////////////////////////////////////////////////////////////////////
/*這個結構,很簡單的:一個是內碼,一個點陣序列,
以前的點陣庫是按內碼順序放的,不需要內碼索引的,
如果只放部分漢字,就需要內碼索引了。
一般內碼兩個位元組就行了,多用1個位元組是加了個尾0而已,
這樣,漢字內碼處直接放漢字字元淳塗桑? */
struct typFNT_HZ16 codeHZ_16[] = // 資料表
{
/*-- 文字: 雲 --*/
/*-- 宋體12; 此字型下對應的點陣為:寬x高=16x16 --*/
"雲",0x00,0x00,0x00,0x30,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x0C,0xFF,0xFE,0x03,0x00,
0x07,0x00,0x06,0x40,0x0C,0x20,0x18,0x10,0x31,0xF8,0x7F,0x0C,0x20,0x08,0x00,0x00,
};
#endif
程式很簡單,可見漢字及相關二進位制編碼是用的結構體來儲存的,
成員如下:
unsigned char Index[3]; // 漢字內碼索引, 存放內碼 如”碩” 但是一個字要兩個位元組表示,這裡多了一個,就是加了零
unsigned char Msk[32]; // // 點陣碼資料 存放內碼後對應的 點陣序列 每個字需要32個位元組的點陣序列(24*24字型和32*32字型,有所區別,自己算出即可)
接下來就是在TFT彩屏顯示的程式編寫,程式碼如下:
//寫入單個漢字 16*16
//x,y:起點座標
// c[2] 漢字
//dcolor 字型顏色
//bgcolor 背景顏色
void PutHZ1616(unsigned short x, unsigned short y, unsigned char c[2], unsigned int dcolor,unsigned int bgcolor)
{
unsigned int i,j,k;
//c[2] 把要顯示的字 以兩個位元組的形式放入 陣列c中
LCD_Set_Window(x,y,16,16);
LCD_SetCursor(x,y);
LCD_WriteRAM_Prepare();
for (k=0;k<64;k++)
{ //64標示自建漢字型檔中的個數,迴圈查詢內碼 一個漢字需要兩個位元組
if ((codeHZ_16[k].Index[0]==c[0])&&(codeHZ_16[k].Index[1]==c[1])) //尋找對應漢字
{
for(i=0;i<32;i++)
{
unsigned short m=codeHZ_16[k].Msk[i];
for(j=0;j<8;j++)
{
if((m&0x80)==0x80)
{
LCD_WR_DATA(dcolor);
}
else
{
LCD_WR_DATA(bgcolor);
}
m<<=1;
}
}
}
}
}
關鍵程式碼分析:
第一個for迴圈,就是查詢自己編寫的字型檔裡的漢字,可以根據自己漢字多少改寫。
if ((codeHZ_16[k].Index[0]==c[0])&&(codeHZ_16[k].Index[1]==c[1])) 這句程式碼意思就是對應於前面標頭檔案裡的編碼,尋找對應漢字
再接下來一個迴圈——for(i=0;i<32;i++) ,總共32個char型資料,即32個位元組,迴圈。
for(j=0;j<8;j++) ——這句程式碼以後,就是將1處寫前景色,0處寫背景色。
還有就是顯示多個漢字函式
//顯示多個漢字或字元 16*16
//在指定位置顯示一個字元大小16*16)
//dcolor為內容顏色,gbcolor為背靜顏色 !='\0'
void showhz16str(unsigned int x1,unsigned int y1,unsigned char *str,unsigned int dcolor,unsigned int bgcolor)
{
unsigned char l=0;
while(*str)
{
if(*str<0x80)
{
LCD_ShowString1(x1,y1,16,(unsigned char*)str);
x1+=7;
str++;
}
else
{
PutHZ1616(x1+l*8,y1,(unsigned char*)str,dcolor, bgcolor);
str+=2;l+=2;
}
}
}