找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16117|回复: 36
打印 上一主题 下一主题
收起左侧

单片机+LCD12864液晶简易菜单程序-c语言

  [复制链接]
跳转到指定楼层
楼主
本帖最后由 lizi 于 2013-6-18 04:58 编辑



lcd12864菜单大致框架算是完成了,主要实现了两个功能----反白,翻页。原本是想做一个多级---起码也得二级----菜单,但有意外的时间安排,故暂且放下。
      个人认为比较费脑筋的是反白功能的制作。首先12864并没有专门为用户准备单行的反白,要么一三行一块反,要么二四一块。所以得参照前人的方法,即将字符显示与图像显示结合,在需要反白的部分用绘图功能全写上0xff,有自带的异或逻辑能成功反白。这部分让我摸索了几小时。
      其次是这种反白实现之前,得先给原来的图像全清掉,也正是这一步让89c52耗费了不少时间,选项切换间居然要用1s 的时间。这是不能忍的啊。所以自己想了一个办法,让图像整体清除换成 部分清除。思路是在选项光标变量 Index_P 外再添一记录变量----Index_P_Pre-----以记录上一次选项所在位置,然后在清除图像的时候专门清除 Index_P_Pre 对于的图像痕迹,这样就将清屏所需的时间减少了3/4。
      好了,这个菜单模块总共用了6KB。对于 64KB的89C516来说还有很多空间,自己也可以放心弄下去。
  1. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  2. /*
  3. Index_Num 数组元素最大序号
  4. Index     数组元素当前序号
  5. Index_P   选中项序号
  6. Index_P_Pre 上一选中项序号,用于快速清理上次所画下的图案
  7. */
  8. #include <reg52.h>
  9. #include <intrins.h>
  10. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
  11. #define LCD_data  P0       //数据口
  12. #define Index_Num 8
  13. typedef unsigned char uchar;
  14. typedef unsigned int uint;

  15. sbit Key1 = P1^0;
  16. sbit Key2 = P1^1;
  17. sbit LCD_RS  =  P2^6;      //寄存器选择输入    cs
  18. sbit LCD_RW  =  P2^5;      //液晶读/写控制     sid
  19. sbit LCD_EN  =  P2^7;      //液晶使能控制      clk
  20. sbit LCD_PSB =  P3^2;      //串/并方式控制
  21. sbit LCD_RST =  P3^7;      //液晶复位端口

  22. bdata uchar DataBuf;
  23. uint Index,Index_P_Pre;
  24. uint Index_P=0;
  25. uchar code Weibo[][16]={"hello","呀咦  晗昱","weibo.com","/maixianyu","blog.163.com","maixianyu@126",
  26.         "123","456","789"};
  27. //////////////////////////////////////////////   200us
  28. void delay(int ms)
  29. {
  30. uchar t;  
  31.   while(ms--)  
  32.   {
  33.     for(t=0; t<20; t++) ;  
  34.   }   
  35. }
  36. //////////////////////////////////////////////////////////////////
  37. void Lcd_Write_8bit(uchar msg){
  38. uint i;
  39. uchar DataBuffer;
  40. DataBuffer=msg;
  41. for(i=0;i<8;i++){
  42.   LCD_RW=(bit)(DataBuffer&0x80);
  43.   LCD_EN=1;
  44.   _nop_();
  45.   _nop_();
  46.   LCD_EN=0;
  47.   _nop_();
  48.   _nop_();
  49.   DataBuffer<<=1;
  50. }
  51. }
  52. /////////////////////////////////////////
  53. uchar Lcd_Rec(uint RS){                    
  54. uint i;
  55. uchar Data_H,Data_L;
  56. LCD_RS=1;
  57. if(RS)
  58.   Lcd_Write_8bit(0xfe);
  59. else
  60.   Lcd_Write_8bit(0xfc);  
  61. delayNOP();
  62. for(i=0;i<8;i++){
  63.   LCD_EN=1;
  64.   Data_H=(Data_H<<1)|LCD_RW;
  65.   LCD_EN=0;
  66. }
  67. delayNOP();
  68. for(i=0;i<8;i++){
  69.   LCD_EN=1;
  70.   Data_L=(Data_L<<1)|LCD_RW;  
  71.   LCD_EN=0;
  72. }
  73. LCD_RS=0;
  74. DataBuf=(Data_H<<4)|Data_L;
  75. return DataBuf;
  76. }
  77. /////////////////////////////////////////
  78. bit Lcd_Busy(){
  79. return Lcd_Rec(0)&0x80;
  80. }
  81. /////////////////////////////////////////
  82. void Lcd_Write(uchar msg,uint dc){              //if dc equals 0,msg is a kind of cmd.
  83. while(Lcd_Busy());
  84. if(dc==0)
  85.   DataBuf=0xf8;
  86. else
  87.   DataBuf=0xfa;
  88. delayNOP();
  89. LCD_RS=1;
  90. Lcd_Write_8bit(DataBuf);
  91. delayNOP();
  92. DataBuf=msg&0xf0;
  93. Lcd_Write_8bit(DataBuf);
  94. delayNOP();
  95. DataBuf=(msg<<4)&0xf0;
  96. Lcd_Write_8bit(DataBuf);
  97. LCD_RS=0;
  98. }

  99. ////////////////////////////////////////////////////
  100. void Disp_black()                          //清理上一次画下的痕迹
  101. {
  102.   uchar i,j;
  103.   Lcd_Write(0x34,0);        //写数据时,关闭图形显示
  104. if(Index_P_Pre<2){
  105.    for(i=0+16*Index_P_Pre; i<16+16*Index_P_Pre; i++)
  106.    {
  107.      Lcd_Write(0x80+i,0);
  108.      Lcd_Write(0x80,0);
  109.      for(j=0;j<16;j++)        
  110.    Lcd_Write(0x00,1);   
  111.    }
  112. }else{
  113.    for(i=0+16*(Index_P_Pre-2);i<16+16*(Index_P_Pre-2);i++)
  114.    {
  115.      Lcd_Write(0x80+i,0);
  116.      Lcd_Write(0x88,0);
  117.      for(j=0;j<16;j++)        
  118.     Lcd_Write(0x00,1);   
  119.    }
  120. }
  121.   Lcd_Write(0x36,0);       //写完数据,开图形显示
  122. }
  123. void convertChar(uchar CX)                                        // 反白函数
  124. {
  125. uchar halfLineCnt, basicBlock,lcdPosX,lcdPosY;
  126. // if(f==1)
  127. Disp_black(); //清绘图区
  128. lcdPosY = 0x80;
  129. if (CX == 0)
  130. {
  131.     CX = 0x80;
  132.     halfLineCnt = 16;
  133. }
  134. else if (CX == 1)
  135. {
  136.     CX = 0x80;
  137.     halfLineCnt = 32;
  138. }
  139. else if (CX == 2)
  140. {
  141.     CX = 0x88;
  142.     halfLineCnt = 16;
  143. }
  144. else if (CX == 3)
  145. {
  146.     CX = 0x88;
  147.     halfLineCnt = 32;
  148. }
  149. lcdPosX = CX;

  150.      for (; halfLineCnt != 0; halfLineCnt--)
  151. {
  152.     basicBlock = 16;
  153.     Lcd_Write(0x34,0);
  154.     Lcd_Write(lcdPosY,0);
  155.     Lcd_Write(lcdPosX,0);
  156.     Lcd_Write(0x30,0);

  157.     for (;basicBlock != 0; basicBlock--)
  158.     {
  159.      if (halfLineCnt > 16)
  160.      {
  161.       Lcd_Write(0x00,1);
  162.      }
  163.      else
  164.      {
  165.    Lcd_Write(0xff,1);
  166.      }
  167.     }
  168.     lcdPosY++;
  169. }

  170. Lcd_Write(0x36,0);
  171. Lcd_Write(0x30,0);
  172. }


  173. ///////////////////////////////////////////////////
  174. void Lcd_Pos(uchar x,uchar y){
  175. uchar pos;
  176. if(x==1)
  177.   {x=0x80;}
  178. else if(x==2)
  179.   {x=0x90;}
  180. else if(x==3)
  181.   {x=0x88;}
  182. else if(x==4)
  183.   {x=0x98;}
  184. pos=x+y;
  185. Lcd_Write(pos,0);
  186. }
  187. ///////////////////////////////////////////
  188. void Lcd_Menu(uint Head){
  189. uint j,i;
  190. uint Index_End=Head+3;
  191. // if(Index_End<=Index_Num){
  192.   for(j=0;Head<=Index_End;Head++,j++){
  193.    Lcd_Pos(j+1,0);
  194.    i=0;
  195.    while(i<15){
  196.     if(Weibo[Head][i]!=0)
  197.      Lcd_Write(Weibo[Head][i++],1);
  198.     else{
  199.      Lcd_Write(0x20,1);
  200.      i++;
  201.     }
  202.    }
  203.    delayNOP();
  204.   }
  205. // }
  206. }
  207. ///////////////////////////////////////////
  208. void Lcd_Init(void){
  209. LCD_PSB=0;
  210. LCD_RST=0;
  211. LCD_RS=0;
  212. LCD_RW=1;
  213. LCD_EN=0;
  214. delay(2);
  215. LCD_RST=1;
  216. delay(2);
  217. Lcd_Write(0x30,0);   //ordinary  cmd
  218. delay(2);
  219. Lcd_Write(0x0c,0);   //how to show
  220. delay(2);
  221. Lcd_Write(0x01,0);   //clear
  222. delay(2);
  223. }
  224. /////////////////////////////////////////
  225. void main(void){
  226. Lcd_Init();
  227. Key1=1;
  228. Lcd_Menu(Index);
  229. convertChar(Index_P);
  230. while(1){
  231.   if(Key1==0&&Index>=0){
  232.    delay(5);
  233.    if(Key1==0&&Index>=0){
  234.     if(Index_P==0&&Index>0)
  235.      Lcd_Menu(--Index);
  236.     if(Index_P>0){
  237.      Index_P_Pre=Index_P;
  238.      convertChar(--Index_P);
  239.     }
  240.    }
  241.   }
  242.   if(Key2==0&&Index_P<=3){
  243.    delay(5);
  244.    if(Key2==0&&Index_P<=3){
  245.     if(Index_P==3&&Index<(Index_Num-3))
  246.      Lcd_Menu(++Index);
  247.     if(Index_P<3){
  248.      Index_P_Pre=Index_P;
  249.      convertChar(++Index_P);
  250.     }
  251.    }
  252.   }
  253. }
  254. }

