点击(此处)折叠或打开
- /**
- * 点阵LCD 128*64显示应用程序
- * 主要实现中英文及数字的显示 包括16*16和12*16汉字库的使用及显示
- * Lzy 2012-9-13
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <linux/ioctl.h>
- #include "app12864.h"
- int InitLcd(int fd)
- {
- return ioctl(fd, LCD_IOC_INIT,NULL);
- }
- int ResetLcd(int fd)
- {
- return ioctl(fd, LCD_IOC_RESET,NULL);
- }
- int SetPage(int fd,unsigned char cx) // 设置行
- {
- return ioctl(fd, LCD_IOC_SET_PAGE,&cx);
- }
- int SetColumn(int fd,unsigned char cx) // 设置列
- {
- return ioctl(fd, LCD_IOC_SET_COLUMN,&cx);
- }
- int ClearScreen(int fd, unsigned char cx) // 清屏
- {
- return ioctl(fd, LCD_IOC_CLR,&cx);
- }
- int LcdDispChar(int fd, unsigned char ch) // 显示一个字符
- {
- unsigned char i;
- int ret=0;
-
- for(i=0; i<5; i++) // 一个字符是5个数据组成,这个要看取模方式来决定
- {
- ret = ioctl(fd, LCD_IOC_WRITE_DATA,&chardot8[(ch - 0x20) * 5 + i]);
- if(ret != 0)
- return ret;
- }
-
- return ret;
- }
- int LcdClrLine(int fd,unsigned char page,unsigned char column,unsigned char len) // 连续清除
- {
- unsigned char i;
- int ret = 0;
- SetPage(fd,page);
- SetColumn(fd,column);
-
- for(i=column; i<len; i++)
- {
- ret = ioctl(fd, LCD_IOC_WRITE_DATA,0x00);
- if(ret != 0)
- return ret;
- }
-
- return ret;
- }
- int LcdDispChars(int fd, int gLcdRow, int gLcdCol, unsigned char *str) // 显示字符串
- {
- unsigned char m;
- int ret = 0;
-
- while(*str)
- {
- SetPage(fd,gLcdRow);
- SetColumn(fd,gLcdCol);
-
- ret = LcdDispChar(fd, *str);
- if(ret != 0)
- break;
-
- gLcdCol += 6;
- if(gLcdCol > 132)
- {
- gLcdCol = 0;
- gLcdRow++;
- if(gLcdRow == 8)
- {
- ClearScreen(fd,0x00);
- gLcdRow = 0;
- }
-
- LcdClrLine(fd,gLcdRow,0,128);
- //ScreenDown8();
- }
- str++;
- }
-
- return ret;
- }
- /***************************************************** 汉字显示处理 ***********************************************************/
- /**
- * 数据重新组合,LCD采用的纵向 而字库是横向编码,需要转换他们的数据
- */
- void DataToMove(unsigned char const src[], unsigned char des[]) // 16 * 16字符转换
- {
- int i, j, k;
- unsigned char temp = 0;
- for(i=0; i<32; i++)
- {
- for(j=0; j<8; j++) // 转换一个字节
- {
- if(i < 8)
- k = j*2;
- else if(i < 16)
- k = j*2+1;
- else if(i < 24)
- k = j*2+16;
- else if(i < 32)
- k = j*2+17;
-
- if(src[k] & (1 << (7 - i%8)))
- temp |= (1 << j);
- }
- des[i] = temp; // 一个字节转换完成
- temp = 0;
- }
- }
- void DataToMove12(unsigned char const src[], unsigned char des[]) // 16 * 12字符转换
- {
- int i, j, k, t;
- unsigned char temp = 0;
- for(i=0; i<24; i++)
- {
- for(j=0; j<8; j++) // 转换一个字节
- {
- if(i < 8)
- {
- k = j*2;
- t = 7 - i%8;
- }
- else if(i < 12)
- {
- k = j*2+1;
- t = 7 - i%8;
- }
- else if(i < 20)
- {
- k = 16 + j*2;
- t = 7 - (i-12)%8;
- }
- else if(i < 24)
- {
- k = 17 + j*2;
- t = 7 - (i-20)%8;
- }
-
- if(i > 11 && j>3) // 只取低四位
- continue;
-
- if(src[k] & (1 << t))
- temp |= (1 << j);
-
- }
- des[i] = temp; // 一个字节转换完成
- temp = 0;
- }
- }
- /*******************************************************************************
- ** 函数名称:Bytes_Read_from_HZK
- ** 函数描述:从字库文件中读取一个汉字的字模点阵数据
- ** 入口参数:unsigned char *s 指向目标汉字的指针,
- char* const chs 用于存储字模的数组首地址
- ** 出口参数:无
- *******************************************************************************/
- void Bytes_Read_from_HZK(int len, unsigned char *s, char* const chs)
- {
- FILE *fp;
- unsigned long offset;
-
- offset=((s[0]-0xa1)*94+(s[1]-0xa1))*len*2; //根据内码找出汉字在HZK16中的偏移位置
- if(len == 16)
- {
- if((fp=fopen("HZK16","r"))==NULL)
- return; //打开字库文件
- }
- else if(len == 12)
- {
- if((fp=fopen("HZK12","r"))==NULL)
- return; //打开字库文件
- }
- fseek(fp,offset,SEEK_SET); //文件指针偏移到要找的汉字处
- fread(chs,len*2,1,fp); //读取该汉字的字模
-
- fclose(fp);
- }
- /*******************************************************************************
- ** 函数名称:Bytes_Display
- ** 函数描述:在屏幕上显示一个汉字
- ** 入口参数:char* const chs 存储了汉字点阵数据的数组首地址
- ** 出口参数:
- *******************************************************************************/
- int Bytes_Display(int len, int fd, int gLcdRow, int gLcdCol, char* const chs)
- {
- int i, ret;
- unsigned char array[32];
-
- if(len == 16)
- DataToMove(chs, array); // 先进行数据的转换
- else if(len == 12)
- DataToMove12(chs, array); // 先进行数据的转换
-
- SetPage(fd,gLcdRow);
- SetColumn(fd,gLcdCol);
-
- for(i=0; i<len;i++)
- {
- ret = ioctl(fd, LCD_IOC_WRITE_DATA,&array[i]);
- if(ret != 0)
- break;
- }
-
- SetPage(fd,gLcdRow+1);
- SetColumn(fd,gLcdCol);
-
- for(i=0; i<len;i++)
- {
- ret = ioctl(fd, LCD_IOC_WRITE_DATA,&array[i+len]);
- if(ret != 0)
- break;
- }
-
- return ret;
- }
- /**
- * 汉字显示 len:12 使用16*12 len:16使用16*16
- */
- int LcdDispChineseChars(int len, int fd, int gLcdRow, int gLcdCol, unsigned char *str) // 显示字符串
- {
- int ret;
- unsigned char chs[32]; //16*16=256个点
-
- while(*str)
- {
- Bytes_Read_from_HZK(len, &str[0],chs); //去字库中读取汉字字模
- ret = Bytes_Display(len, fd, gLcdRow, gLcdCol, chs); //在屏幕上显示这个汉字
- if(ret != 0)
- break;
-
- gLcdCol += len;
- if(gLcdCol > 132)
- {
- gLcdCol = 0;
- gLcdRow += 2;
-
- if(gLcdRow == 8)
- {
- ClearScreen(fd,0x00);
- gLcdRow = 0;
- }
-
- LcdClrLine(fd,gLcdRow,0,128);
- LcdClrLine(fd,gLcdRow+1,0,128);
- //ScreenDown8();
- }
- str += 2; // 一个汉字占两位
- }
- }
- int main(int argc, char **argv)
- {
- int fd;
- unsigned char s[]="罗志勇"; //要显示的汉字
-
- fd = open("/dev/graylcd", 0);
- if (fd < 0)
- {
- perror("open lcd12864 error");
- return 0;
- }
-
- InitLcd(fd);
- ClearScreen(fd,0);
-
- LcdDispChars(fd,1,0,"123, AbC!");
-
- LcdDispChineseChars(12, fd, 3, 1, s);
-
-
- close(fd);
-
- return 0;
- }
