TFT彩屏常见汉字取模方式及相关驱动函数

今天在写智能灯光的界面,用的是STM32和3.2寸TFT 彩屏。
我们在设计一个显示界面时,常常需要考虑一下汉字字体的大小,常见的字体有像素值为16*16、24*24、32*32的,而有时候我们界面用的汉字也不是很多,或者没有SD卡,没有保存相应的汉字字库,这时候就可以自己用取模软件,取相应的几个汉字即可,我用的下面这款取模软件
TFT彩屏常见汉字取模方式及相关驱动函数_第1张图片

下面就是各个大小字体对应的参数:
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;
      }
    }   
}

你可能感兴趣的:(stm32)