×
嵌入式 > 技术百科 > 详情

单片机GUI编程显示汉字

发布时间:2020-06-06 发布时间:
|
单片机GUI编程显示汉字

int8 GetGB12_Address( int8 *ptr )                              

{

       int8 addr;      

      for (addr=0;addr     // 查找定位

      {

          if (( *ptr == gb12Dot[addr].Index[0]) && ( *(ptr+1) == gb12Dot[addr].Index[1]))

            {break;}

      }

      return addr;

}

 

GUI_PutHZ(x1,y1,(uint8*)gb12Dot[GetGB12_Address(ptr)].Msk,12, 12);

 

const typFNT_GB12 gb12Dot[] = { 

" ", 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

":", 0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,

      0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

"敏", 0x41,0x00,0x7F,0x00,0x81,0xE0,0x7F,0x40,0x55,0x40,0xFF,0x40,0x55,0x40,0x54,0x80,

      0x7E,0x80,0x05,0x40,0x1A,0x20,0x00,0x00,

"感", 0x01,0x40,0x7F,0xE0,0x41,0x00,0x7F,0x40,0x5D,0x40,0x54,0xA0,0x9D,0x60,0x82,0x20,

      0x54,0x40,0x52,0xA0,0x9F,0x80,0x00,0x00,

"度", 0x02,0x00,0x7F,0xE0,0x48,0x80,0x7F,0xE0,0x48,0x80,0x4F,0x80,0x40,0x00,0x5F,0x80,

      0x45,0x00,0x87,0x00,0xB8,0xE0,0x00,0x00

}

 

 

typedef struct     // 汉字字模数据结构

{

        int8 Index[2];    // 汉字内码索引

        int8 Msk[24];    // 点阵码数据

}typFNT_GB12;

 

 

void  GUI_PutHZ(uint32 x, uint32 y, uint8 *dat, uint8 hno, uint8 lno)

 uint8  i;

 

   for(i=0; i

   {  GUI_LoadLine(x, y, dat, hno);                                    // 输出一行数据

      y++;                                                                                 // 显示下一行

      dat += (hno>>3);                                                               //计算下一行的数据

      if( (hno&0x07)!=0 ) dat++;

   }

}

 

uint8  GUI_LoadLine(uint32 x, uint32 y, uint8 *dat, uint32 no)

   uint8   bit_dat;

   uint8   i;

   TCOLOR  bakc;

 

  

   if(x>=GUI_LCM_XMAX)

      return(0);

   if(y>=GUI_LCM_YMAX)

      return(0);

  

   for(i=0; i

   { 

      if( (i%8)==0 ) bit_dat = *dat++;

    

     

      if( (bit_dat&DCB2HEX_TAB[i&0x07])==0 )

            GUI_CopyColor(&bakc, back_color);

      else 

            GUI_CopyColor(&bakc, disp_color);

      GUI_Point(x, y, bakc);      

    

      if( (++x)>=GUI_LCM_XMAX )

            return(0);

   }

  

   return(1);

}

 

 

uint8  GUI_Point(uint8 x, uint8 y, TCOLOR color)

   if(x>=GUI_LCM_XMAX)

       return(0);

   if(y>=GUI_LCM_YMAX)

       return(0);

  

  

   if( (color&0x01) != 0 )

       gui_disp_buf[y][x>>3] |= DCB_HEX_TAB[x&0x07];

   else 

       gui_disp_buf[y][x>>3] &= (~DCB_HEX_TAB[x&0x07]);

 

  

   LCD_UpdatePoint(x, y);

   return(1);

}

 

uint8 const  DCB_HEX_TAB[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

 

TCOLOR  gui_disp_buf[GUI_LCM_YMAX][GUI_LCM_XMAX/8];

 

 

void  LCD_UpdatePoint(uint32 x, uint32 y)

{ // uint32  addr;

 

  uint32  addr11;

  uint32  addr22;

 

  

   //addr = y*(GUI_LCM_XMAX>>3) + (x>>3);

   addr11 = y*32%6 + (x>>3);

   addr22 =  y*32/256;

   //WriteCmd3(addr&0xFF, addr>>8,AddrSet);       // 置地址指针

   WriteCmd3(addr11, addr22,AddrSet);  // 置地址指针

   delay(10);

  

   WriteCmd2(gui_disp_buf[y][x>>3],DataWAddrI);

   delay(10);

  

}

 [page]

uint8 ReadSdate(void)

    uint8   checkbusy;

    //LCD_BUS = 0xff;

    OutData(0xff);

   

    //CD1=1;

    SCD1();

    //RD1=0;

    CRD1();

    //checkbusy=((IO0PIN&0x00ff0000)>>16);

       checkbusy = (GPIOD->IDR&0x00ff);

    //RD1=1;

    SRD1();

    return ( checkbusy ); 

}

 