复制代码
完整代码下载:
12864cd.rar (1.78 KB, 下载次数: 254)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:51343 发表于 2013-7-1 15:55 | 只看该作者
51Hei(51黑)论坛有你更精彩
回复

使用道具 举报

板凳
ID:53223 发表于 2013-8-19 14:22 | 只看该作者
学习下   最近要用菜单
回复

使用道具 举报

地板
ID:52972 发表于 2013-8-20 10:01 | 只看该作者
好东西呀
回复

使用道具 举报

5#
ID:51962 发表于 2013-8-20 20:08 | 只看该作者
刚做完lcd显示、不过只是简单的应用
回复

使用道具 举报

6#
ID:53421 发表于 2013-10-4 01:57 | 只看该作者
学习了,感谢!
回复

使用道具 举报

7#
ID:55611 发表于 2013-10-5 13:03 | 只看该作者

好好学习,天天向上
回复

使用道具 举报

8#
ID:52286 发表于 2013-10-13 23:48 | 只看该作者
支持支持!!
回复

使用道具 举报

9#
ID:59780 发表于 2014-3-18 21:06 | 只看该作者
51Hei(51黑)论坛有你更精彩
回复

使用道具 举报

10#
ID:59867 发表于 2014-3-21 11:35 | 只看该作者
真是太棒了 加油
回复

