Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7723370
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2012-09-14 11:16:46

点击(此处)折叠或打开

  1. /**
  2.  * 点阵LCD 128*64显示应用程序
  3.  * 主要实现中英文及数字的显示 包括16*16和12*16汉字库的使用及显示
  4.  * Lzy 2012-9-13
  5.  */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <sys/ioctl.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #include <linux/ioctl.h>
  13. #include "app12864.h"

  14. int InitLcd(int fd)
  15. {
  16.     return ioctl(fd, LCD_IOC_INIT,NULL);
  17. }

  18. int ResetLcd(int fd)
  19. {
  20.     return ioctl(fd, LCD_IOC_RESET,NULL);
  21. }

  22. int SetPage(int fd,unsigned char cx) // 设置行
  23. {
  24.     return ioctl(fd, LCD_IOC_SET_PAGE,&cx);     
  25. }

  26. int SetColumn(int fd,unsigned char cx) // 设置列
  27. {
  28.     return ioctl(fd, LCD_IOC_SET_COLUMN,&cx);
  29. }

  30. int ClearScreen(int fd, unsigned char cx) // 清屏
  31. {
  32.     return ioctl(fd, LCD_IOC_CLR,&cx);
  33. }

  34. int LcdDispChar(int fd, unsigned char ch) // 显示一个字符
  35. {
  36.     unsigned char i;
  37.     int ret=0;
  38.     
  39.     for(i=0; i<5; i++) // 一个字符是5个数据组成,这个要看取模方式来决定
  40.     {
  41.         ret = ioctl(fd, LCD_IOC_WRITE_DATA,&chardot8[(ch - 0x20) * 5 + i]);
  42.         if(ret != 0)
  43.          return ret;
  44.     }
  45.     
  46.     return ret;
  47. }

  48. int LcdClrLine(int fd,unsigned char page,unsigned char column,unsigned char len) // 连续清除
  49. {
  50.      unsigned char i;
  51.      int ret = 0;

  52.      SetPage(fd,page);
  53.      SetColumn(fd,column);
  54.      
  55.      for(i=column; i<len; i++)     
  56.      {
  57.       ret = ioctl(fd, LCD_IOC_WRITE_DATA,0x00);
  58.       if(ret != 0)
  59.       return ret;
  60.      }
  61.      
  62.      return ret;
  63. }

  64. int LcdDispChars(int fd, int gLcdRow, int gLcdCol, unsigned char *str)     // 显示字符串
  65. {
  66.       unsigned char m;
  67.       int ret = 0;    
  68.           
  69.       while(*str)
  70.     {                 
  71.      SetPage(fd,gLcdRow);
  72.         SetColumn(fd,gLcdCol);    
  73.       
  74.         ret = LcdDispChar(fd, *str);
  75.         if(ret != 0)
  76.             break;
  77.             
  78.           gLcdCol += 6;         
  79.           if(gLcdCol > 132)
  80.         {
  81.             gLcdCol = 0;
  82.             gLcdRow++;
  83.             if(gLcdRow == 8)
  84.             {
  85.                 ClearScreen(fd,0x00);
  86.                 gLcdRow = 0;            
  87.             }
  88.             
  89.             LcdClrLine(fd,gLcdRow,0,128);            
  90.             //ScreenDown8();
  91.         }
  92.         str++;
  93.     }    
  94.     
  95.     return ret;
  96. }

  97. /***************************************************** 汉字显示处理 ***********************************************************/
  98. /**
  99.  * 数据重新组合,LCD采用的纵向 而字库是横向编码,需要转换他们的数据
  100.  */
  101. void DataToMove(unsigned char const src[], unsigned char des[]) // 16 * 16字符转换
  102. {
  103.     int i, j, k;
  104.     unsigned char temp = 0;

  105.     for(i=0; i<32; i++)
  106.     {
  107.         for(j=0; j<8; j++) // 转换一个字节
  108.         {
  109.             if(i < 8)
  110.                 k = j*2;
  111.             else if(i < 16)
  112.                 k = j*2+1;
  113.             else if(i < 24)
  114.                 k = j*2+16;
  115.             else if(i < 32)
  116.                 k = j*2+17;
  117.                     
  118.             if(src[k] & (1 << (7 - i%8)))
  119.                 temp |= (1 << j);
  120.         }
  121.         des[i] = temp; // 一个字节转换完成
  122.         temp = 0;
  123.     }
  124. }

  125. void DataToMove12(unsigned char const src[], unsigned char des[]) // 16 * 12字符转换
  126. {
  127.     int i, j, k, t;
  128.     unsigned char temp = 0;

  129.      for(i=0; i<24; i++)
  130.     {
  131.         for(j=0; j<8; j++) // 转换一个字节
  132.         {
  133.             if(i < 8)
  134.             {
  135.                 k = j*2;
  136.                 t = 7 - i%8;
  137.             }
  138.             else if(i < 12)
  139.             {
  140.                  k = j*2+1;
  141.                  t = 7 - i%8;
  142.             }
  143.             else if(i < 20)
  144.             {
  145.                 k = 16 + j*2;
  146.                 t = 7 - (i-12)%8;
  147.             }
  148.             else if(i < 24)
  149.             {
  150.                 k = 17 + j*2;
  151.                 t = 7 - (i-20)%8;
  152.             }
  153.             
  154.             if(i > 11 && j>3) // 只取低四位
  155.                 continue;
  156.                                  
  157.             if(src[k] & (1 << t))
  158.                temp |= (1 << j);
  159.       
  160.         }
  161.         des[i] = temp; // 一个字节转换完成
  162.         temp = 0;
  163.     }
  164. }

  165. /*******************************************************************************
  166. ** 函数名称:Bytes_Read_from_HZK
  167. ** 函数描述:从字库文件中读取一个汉字的字模点阵数据
  168. ** 入口参数:unsigned char *s 指向目标汉字的指针,
  169.              char* const chs 用于存储字模的数组首地址
  170. ** 出口参数:无
  171. *******************************************************************************/
  172. void Bytes_Read_from_HZK(int len, unsigned char *s, char* const chs)
  173. {
  174.     FILE *fp;
  175.     unsigned long offset;
  176.     
  177.     offset=((s[0]-0xa1)*94+(s[1]-0xa1))*len*2; //根据内码找出汉字在HZK16中的偏移位置
  178.     if(len == 16)
  179.     {
  180.         if((fp=fopen("HZK16","r"))==NULL)
  181.             return; //打开字库文件
  182.     }
  183.     else if(len == 12)
  184.     {
  185.          if((fp=fopen("HZK12","r"))==NULL)
  186.             return; //打开字库文件
  187.     }
  188.     fseek(fp,offset,SEEK_SET); //文件指针偏移到要找的汉字处
  189.     fread(chs,len*2,1,fp); //读取该汉字的字模
  190.   
  191.     fclose(fp);
  192. }

  193. /*******************************************************************************
  194. ** 函数名称:Bytes_Display
  195. ** 函数描述:在屏幕上显示一个汉字
  196. ** 入口参数:char* const chs 存储了汉字点阵数据的数组首地址
  197. ** 出口参数:
  198. *******************************************************************************/
  199. int Bytes_Display(int len, int fd, int gLcdRow, int gLcdCol, char* const chs)
  200. {
  201.     int i, ret;
  202.     unsigned char array[32];
  203.     
  204.     if(len == 16)
  205.         DataToMove(chs, array); // 先进行数据的转换
  206.     else if(len == 12)
  207.         DataToMove12(chs, array); // 先进行数据的转换
  208.          
  209.     SetPage(fd,gLcdRow);
  210.     SetColumn(fd,gLcdCol);    
  211.     
  212.     for(i=0; i<len;i++)
  213.     {
  214.         ret = ioctl(fd, LCD_IOC_WRITE_DATA,&array[i]);
  215.         if(ret != 0)
  216.             break;
  217.     }
  218.     
  219.     SetPage(fd,gLcdRow+1);
  220.        SetColumn(fd,gLcdCol);
  221.        
  222.     for(i=0; i<len;i++)
  223.     {
  224.         ret = ioctl(fd, LCD_IOC_WRITE_DATA,&array[i+len]);
  225.         if(ret != 0)
  226.             break;
  227.     }
  228.     
  229.     return ret;
  230. }

  231. /**
  232.  * 汉字显示 len:12 使用16*12 len:16使用16*16
  233.  */
  234. int LcdDispChineseChars(int len, int fd, int gLcdRow, int gLcdCol, unsigned char *str)     // 显示字符串
  235. {
  236.     int ret;
  237.     unsigned char chs[32]; //16*16=256个点
  238.   
  239.     while(*str)
  240.     {             
  241.      Bytes_Read_from_HZK(len, &str[0],chs); //去字库中读取汉字字模    
  242.         ret = Bytes_Display(len, fd, gLcdRow, gLcdCol, chs); //在屏幕上显示这个汉字
  243.         if(ret != 0)
  244.             break;
  245.             
  246.           gLcdCol += len;         
  247.           if(gLcdCol > 132)
  248.         {
  249.             gLcdCol = 0;
  250.             gLcdRow += 2;
  251.             
  252.             if(gLcdRow == 8)
  253.             {
  254.                 ClearScreen(fd,0x00);
  255.                 gLcdRow = 0;            
  256.             }
  257.             
  258.             LcdClrLine(fd,gLcdRow,0,128);        
  259.             LcdClrLine(fd,gLcdRow+1,0,128);    
  260.             //ScreenDown8();
  261.         }
  262.         str += 2; // 一个汉字占两位
  263.     }    
  264. }


  265. int main(int argc, char **argv)
  266. {
  267.     int fd;
  268.     unsigned char s[]="罗志勇"; //要显示的汉字
  269.     
  270.     fd = open("/dev/graylcd", 0);
  271.      if (fd < 0)
  272.     {
  273.         perror("open lcd12864 error");
  274.         return 0;
  275.     }
  276.     
  277.     InitLcd(fd);
  278.     ClearScreen(fd,0);
  279.     
  280.     LcdDispChars(fd,1,0,"123, AbC!");
  281.          
  282.     LcdDispChineseChars(12, fd, 3, 1, s);
  283.          
  284.      
  285.     close(fd);
  286.     
  287.     return 0;
  288. }

 lcd.tar.zip   
阅读(2309) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~