void RWcheck(void)

 

     uint8   databusy;

     do

        {

           databusy=ReadSdate();

        }while( !(databusy&0x03) );

}

 

void AutoRcheck(void)

 

     uint8   databusy;

     do

        {

            databusy=ReadSdate();

        }while( !(databusy&0x04) );

}

 

void AutoWcheck(void)

  

     uint8   databusy;

     do

        {

            databusy=ReadSdate();

        }while( !(databusy&0x08) );

}

 

//写数据

void WriteData(uint8 dat)

 

    RWcheck();

    //CD1=0; 

    CCD1();              

    //LCD_BUS=dat;

    OutData(dat);

    //WR1=0;

    CWR1();

    //WR1=1;

    SWR1();

}

//写指令

void WriteCmd1(unsigned char cmd)

{

    RWcheck();;

    //CD1=1; 

    SCD1();    

    //LCD_BUS=cmd;

    OutData(cmd);

    //WR1=0;   

    CWR1();  

    //WR1=1;   

    SWR1();  

}

//先写数据再写指令

void WriteCmd2(uint8 dat,uint8 cmd)

{

    WriteData(dat);  

    WriteCmd1(cmd);    

}

//先写2组数据 再写1组指令

void WriteCmd3(uint8 dat1,uint8 dat2,uint8 cmd)

     

    WriteData(dat1);

 

    WriteData(dat2);;

    WriteCmd1(cmd);  

}

//数据自动写

void AutoWriteData( uint8 dat)

    AutoWcheck();;

    //CD1 = 0;   

    CCD1();

    //    LCD_BUS= dat;

    OutData(dat);

    //WR1=0;

    CWR1();

    //WR1=1;

    SWR1();

}

 

 

#define    OutData(dat)      GPIOD->BRR = 0xff<BSRR = (dat&0xff)<

 

 

#define  LCM_WR1     12

#define  SWR1()         GPIOB->BSRR = 1<

#define  CWR1()        GPIOB->BRR  = 1<

 

 

#define  LCM_RD1      13

#define  SRD1()          GPIOB->BSRR = 1<

#define  CRD1()          GPIOB->BRR  = 1<

 

 

#define  LCM_CE1      14

#define  SCE1()          GPIOB->BSRR = 1<

#define  CCE1()          GPIOB->BRR  = 1<

 

 

#define  LCM_CD1      15

#define  SCD1()          GPIOB->BSRR = 1<

#define  CCD1()          GPIOB->BRR  = 1<

 

图形显示的操作,最根本是对缓存的操作。

从应用层到底层的整个过程解析如下:

1、  调用写字函数在LCD上显示一个汉字。

GUI_PutHZ(x1,y1,(uint8*)gb12Dot[GetGB12_Address(ptr)].Msk,12, 12);

        参数参考上面的函数说明,其中要显示的字需要通过一个数组查找。

        该数组是一个结构体数组,每一个结构体中有两个分量,第一个是要显示的汉字,第二个是该汉字的字库。

        把需要写入的汉字及字库先存放在数组中,根据汉字的内容查找到相应字库。

2、  在GUI_PutHZ函数中调用了GUI_LoadLine(x, y, dat, hno);      

字库的实质是点矩阵,写字的实质就是把字库里安排的点阵写进缓存里。

这里调用画线函数,对矩阵进行操作。

3、  在GUI_LoadLine函数中调用了GUI_Point(x, y, bakc);

        对画线的操作,实质就是对线上的每一点进行操作。

        对于黑白屏来说,点的操作就是点亮与熄灭。

        对于彩色屏就是对像素位的操作来实现颜色的变化。

        所有的图案及字,都是不同颜色组合后给人的一种感官视觉。

        gui_disp_buf[y][x>>3] |= DCB_HEX_TAB[x&0x07];改变显示缓存中的数据。

        LCD_UpdatePoint(x, y);调用更新点函数实现刷屏。

4、  LCD_UpdatePoint函数中,调用了WriteCmd3和WriteCmd2函数

WriteCmd3这两个函数是对底层最基本的IO口操作,涉及硬件原理,涉及时序。

 

GUI的操作原理及程序例子基本完成。操作关键总结归纳如下:

        如何设计外围接口。

        如何编写底层驱动函数。

        如何根据需求编写应用软件。

 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
实时控制.安全.如何加速实现未来工厂落地?