標題: 單片機+LCD12864液晶簡易菜單程序-c語言 [打印本頁]

作者: lizi    時間: 2013-6-18 04:56
標題: 單片機+LCD12864液晶簡易菜單程序-c語言
本帖最后由 lizi 于 2013-6-18 04:58 編輯



lcd12864菜單大致框架算是完成了,主要實現(xiàn)了兩個功能----反白,翻頁。原本是想做一個多級---起碼也得二級----菜單,但有意外的時間安排,故暫且放下。
      個人認為比較費腦筋的是反白功能的制作。首先12864并沒有專門為用戶準備單行的反白,要么一三行一塊反,要么二四一塊。所以得參照前人的方法,即將字符顯示與圖像顯示結(jié)合,在需要反白的部分用繪圖功能全寫上0xff,有自帶的異或邏輯能成功反白。這部分讓我摸索了幾小時。
      其次是這種反白實現(xiàn)之前,得先給原來的圖像全清掉,也正是這一步讓89c52耗費了不少時間,選項切換間居然要用1s 的時間。這是不能忍的啊。所以自己想了一個辦法,讓圖像整體清除換成 部分清除。思路是在選項光標變量 Index_P 外再添一記錄變量----Index_P_Pre-----以記錄上一次選項所在位置,然后在清除圖像的時候?qū)iT清除 Index_P_Pre 對于的圖像痕跡,這樣就將清屏所需的時間減少了3/4。
      好了,這個菜單模塊總共用了6KB。對于 64KB的89C516來說還有很多空間,自己也可以放心弄下去。
  1. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  2. /*
  3. Index_Num 數(shù)組元素最大序號
  4. Index     數(shù)組元素當前序號
  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       //數(shù)據(jù)口
  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;      //液晶復(fù)位端口

  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);        //寫數(shù)據(jù)時,關(guān)閉圖形顯示
  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);       //寫完數(shù)據(jù),開圖形顯示
  122. }
  123. void convertChar(uchar CX)                                        // 反白函數(shù)
  124. {
  125. uchar halfLineCnt, basicBlock,lcdPosX,lcdPosY;
  126. // if(f==1)
  127. Disp_black(); //清繪圖區(qū)
  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. }

復(fù)制代碼
完整代碼下載:
12864cd.rar (1.78 KB, 下載次數(shù): 256)



作者: 左左右右    時間: 2013-7-1 15:55
51Hei(51黑)論壇有你更精彩
作者: 弒あ殤    時間: 2013-8-19 14:22
學(xué)習(xí)下   最近要用菜單
作者: danpianji889    時間: 2013-8-20 10:01
好東西呀
作者: №奔跑№    時間: 2013-8-20 20:08
剛做完lcd顯示、不過只是簡單的應(yīng)用
作者: asn60    時間: 2013-10-4 01:57
學(xué)習(xí)了,感謝!
作者: xiaoafei    時間: 2013-10-5 13:03

好好學(xué)習(xí),天天向上
作者: 13620819446    時間: 2013-10-13 23:48
支持支持。
作者: 小新灬    時間: 2014-3-18 21:06
51Hei(51黑)論壇有你更精彩
作者: leeclyc    時間: 2014-3-21 11:35
真是太棒了 加油
作者: 稻草人‘mirror    時間: 2014-5-2 02:31
感謝樓主的分享
作者: yy8881    時間: 2014-6-5 14:05
學(xué)習(xí)了,感謝!
作者: lijunlinv    時間: 2014-8-5 17:16
12864cd.rar,謝謝
作者: lijunlinv    時間: 2014-8-5 17:17
51Hei(51黑)論壇有你更精彩
作者: qzsulin    時間: 2014-8-7 09:29
學(xué)習(xí)下
作者: lovingadu    時間: 2014-8-15 09:01
很好的東西!
作者: heweli888    時間: 2014-9-2 06:55
菜單弄了幾天了還在研究中
作者: heam    時間: 2014-9-15 11:10
謝謝分享
作者: zmc5354    時間: 2014-9-28 12:02

菜單弄了幾天了還在研究中!!
作者: c2541    時間: 2014-12-15 15:18
論壇有你更精彩
作者: popo119    時間: 2015-4-26 23:38
學(xué)習(xí)!收藏。
作者: qianfz    時間: 2015-4-27 10:23
學(xué)習(xí)下                        
作者: qianfz    時間: 2015-4-27 10:32
好東西                                       
作者: Jameszuo    時間: 2015-4-29 08:57
收下了  樓主 辛苦了
作者: 小天愛小蔥    時間: 2015-5-4 15:56
謝謝分享!
作者: 怒放    時間: 2015-5-4 16:15
學(xué)習(xí)了
作者: 743570032    時間: 2015-5-4 16:18
漂亮,頂頂頂頂。
作者: zhengjianping    時間: 2016-4-5 20:00
最近在學(xué)習(xí)菜單的使用,謝謝樓主分享!
作者: 王城wc    時間: 2016-4-20 20:48
好用,值得學(xué)習(xí)
作者: igiucom    時間: 2016-5-10 15:45
正在學(xué)習(xí)中。
作者: igiucom    時間: 2016-5-10 15:46
正在學(xué)習(xí)菜單。借鑒一下。謝謝。
作者: kz1269108444    時間: 2017-2-26 19:39
厲害了
作者: kz1269108444    時間: 2017-2-26 19:40
.........................................
作者: lyxxzrb    時間: 2017-2-26 20:35
感謝樓主費心分享,mark一下學(xué)習(xí)備用。
作者: 12大風(fēng)    時間: 2017-2-27 08:18
好東西
作者: 589ccg    時間: 2017-4-15 03:36
左左右右 發(fā)表于 2013-7-1 15:55
51Hei(51黑)論壇有你更精彩

很不錯啊

作者: 51黑電子論壇111    時間: 2017-7-12 10:06
lijunlinv 發(fā)表于 2014-8-5 17:16
12864cd.rar,謝謝

可以把源代碼發(fā)給我一下嗎




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1