找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2183|回復(fù): 1
收起左側(cè)

單片機(jī)矩陣鍵盤輸入和液晶顯示

[復(fù)制鏈接]
ID:1050239 發(fā)表于 2022-11-3 18:26 | 顯示全部樓層 |閱讀模式
51鍵盤及數(shù)字輸入顯示
主程序
  1. #include<reg51.h>        
  2. #include"lcd.h"

  3. #define GPIO_KEY P1

  4. unsigned char KeyValue;           //用來存放讀取到的鍵值
  5. unsigned char KeyState;           //用來存放按鍵狀態(tài)

  6. unsigned char dat[]="0123456789ABCDEF";
  7. unsigned char test[]=" 51_  lcd  ";

  8. void Delay10ms();   //延時50us
  9. void KeyDown();                 //檢測按鍵函數(shù)

  10. /*******************************************************************************
  11. * 函 數(shù) 名         : main
  12. * 函數(shù)功能                       : 主函數(shù)
  13. * 輸    入         : 無
  14. * 輸    出         : 無
  15. *******************************************************************************/
  16. void main(void)
  17. {
  18.         unsigned char i;
  19.                
  20.         unsigned char cursor = '_';       //模擬光標(biāo)
  21.         unsigned int cnt = 0;             //光標(biāo)計數(shù)
  22.         unsigned char len = 0;            //編輯框現(xiàn)有字符數(shù)
  23.         
  24.         LcdInit();
  25.         KeyState=0;                 //按鍵狀態(tài)復(fù)位
  26.         for(i=0;i<16;i++)
  27.         {
  28. //                LcdWriteCom(0x80);             //設(shè)置數(shù)據(jù)指針起點為第一行,默認(rèn)為第一行
  29.                 LcdWriteData(test[i]);        
  30.         }
  31.         while(1)
  32.         {
  33.                 KeyDown();                  //檢測按鍵
  34.                 if(KeyState)                //檢測到有按鍵按下
  35.                 {
  36.                         if(len < 16)                           //一行最多16個字符
  37.                         {
  38.                                 KeyState=0;                               //狀態(tài)復(fù)位
  39.                                 LcdWriteCom(0x80+0x40+len);                //設(shè)置數(shù)據(jù)指針起點為第二行,默認(rèn)為第一行
  40.                           LcdWriteData(dat[KeyValue]);               //顯示數(shù)據(jù)(按鍵值)到LCD
  41.                                 LcdWriteCom(0x80 + 0x40 + (++len));        //設(shè)置數(shù)據(jù)指針起點
  42.                    }
  43.            }        
  44. /* 模擬光標(biāo)閃爍--不重要 */
  45.                 cnt++;
  46.                 if(cnt == 2500)
  47.                 {
  48.                         LcdWriteCom(0x80+0x40 + len);    //光標(biāo)在當(dāng)前字符后面顯示
  49.                         LcdWriteData(cursor);            //顯示光標(biāo)
  50.                 }
  51.                 else if(cnt == 5000)
  52.                 {
  53.                         cnt = 0;        
  54.                         LcdWriteCom(0x80+0x40 + len);    //不顯示光標(biāo),閃爍一次
  55.                         LcdWriteData(' ');
  56.                         
  57.                 }
  58.         }                                       
  59. }
  60. /*******************************************************************************
  61. * 函 數(shù) 名         : KeyDown
  62. * 函數(shù)功能                   : 檢測有按鍵按下并讀取鍵值
  63. * 輸    入         : 無
  64. * 輸    出         : 無
  65. *******************************************************************************/
  66. void KeyDown(void)
  67. {
  68.         char a;
  69.         GPIO_KEY=0x0f;
  70.         if(GPIO_KEY!=0x0f)
  71.         {
  72.                 Delay10ms();
  73.                 if(GPIO_KEY!=0x0f)
  74.                 {
  75.                         KeyState=1;
  76.                         //測試列
  77.                         GPIO_KEY=0X0F;
  78. //                         Delay10ms();
  79.                         switch(GPIO_KEY)
  80.                         {
  81.                                 case(0X07):        KeyValue=0;break;
  82.                                 case(0X0b):        KeyValue=1;break;
  83.                                 case(0X0d): KeyValue=2;break;
  84.                                 case(0X0e):        KeyValue=3;break;
  85. //                                default:        KeyValue=17;        //檢測出錯回復(fù)17意思是把數(shù)碼管全滅掉。
  86.                         }
  87.                         //測試行
  88.                         GPIO_KEY=0XF0;
  89.                         Delay10ms();
  90.                         switch(GPIO_KEY)
  91.                         {
  92.                                 case(0X70):        KeyValue=KeyValue;break;
  93.                                 case(0Xb0):        KeyValue=KeyValue+4;break;
  94.                                 case(0Xd0): KeyValue=KeyValue+8;break;
  95.                                 case(0Xe0):        KeyValue=KeyValue+12;break;
  96. //                                default:        KeyValue=17;
  97.                         }
  98.                         while((a<50)&&(GPIO_KEY!=0xf0))         //檢測按鍵松手檢測
  99.                         {
  100.                                 Delay10ms();
  101.                                 a++;
  102.                         }
  103.                         a=0;
  104.                 }
  105.         }
  106. }
  107. /*******************************************************************************
  108. * 函 數(shù) 名         : Delay10ms
  109. * 函數(shù)功能                   : 延時函數(shù),延時10ms
  110. * 輸    入         : 無
  111. * 輸    出         : 無
  112. *******************************************************************************/
  113. void Delay10ms(void)   //誤差 0us
  114. {
  115.     unsigned char a,b,c;
  116.     for(c=1;c>0;c--)
  117.         for(b=38;b>0;b--)
  118.             for(a=130;a>0;a--);
  119. }

