LCD 显示文字与图片

本文详细介绍了在LCD屏幕上显示汉字和ASCII字符的两种方法。第一种方法涉及GB2312编码,通过计算汉字的区位码来定位字模并逐点绘制。第二种方法使用预先生成的字符数组进行输出。文中还提供了相关的代码示例,包括LCD初始化、延时函数以及串口通信的设置。


第一种方法:直接输汉字或字母等 直接输出

在GB2312编码中对所收汉字进行了“分区”处理,94个区,每区含有94个汉字/符号
 * 汉字由两个ASCII码组成,第一个减去160就是区码,第二个减去160就是位码
 * 在C中处理时,如"啊"的代码是B0A0 +1,定义*pStr = "啊",则*pStr = 176(B0),*(pStr+1) = 161(A0+1)
 * 第一个ASC 176 - 160(0xA0) = 16 ,第二个 ASC 161 - 160(0xA0) = 1,所以区位码为:1601
 * 按GB2312表顺序,从第一行开始向右每取8个点作为一个字节,如果最后不足8个点就补满8位。
 * 8位逐行取模,第一点为高位.16X16汉字一行就有两个字节 X 16行
 * 因字模数字式从0开始,所以 起始位为 ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32                  
 */
  /* 左侧字模起始地址 */
   pZKL = &__CHS[ ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32];
   /* 右侧字模起始地址 */ 
   pZKR = &__CHS[ ( ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32 ) + 1];

/*******************************************************************************
* 函数名称: Lcd_Print_ZW
* 功能描述: 在LCD屏幕上指定坐标点写汉字 NETC-陈建长.
* 输入参数: (unsigned int x,unsigned int y坐标),(unsigned char *pStr 单个汉字 如 “啊”),
             (unsigned int c,unsigned int bk_c颜色和区域颜色),unsigned int st  区域颜色选择
     st = 1 有 st = 0 无,在动态变化的情况下,如果没有区域颜色则前后信息叠加.   
* 输出参数: None        
* 返回参数: None
*******************************************************************************/

void Lcd_Print_ZW(unsigned int x,unsigned int y,unsigned char *pStr,unsigned int c,unsigned int bk_c,unsigned int st)
{
    unsigned short int i,j;     
    unsigned char *pZKL,*pZKR,mask,buf;   
    pZKL = &__CHS[ ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32];
    pZKR = &__CHS[ ( ( ( (*pStr - 0xA0) - 1 ) * 94 + ( *(pStr+1) - 0xA0 ) - 1 ) * 32 ) + 1];
    for( i = 0 ; i < 16 ; i++ )
       {
              /* 处理左侧显示 */
              mask = 0x80;
              buf = *pZKL;
     *(pZKL += 2);
              for( j = 0 ; j < 8 ; j++ )
              {
                     if( buf & mask )
                     {
                            PutPixel(x+j,y+i,c);
                     }
      else
      {
       if( st )
                  {
                      PutPixel(x+j,y+j,bk_c);
                  }
      }
                    
                     mask = mask >> 1;
              }     
             /* 处理右侧显示 */
              mask = 0x80;
              buf = *pZKR;
     *(pZKR += 2);
              for( j = 0 ; j < 8 ; j++ )
              {
                     if( buf & mask )
                     {
                            PutPixel(x+j + 8,y+i,c);
                     }
      else
      {
      if( st )
                     {
                         PutPixel(x+j + 8,y+i,bk_c);
                     }
     }
                     mask = mask >> 1;
              }                
       }

}


eg : 输出:“啊”

Lcd_Print_ZW(100, 100, "啊", 0x0, 0x0, 0);


第二种方法:用字符取模软件生成字符数组,读取输出

