微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > 嵌入式系统设计讨论 > 使用orangepi zero控制LCD5110显示中文(ASCII+GB2312字库)

使用orangepi zero控制LCD5110显示中文(ASCII+GB2312字库)

时间:10-02 整理:3721RD 点击:
关于如何在Linux下使用LCD5110参见上一篇使用GPIO的软模SPI控制LCD5110的使用帖,在此基础上需要添加屏幕绘点的函数:

  1. void LCD_DrawDot(int x,int y,int onoff)  
  2. {  
  3.     int a = y / 8,b = y % 8;  
  4.     if(onoff)  
  5.     {  
  6.         LCD_Buffer[a * 84 + x] |= (0x01 << b);  
  7.     }  
  8.     else  
  9.     {  
  10.         LCD_Buffer[a * 84 + x] &= ~(0x01 << b);  
  11.     }  
  12.     WriteByte(0x80 | x,0);  
  13.     WriteByte(0x40 | a,0);  
  14.     WriteByte(LCD_Buffer[a * 84 + x],1);  
  15. }  

复制代码

使用的缓冲区是84*6的,所以这里的LCD_DrawDot函数是在84*6的数组中进行绘制点,绘点不会影响与该像素点在同一个字节中的其他7个像素,使用的是或操作和与操作。有了这个绘点的基础函数就可以进行画线、画圆等函数,同样的也可以进行绘制汉字和ASCII码。

在绘制汉字和ASCII码之前需要了解一下GB2312和ASCII码表的编码规范,首先ASCII码比较简单,我制作的ASCII码字库是从‘ ’到‘~’的,全部字符如下: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~,使用的是8*16点阵,有点浪费空间其实6*12就够了貌似,但是为了配合汉字的16*16还是使用了8*16点阵。ASCII字库一共使用了1520字节的空间,存储在字库文件的前1520字节,后面的空间用于存储GB2312字库空间。GB2312的内容 太多了,网上一大把的就不贴出来了,但是这里要说说GB2312的编码规则。

ASCII码规定每个字符使用一个字节表示,并且该字节的范围为0x00到0x7F,所以当一个字符在0x00到0x7f之间的时候标志这个字符是一个ASCII字符,要从ASCII码库中提取对应的点阵数据显示。当一个字符的编码大于0xA0时则表示这个字符不是ASCII码字符了,是GB2312或者其他编码的字符例如UTF8等。程序中的汉字可能是GB2312编码也可能是其他编码格式,需要手动调节编辑器的编码方式,例如使用Notepad++时选择格式-》中文-》GB2312,这样才能保证程序中的中文是以GB2312的编码格式存储在字符串中的。GB2312编码规定一个字符是有两个字节组成的,两个字节的范围都是A1A1-FEFE,所以可以通过范围来判断是否是GB2312字符。GB2312的编码标准中有区码和位码,前者用于表示汉字所在的区,后者用于表示汉字所在区中的偏移量, 具体的编码规范可以参考:http://tools.jb51.net/table/gb2312 和 http://www.qqxiuzi.cn/zh/hanzi-gb2312-bianma.php两篇文章。

程序上有三个关于绘制字符的函数,第一个是绘制ASCII字符函数,第二个是绘制GB2312字符函数,最后一用于整合前面两个函数。

  1. void LCD_DrawAscii(int x,int y,unsigned short offset)  
  2. {  
  3.     unsigned int i,j;  
  4.     for(i=0;i<16;i++)  
  5.     {  
  6.         for(j=0;j<8;j++)  
  7.         {  
  8.             if(FontData[offset*16 + i] & (0x80 >> j))  
  9.                 LCD_DrawDot(x + j, y + i,1);  
  10.             else  
  11.                 LCD_DrawDot(x + j,y + i,0);  
  12.         }  
  13.     }  
  14. }  
  15.   
  16. void LCD_DrawHanzi(int x,int y,unsigned short offset)  
  17. {  
  18.     unsigned int i,j;  
  19.     for(i=0;i<16;i++)  
  20.     {  
  21.         for(j=0;j<16;j++)  
  22.         {  
  23.             if(FontData[offset*32 + 0x5f0 + i*2 + j/8] & (0x80 >> j%8))  
  24.                 LCD_DrawDot(x + j, y + i,1);  
  25.             else  
  26.                 LCD_DrawDot(x + j,y + i,0);  
  27.         }  
  28.     }  
  29. }  
  30.   
  31. void LCD_DrawText(int x,int y,char *text)  
  32. {  
  33.     unsigned int i,j;  
  34.     for(i=0;text[i]!='\0';i++)  
  35.     {  
  36.         if(text[i] < 0xA0)   //ASCII  
  37.         {  
  38.             LCD_DrawAscii(x,y,text[i] - ' ');  
  39.             x += 8;  
  40.         }  
  41.         else    //chinese  
  42.         {  
  43.             LCD_DrawHanzi(x,y,(text[i]-0xA1)*94 + (text[++i] - 0xA1));  //这里i要自加1个因为汉子占用两个字节  
  44.             x += 16;  
  45.         }  
  46.     }  
  47. }  

复制代码

LCD_DrawText函数的具体功能是在x、y像素位置绘制一个字符串text,这个函数会根据字符的类型调用LCD_DrawAscii和LCD_DrawHanzi函数实现字符绘制功能,主函数测试程序如下:

  1. int fd;  
  2. struct stat file_stat;  
  3. if((fd = open("ASCII+GB2312.bin",O_RDWR)) < 0)  
  4. {  
  5.     printf("open gb2312 failed\r\n");  
  6.     goto close;  
  7. }  
  8. if(stat("ASCII+GB2312.bin",&file_stat) < 0)  
  9. {  
  10.     printf("stat failed\r\n");  
  11.     goto close;  
  12. }  
  13.   
  14. printf("filesize:%d\r\n",file_stat.st_size);  
  15. FontData = (unsigned char *)malloc(file_stat.st_size);  
  16.   
  17. if(FontData == NULL)  
  18. {  
  19.     printf("malloc failed\r\n");  
  20.     goto close;  
  21. }  
  22. read(fd,FontData,file_stat.st_size);  
  23.   
  24.   
  25.   
  26. LCD_DrawText(0,0,"汤权1994");  
  27. LCD_DrawText(0,16,"123我是谁");  
  28. LCD_DrawText(0,32,"中华人民");  

复制代码

程序的执行效果如下:



Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top