关于如何在Linux下使用LCD5110参见上一篇使用GPIO的软模SPI控制LCD5110的使用帖,在此基础上需要添加屏幕绘点的函数:
- void LCD_DrawDot(int x,int y,int onoff)
- {
- int a = y / 8,b = y % 8;
- if(onoff)
- {
- LCD_Buffer[a * 84 + x] |= (0x01 << b);
- }
- else
- {
- LCD_Buffer[a * 84 + x] &= ~(0x01 << b);
- }
- WriteByte(0x80 | x,0);
- WriteByte(0x40 | a,0);
- WriteByte(LCD_Buffer[a * 84 + x],1);
- }
复制代码
使用的缓冲区是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.***51.net/table/gb2312 和 http://www.qqxiuzi.cn/zh/hanzi-gb2312-bianma.php两篇文章。 程序上有三个关于绘制字符的函数,第一个是绘制ASCII字符函数,第二个是绘制GB2312字符函数,最后一用于整合前面两个函数。
- void LCD_DrawAscii(int x,int y,unsigned short offset)
- {
- unsigned int i,j;
- for(i=0;i<16;i++)
- {
- for(j=0;j<8;j++)
- {
- if(FontData[offset*16 + i] & (0x80 >> j))
- LCD_DrawDot(x + j, y + i,1);
- else
- LCD_DrawDot(x + j,y + i,0);
- }
- }
- }
-
- void LCD_DrawHanzi(int x,int y,unsigned short offset)
- {
- unsigned int i,j;
- for(i=0;i<16;i++)
- {
- for(j=0;j<16;j++)
- {
- if(FontData[offset*32 + 0x5f0 + i*2 + j/8] & (0x80 >> j%8))
- LCD_DrawDot(x + j, y + i,1);
- else
- LCD_DrawDot(x + j,y + i,0);
- }
- }
- }
-
- void LCD_DrawText(int x,int y,char *text)
- {
- unsigned int i,j;
- for(i=0;text[i]!='\0';i++)
- {
- if(text[i] < 0xA0) //ASCII
- {
- LCD_DrawAscii(x,y,text[i] - ' ');
- x += 8;
- }
- else //chinese
- {
- LCD_DrawHanzi(x,y,(text[i]-0xA1)*94 + (text[++i] - 0xA1)); //这里i要自加1个因为汉子占用两个字节
- x += 16;
- }
- }
- }
复制代码
LCD_DrawText函数的具体功能是在x、y像素位置绘制一个字符串text,这个函数会根据字符的类型调用LCD_DrawAscii和LCD_DrawHanzi函数实现字符绘制功能,主函数测试程序如下:
- int fd;
- struct stat file_stat;
- if((fd = open("ASCII+GB2312.bin",O_RDWR)) < 0)
- {
- printf("open gb2312 failedrn");
- goto close;
- }
- if(stat("ASCII+GB2312.bin",&file_stat) < 0)
- {
- printf("stat failedrn");
- goto close;
- }
-
- printf("filesize:%drn",file_stat.st_size);
- FontData = (unsigned char *)malloc(file_stat.st_size);
-
- if(FontData == NULL)
- {
- printf("malloc failedrn");
- goto close;
- }
- read(fd,FontData,file_stat.st_size);
-
-
-
- LCD_DrawText(0,0,"汤权1994");
- LCD_DrawText(0,16,"123我是谁");
- LCD_DrawText(0,32,"中华人民");
复制代码
程序的执行效果如下:
|