代码如下:

  1. *************************************************
  2. file name     LCD_hanzi
  3. function    显示16*16汉字 和 16*8 ASCII码字符
  4. 硬件设备    mini2440开发板
  5.         索尼X-35 3.5寸液晶屏
  6. lcd参数    宽和高 240x320
  7.         TFT 16bpp显示
  8. 完成时间    2011-08-10
  9. 作者        周茂夫
  10. problem    暂无
  11. 修改记录    暂无
  12. *************************************************/
  13. #define    GLOBAL_CLK        1

  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include "def.h"
  17. #include "option.h"
  18. #include "2440addr.h"
  19. #include "2440lib.h"
  20. #include "2440slib.h"
  21. #include "mmu.h"
  22. #include "profile.h"
  23. #include "memtest.h"
  24. #include "zifu.h"

  25. #define baudrate 115200

  26. #define    LCD_WIDTH    240
  27. #define    LCD_HEIGHT    320
  28. //#define LCD_CLKCAL    17    //这个我计算出来是17参考程序给的是4 测试俩个都可以
  29.                             //影响不大 测试25 30 都还可以
  30. #define LCD_CLKCAL    17        

  31. #define    LCD_RIGHT_MARGIN 25
  32. #define    LCD_LEFT_MARGIN 0
  33. #define    LCD_HSYNC_LEN 4

  34. #define    LCD_UPPER_MARGIN 0
  35. #define    LCD_LOWER_MARGIN 4
  36. #define    LCD_VSYNC_LEN 9

  37. #define    LCD_XSIZE    LCD_WIDTH
  38. #define    LCD_YSIZE    LCD_HEIGHT
  39. #define    SCR_XSIZE    LCD_WIDTH
  40. #define    SCR_YSIZE    LCD_HEIGHT

  41. extern const unsigned char sunflower_240x320[];
  42. extern const unsigned char GB2312Dot16X16[];
  43. volatile static unsigned short LCD_BUFFER[SCR_YSIZE][SCR_XSIZE];//LCD BUFFER

  44. #define M5D(n)        ((n)&0x1fffff)//设置显示缓存区时取地址的低21位
  45. #define    LCD_ADDR    ((U32)(LCD_BUFFER))    

  46. /********横向取模,字节不倒序,C51格式*******/
  47. unsigned char zhou[]=
  48. {
  49. 0x00,0x00,0x1F,0xFC,0x10,0x84,0x13,0xE4,0x10,0x84,0x10,0x84,0x17,0xF4,0x10,0x04,
  50. 0x13,0xE4,0x12,0x24,0x12,0x24,0x13,0xE4,0x22,0x24,0x20,0x04,0x40,0x14,0x80,0x08,
  51. } ;

  52. unsigned char mao[]=
  53. {
  54. 0x04,0x40,0x04,0x40,0xFF,0xFE,0x04,0x40,0x00,0xA0,0x00,0x90,0x3F,0xFE,0x20,0x80,
  55. 0x20,0x84,0x20,0x48,0x20,0x50,0x20,0x60,0x20,0xA0,0x43,0x12,0x4C,0x0A,0x80,0x04,
  56. } ;

  57. unsigned char Y[]=
  58. {
  59. 0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,
  60. } ;

  61. unsigned char zhao[]=
  62. {
  63. 0x00,0x00, 0xF7,0x7E, 0x95,0x04, 0x95,0x04,
  64. 0x96,0x74, 0x96,0x54, 0x95,0x54, 0x95,0x54,
  65. 0x95,0x54, 0xF5,0x54, 0x97,0x74, 0x04,0x04,
  66. 0x04,0x04, 0x04,0x04, 0x04,0x14, 0x04,0x08,
  67. } ;

  68. /**********************************
  69. void delay(int times)
  70. {
  71.     int i = 1000;
  72.     while(times--)
  73.     {
  74.         for(; i>0;--i)
  75.             ;
  76.     }
  77. }
  78. ************************************/
  79. /***********************************
  80. UART_int初始化led IO端口GPBCON5-8
  81. 初始化GPBHCON为串口通信
  82. 配置串口通信寄存器
  83. 配置中断寄存器
  84. ************************************/
  85. void UART_int_init(void)
  86. {
  87.     /********configuration LED IO port**********/
  88.     rGPBCON &=~(0xff<<10);
  89.     rGPBCON |= 0x55<<10;
  90.     
  91.     /*******configuration GPHCON to UART*******/
  92.     rGPHCON &=~(0xf<<4);
  93.     rGPHCON |= 0xa<<4;
  94.     
  95.     /****configuration UART0 communication register******/
  96.     rULCON0 = 0x03 ;                        //8-bits,1 stop bit, no parity
  97.     rUCON0 = 0x05 ;
  98.     rUBRDIV0= (int)(PCLK/baudrate/16)-1;    //configuration UART baudrate
  99.     
  100.     /*****clean interrupt bit clea RX_INT******/
  101.     rSUBSRCPND |= 0x1;
  102.     rSRCPND |= 1<<28;
  103.     rINTPND |= 1<<28;

  104.     /******open UART interrupt*********/
  105.     rINTSUBMSK &=~(0x1);
  106.     rINTMSK &=~(0x1<<28);    
  107. }

  108. //UART send byte
  109. void UART_send_byte(char Tx_data)
  110. {
  111.     while(!(rUTRSTAT0&0x2));//wait Txempty
  112.     if(Tx_data=='\n')        //Tx'\n'
  113.     {
  114.         rUTXH0 = 0x0d ;
  115.         while(!(rUTRSTAT0&0x2));
  116.         rUTXH0 = 0x0a ;
  117.     }
  118.     else
  119.     {
  120.         rUTXH0 = Tx_data ;
  121.     }
  122. }
  123. //UART sendstring
  124. void UART_send_string(const char*str)
  125. {
  126.     while(*str)
  127.     {
  128.         UART_send_byte(*str);
  129.         str++;
  130.     }
  131. }
  132. //UART receive byte
  133. void UART_receive_byte(void)
  134. {
  135.     char temp ;
  136.     
  137.     while(!(rUTRSTAT0&0x1));    //wait RX ready
  138.     
  139.     temp = rURXH0 ;
  140.     
  141.     switch(temp)            //测试发送单个字符
  142.     {
  143.         case 's': rGPBDAT&=~(0xf<<5); break;
  144.         case 'p': rGPBDAT|=(0xf<<5); break;
  145.     }
  146.     UART_send_byte(temp);
  147. }
  148. /*******************************************
  149. 中断处理函数
  150. 置1清除中断,注意顺序,先子中断后父中断
  151. 点亮led灯
  152. ********************************************/
  153. void __irq UART0_interrupt(void)
  154. {
  155.     /******clean interrupt bit*************/
  156.     rSUBSRCPND |= 0x1;
  157.     rSRCPND |= 1<<28;
  158.     rINTPND |= 1<<28;
  159.     
  160.     rGPBDAT &=~(0xf<<5);    //lighten led
  161.     UART_receive_byte();
  162. }
  163. /****************************************************************
  164. function    initialize LCD IO port VD[0:15] VM VLINE VCLK VFREAM
  165. input         void
  166. return        void
  167. *****************************************************************/
  168. static void Lcd_port_init(void)
  169. {
  170.     rGPCUP    = 0xffffffff ; //Disable Pull-up register
  171.     rGPCCON    = 0xaaaa02a8 ; //Initialize VD[7:0],VM,VFREAM,VLINE,VCLK
  172.     
  173.     rGPDUP    = 0xffffffff ; //Disable Pull-up register
  174.     rGPDCON    = 0xaaaaaaaa ; //Initialize VD[15:8]
  175.     
  176. }
  177. /****************************************************************
  178. function    configarution LCDCON1-5 LCDSADDR1-3 LCD INTERRUPT TPAL
  179.             etc register TFT 16bpp
  180. input         void
  181. return        void
  182. *****************************************************************/
  183. static void Lcd_init(void)
  184. {
  185.     rLCDCON1 = (LCD_CLKCAL<<8)|(3<<5)|(12<<1);    
  186.        rLCDCON2 = (LCD_UPPER_MARGIN << 24)|((LCD_HEIGHT- 1)<< 14)|(LCD_LOWER_MARGIN<< 6)|(LCD_VSYNC_LEN<< 0);
  187.        rLCDCON3 = (LCD_RIGHT_MARGIN << 19)|((LCD_WIDTH- 1)<< 8)|(LCD_LEFT_MARGIN<< 0);
  188.        rLCDCON4 = (LCD_HSYNC_LEN << 0);    
  189.        rLCDCON5 = (1<<11)|(1 << 9)|(1 << 8)|(1<<6)|(1 << 3)|(1 << 0);
  190.     
  191.     rLCDSADDR1    = ((LCD_ADDR>>22)<<21)|(M5D(LCD_ADDR>>1));
  192.     //LCDBASEL OFFSIZE=0,PAGEWIDTH=LCD_WIDTH, x2的原因 16bpp 每个像素点2个字节,>>1见地址对应关系 16bpp
  193.     rLCDSADDR2    = M5D((LCD_ADDR+ LCD_WIDTH* LCD_HEIGHT* 2)>>1);
  194.      rLCDSADDR3    = LCD_WIDTH ;
  195.      
  196.      rLCDINTMSK    |= 3;//屏蔽中断
  197.      rTCONSEL    = 0 ; //LPC3600 LCC3600 无效
  198.      rTPAL        = 0 ; //禁止临时调色板
  199.  }
  200. /****************************************************************
  201. function    Envid turn on or off
  202. input         onoff    1,Envid turn on
  203. return        void
  204. *****************************************************************/
  205. static void Lcd_EnvidOnOff(int onoff)
  206. {
  207.      if(onoff==1)
  208.          rLCDCON1 |= 1;//ENVIDON
  209.      else
  210.          rLCDCON1 &=~(1<<0);//ENBID OFF
  211. }
  212. /****************************************************************
  213. function    LCD power enable
  214. input         pwren    1, enable lcd power
  215. return        void
  216. *****************************************************************/
  217. static void Lcd_PowerEnable(int pwren)
  218. {
  219.      rGPGUP    |=(1<<4);//Pull-up Disable
  220.      rGPGCON    |=(3<<8);//GPG4is LCD_PWREN
  221.      
  222.      rLCDCON5&=~(1<<5);    //invpwren 正常极性
  223.      rLCDCON5 = rLCDCON5 & ~(1<<3)|(pwren<<3);    //PWREN 使能
  224. }
  225. /****************************************************************
  226. function    Filling sole colour into LCD background
  227. input         c         colour
  228. return        void
  229. *****************************************************************/
  230. static void Lcd_FillCor(U16 c)
  231. {
  232.      unsigned int x,y;
  233.      for(y=0; y<SCR_YSIZE; y++)
  234.      {
  235.          for(x=0; x<SCR_XSIZE; x++)
  236.          {
  237.              LCD_BUFFER[y][x]= c;        
  238.          }
  239.      }
  240. }
  241. /****************************************************************
  242. function    Paint picture
  243. input         x0 y0            assign start bit
  244.             level vertical    the wide and high of picture
  245.             *bmp            the picture string
  246. return        void
  247. *****************************************************************/
  248. static void Paint_BMP(int x0,int y0,int level, int vertical, const unsigned char *bmp)
  249. {
  250.      int x, y;
  251.      U32 col ;
  252.      int p = 0;
  253.      
  254.      for(y=0; y<vertical; y++)
  255.      {
  256.          for(x=0; x<level; x++)
  257.          {
  258.              col = bmp[p+1]|(bmp[p]<<8);    //16bpp 一个像素点用俩个字节
  259.              if(((x0+x)<SCR_XSIZE)&&((y0+y)<SCR_YSIZE))
  260.                  LCD_BUFFER[y0+y][x0+x]= col ;
  261.              p += 2;
  262.          }
  263.      }
  264. }
  265. /****************************************************************
  266. function    Display 像素点
  267. input         x y    display start bit
  268.             col        color of the char
  269. return        void
  270. *****************************************************************/
  271. static void PutPixel(U32 x, U32 y, U16 col)
  272. {
  273.     LCD_BUFFER[y][x]= col;
  274. }
  275. /****************************************************************
  276. function    Display 汉字 hzk16 16*16
  277. input         x y    display start bit
  278.             col        color of the char
  279.             ch[]    字模数组
  280. return        void
  281. *****************************************************************/
  282. static void Draw_Text16(U32 x, U32 y, U16 col,const unsigned char ch[])
  283. {
  284.     unsigned short i, j ;
  285.     unsigned char mask, tem ;
  286.     for(i=0; i<16; i++)
  287.     {
  288.         mask= 0x80 ;
  289.         tem    = ch[i*2];    //俩个字节一组16位,取第一个字节
  290.         for(j=0; j<8; j++)
  291.         {
  292.             if(tem& mask)
  293.             {
  294.                 PutPixel(x+j, y+i, col);
  295.             }
  296.             mask = mask >> 1 ;
  297.         }
  298.         
  299.         mask = 0x80 ;
  300.         tem = ch[i*2+ 1];
  301.         for(j=0; j<8; j++)
  302.         {
  303.             if(tem& mask)
  304.             {
  305.                 PutPixel(x+j+8, y+i, col);
  306.             }
  307.             mask = mask >> 1 ;
  308.         }
  309.     }
  310. }
  311. /****************************************************************
  312. function    Display ASCII 字符 16*8
  313. input         x y    display start bit
  314.             col        color of the char
  315.             ch[]    字模数组
  316. return        void
  317. *****************************************************************/
  318. static void Draw_ASCII(U32 x, U32 y, U16 col,const unsigned char ch[])
  319. {
  320.     unsigned short i, j ;
  321.     unsigned char temp, mask ;
  322.     for(i=0; i<16; i++)
  323.     {
  324.         mask = 0x80 ;
  325.         temp = ch[i];
  326.         for(j=0; j<8; j++)
  327.         {
  328.             if(mask& temp)
  329.             {
  330.                 PutPixel(x+j, y+i, col);
  331.             }
  332.             mask = mask >> 1 ;
  333.         }
  334.     }
  335. }
  336. /****************************************************************
  337. function    Display 汉字字符 16*16
  338. input         x y    display start bit
  339.             col        color of the char
  340.             str[]    字符数组
  341.             strlen 字符串长度 字节表示
  342. return        void
  343. *****************************************************************/
  344. static void Draw_ch_lib(U32 x, U32 y, U16 col,const unsigned char str[], unsignedint strlen)
  345. {
  346.     int loc, i;
  347.     unsigned char qh, wh ;
  348.     const unsigned char *pchlib ;
  349.     
  350.     for(loc=0, i=0; i<strlen; i++)
  351.     {
  352.         if(str[i]& 0x80)
  353.         {
  354.             qh = str[i]- 0xa0;
  355.             wh = str[i+1]- 0xa0;
  356.             pchlib = &GB2312Dot16X16[( 94*(qh-1)+(wh-1)-1410)*32];
  357.             Draw_Text16( x+loc, y, col, pchlib);
  358.             i++;
  359.             loc += 16;
  360.         }
  361.     }
  362. }
  363. /*******************************************************************
  364. 串口UART是挂在PCLK总线上的,需要设置PCLK时钟,即需要设置2440时钟。
  365. 首先需要设置PLLCON寄存器设置CPU时钟(FCLK),然后设置FCLK HCLK PCLK的
  366. 分频比,确定好PCLK时钟。
  367. *****************************************************************/
  368. int Main(void)
  369. {
  370.     unsigned int length ;
  371.     unsigned char display[]="啊周茂夫是个大笨蛋";
  372.     /*****************【CLOCK】******************/
  373.     MMU_Init();
  374.     ChangeMPllValue(127,2,1);        //405MHZ
  375.     ChangeClockDivider(13,12);//1:3:6    
  376.     
  377.     /**************【UART】**********************/
  378.     UART_int_init();
  379.     UART_send_string("wo zhen de hen yun si \n");    
  380.     pISR_UART0 = (U32)UART0_interrupt ;
  381.     /*************【LCD】************************/
  382.     Lcd_port_init();
  383.     Lcd_init();
  384.     Lcd_PowerEnable(1);
  385.     Lcd_EnvidOnOff(1);
  386.     UART_send_string("LCD initial \n");
  387.     
  388.     Lcd_FillCor(0xffff);
  389.     Draw_Text16(16, 20, 0x0, zhou)     ;
  390.     Draw_Text16(32, 20, 0x0, mao)     ;     //汉字后需要16位
  391.     Draw_ASCII (48, 20, 0x0, Y)     ;
  392.     Draw_ASCII (56, 20, 0x0, Y)     ;
  393.     Draw_Text16 (100, 20, 0x0, zhao)     ;    
  394.     Draw_Text16(80, 20, 0x0, zhou)     ;    
  395.     
  396.     length = sizeof(display)- 1;     //用sizeof可以直接算出数组占内存的字节数,减去1
  397.                                     //字符串结束符占一个字节
  398.     Draw_ch_lib(10, 100,0x0, display, length);

  399.     while(1)
  400.     {
  401.         //Lcd_FillCor((0x00<<11)|(0x00<<5)|(0x00<<0));     //clear screen
  402.         //Paint_BMP(0,0,240,320,sunflower_240x320);            //filling picture sunflower
  403.     }
  404.     return 0 ;
  405. }


字符与图片取模软件 : 点击打开链接

GB2312汉字编码表与其字符数组:  文档在这


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值