使用道具 举报

11#
ID:61339 发表于 2014-5-2 02:31 | 只看该作者
感谢楼主的分享
回复

使用道具 举报

12#
ID:62636 发表于 2014-6-5 14:05 | 只看该作者
学习了,感谢!
回复

使用道具 举报

13#
ID:20446 发表于 2014-8-5 17:16 | 只看该作者
12864cd.rar,谢谢
回复

使用道具 举报

14#
ID:20446 发表于 2014-8-5 17:17 | 只看该作者
51Hei(51黑)论坛有你更精彩
回复

使用道具 举报

15#
ID:64825 发表于 2014-8-7 09:29 | 只看该作者
学习下
回复

使用道具 举报

16#
ID:64655 发表于 2014-8-15 09:01 | 只看该作者
很好的东西!
回复

使用道具 举报

17#
ID:65691 发表于 2014-9-2 06:55 | 只看该作者
菜单弄了几天了还在研究中
回复

使用道具 举报

18#
ID:66181 发表于 2014-9-15 11:10 | 只看该作者
谢谢分享
回复

使用道具 举报

19#
ID:66757 发表于 2014-9-28 12:02 | 只看该作者

菜单弄了几天了还在研究中!!
回复

使用道具 举报

20#
ID:70478 发表于 2014-12-15 15:18 | 只看该作者
论坛有你更精彩
回复