復(fù)制代碼
LCD.C文件

  1. #include"lcd.h"

  2. /*******************************************************************************
  3. * 函 數(shù) 名         : Lcd1602_Delay1ms
  4. * 函數(shù)功能                   : 延時函數(shù),延時1ms
  5. * 輸    入         : c
  6. * 輸    出         : 無
  7. * 說    名         : 該函數(shù)是在12MHZ晶振下,12分頻單片機(jī)的延時。
  8. *******************************************************************************/

  9. void Lcd1602_Delay1ms(uint c)   //誤差 0us
  10. {
  11.     uchar a,b;
  12.         for (; c>0; c--)
  13.         {
  14.                  for (b=199;b>0;b--)
  15.                  {
  16.                           for(a=1;a>0;a--);
  17.                  }      
  18.         }
  19.             
  20. }

  21. /*******************************************************************************
  22. * 函 數(shù) 名         : LcdWriteCom
  23. * 函數(shù)功能               : 向LCD寫入一個字節(jié)的命令
  24. * 輸    入          : com
  25. * 輸    出          : 無
  26. *******************************************************************************/
  27. #ifndef         LCD1602_4PINS         //當(dāng)沒有定義這個LCD1602_4PINS時
  28. void LcdWriteCom(uchar com)          //寫入命令
  29. {
  30.         LCD1602_E = 0;     //使能
  31.         LCD1602_RS = 0;           //選擇發(fā)送命令
  32.         LCD1602_RW = 0;           //選擇寫入
  33.         
  34.         LCD1602_DATAPINS = com;     //放入命令
  35.         Lcd1602_Delay1ms(1);                //等待數(shù)據(jù)穩(wěn)定

  36.         LCD1602_E = 1;                  //寫入時序
  37.         Lcd1602_Delay1ms(5);          //保持時間
  38.         LCD1602_E = 0;
  39. }
  40. #else
  41. void LcdWriteCom(uchar com)          //寫入命令
  42. {
  43.         LCD1602_E = 0;         //使能清零
  44.         LCD1602_RS = 0;         //選擇寫入命令
  45.         LCD1602_RW = 0;         //選擇寫入

  46.         LCD1602_DATAPINS = com;        //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
  47.         Lcd1602_Delay1ms(1);

  48.         LCD1602_E = 1;         //寫入時序
  49.         Lcd1602_Delay1ms(5);
  50.         LCD1602_E = 0;

  51. //        Lcd1602_Delay1ms(1);
  52.         LCD1602_DATAPINS = com << 4; //發(fā)送低四位
  53.         Lcd1602_Delay1ms(1);

  54.         LCD1602_E = 1;         //寫入時序
  55.         Lcd1602_Delay1ms(5);
  56.         LCD1602_E = 0;
  57. }
  58. #endif
  59. /*******************************************************************************
  60. * 函 數(shù) 名         : LcdWriteData
  61. * 函數(shù)功能                   : 向LCD寫入一個字節(jié)的數(shù)據(jù)
  62. * 輸    入         : dat
  63. * 輸    出         : 無
  64. *******************************************************************************/                  
  65. #ifndef         LCD1602_4PINS                  
  66. void LcdWriteData(uchar dat)                        //寫入數(shù)據(jù)
  67. {
  68.         LCD1602_E = 0;        //使能清零
  69.         LCD1602_RS = 1;        //選擇輸入數(shù)據(jù)
  70.         LCD1602_RW = 0;        //選擇寫入

  71.         LCD1602_DATAPINS = dat; //寫入數(shù)據(jù)
  72.         Lcd1602_Delay1ms(1);

  73.         LCD1602_E = 1;   //寫入時序
  74.         Lcd1602_Delay1ms(5);   //保持時間
  75.         LCD1602_E = 0;
  76. }
  77. #else
  78. void LcdWriteData(uchar dat)                        //寫入數(shù)據(jù)
  79. {
  80.         LCD1602_E = 0;          //使能清零
  81.         LCD1602_RS = 1;          //選擇寫入數(shù)據(jù)
  82.         LCD1602_RW = 0;          //選擇寫入

  83.         LCD1602_DATAPINS = dat;        //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
  84.         Lcd1602_Delay1ms(1);

  85.         LCD1602_E = 1;          //寫入時序
  86.         Lcd1602_Delay1ms(5);
  87.         LCD1602_E = 0;

  88.         LCD1602_DATAPINS = dat << 4; //寫入低四位
  89.         Lcd1602_Delay1ms(1);

  90.         LCD1602_E = 1;          //寫入時序
  91.         Lcd1602_Delay1ms(5);
  92.         LCD1602_E = 0;
  93. }
  94. #endif
  95. /*******************************************************************************
  96. * 函 數(shù) 名       : LcdInit()
  97. * 函數(shù)功能                 : 初始化LCD屏
  98. * 輸    入       : 無
  99. * 輸    出       : 無
  100. *******************************************************************************/                  
  101. #ifndef                LCD1602_4PINS
  102. void LcdInit()                                                  //LCD初始化子程序
  103. {
  104.          LcdWriteCom(0x38);  //開顯示
  105.         LcdWriteCom(0x0c);  //開顯示不顯示光標(biāo)
  106.         LcdWriteCom(0x06);  //寫一個指針加1
  107.         LcdWriteCom(0x01);  //清屏
  108.         LcdWriteCom(0x80);  //設(shè)置數(shù)據(jù)指針起點
  109. }
  110. #else
  111. void LcdInit()                                                  //LCD初始化子程序
  112. {
  113.         LcdWriteCom(0x32);         //將8位總線轉(zhuǎn)為4位總線
  114.         LcdWriteCom(0x28);         //在四位線下的初始化
  115.         LcdWriteCom(0x0c);  //開顯示不顯示光標(biāo)
  116.         LcdWriteCom(0x06);  //寫一個指針加1
  117.         LcdWriteCom(0x01);  //清屏
  118.         LcdWriteCom(0x80);  //設(shè)置數(shù)據(jù)指針起點
  119. }
  120. #endif