使用道具 举报

21#
ID:78060 发表于 2015-4-26 23:38 | 只看该作者
学习!收藏!!
回复

使用道具 举报

22#
ID:78187 发表于 2015-4-27 10:23 | 只看该作者
学习下                        
回复

使用道具 举报

23#
ID:78187 发表于 2015-4-27 10:32 | 只看该作者
好东西                                       
回复

使用道具 举报

24#
ID:78314 发表于 2015-4-29 08:57 | 只看该作者
收下了  楼主 辛苦了
回复

使用道具 举报

25#
ID:77907 发表于 2015-5-4 15:56 | 只看该作者
谢谢分享!
回复

使用道具 举报

26#
ID:78403 发表于 2015-5-4 16:15 | 只看该作者
学习了
回复

使用道具 举报

27#
ID:78843 发表于 2015-5-4 16:18 | 只看该作者
漂亮,顶顶顶顶。
回复

使用道具 举报

28#
ID:112374 发表于 2016-4-5 20:00 | 只看该作者
最近在学习菜单的使用,谢谢楼主分享!
回复

使用道具 举报

29#
ID:109035 发表于 2016-4-20 20:48 | 只看该作者
好用,值得学习
回复

使用道具 举报

30#
ID:52823 发表于 2016-5-10 15:45 | 只看该作者
正在学习中。
回复

使用道具 举报

31#
ID:52823 发表于 2016-5-10 15:46 | 只看该作者
正在学习菜单。借鉴一下。谢谢。
回复

使用道具 举报

32#
ID:166781 发表于 2017-2-26 19:39 | 只看该作者
厉害了
回复

使用道具 举报

33#
ID:166781 发表于 2017-2-26 19:40 | 只看该作者
.........................................
回复

使用道具 举报

34#
ID:116826 发表于 2017-2-26 20:35 | 只看该作者
感谢楼主费心分享,mark一下学习备用。
回复

使用道具 举报

35#
ID:75280 发表于 2017-2-27 08:18 | 只看该作者
好东西
回复

使用道具 举报

36#
ID:189727 发表于 2017-4-15 03:36 来自手机 | 只看该作者
左左右右 发表于 2013-7-1 15:55
51Hei(51黑)论坛有你更精彩

很不错啊
回复

使用道具 举报

37#
ID:219002 发表于 2017-7-12 10:06 | 只看该作者

可以把源代码发给我一下吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表