復(fù)制代碼
LCD.H文件
  1. #ifndef __LCD_H_
  2. #define __LCD_H_
  3. /**********************************
  4. 當(dāng)使用的是4位數(shù)據(jù)傳輸?shù)臅r候定義,
  5. 使用8位取消這個定義
  6. **********************************/
  7. //#define LCD1602_4PINS

  8. /**********************************
  9. 包含頭文件
  10. **********************************/
  11. #include<reg51.h>

  12. //---重定義關(guān)鍵詞---//
  13. #ifndef uchar
  14. #define uchar unsigned char
  15. #endif

  16. #ifndef uint
  17. #define uint unsigned int
  18. #endif

  19. /**********************************
  20. PIN口定義
  21. **********************************/
  22. #define LCD1602_DATAPINS P0
  23. sbit LCD1602_E=P2^7;
  24. sbit LCD1602_RW=P2^5;
  25. sbit LCD1602_RS=P2^6;

  26. /**********************************
  27. 函數(shù)聲明
  28. **********************************/
  29. /*在51單片機(jī)12MHZ時鐘下的延時函數(shù)*/
  30. void Lcd1602_Delay1ms(uint c);   //誤差 0us
  31. /*LCD1602寫入8位命令子函數(shù)*/
  32. void LcdWriteCom(uchar com);
  33. /*LCD1602寫入8位數(shù)據(jù)子函數(shù)*/        
  34. void LcdWriteData(uchar dat)        ;
  35. /*LCD1602初始化子程序*/               
  36. void LcdInit();                                                  

  37. #endif
復(fù)制代碼

LM016.jpg

評分

參與人數(shù) 1黑幣 +30 收起 理由
admin + 30 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報

ID:1064915 發(fā)表于 2023-7-23 15:12 | 顯示全部樓層
LCD1602_4PINS如何使用?
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表