找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1560|回复: 1
收起左侧

单片机矩阵键盘输入和液晶显示

[复制链接]
ID:1050239 发表于 2022-11-3 18:26 | 显示全部楼层 |阅读模式
51键盘及数字输入显示
主程序
  1. #include<reg51.h>        
  2. #include"lcd.h"

  3. #define GPIO_KEY P1

  4. unsigned char KeyValue;           //用来存放读取到的键值
  5. unsigned char KeyState;           //用来存放按键状态

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

  8. void Delay10ms();   //延时50us
  9. void KeyDown();                 //检测按键函数

  10. /*******************************************************************************
  11. * 函 数 名         : main
  12. * 函数功能                       : 主函数
  13. * 输    入         : 无
  14. * 输    出         : 无
  15. *******************************************************************************/
  16. void main(void)
  17. {
  18.         unsigned char i;
  19.                
  20.         unsigned char cursor = '_';       //模拟光标
  21.         unsigned int cnt = 0;             //光标计数
  22.         unsigned char len = 0;            //编辑框现有字符数
  23.         
  24.         LcdInit();
  25.         KeyState=0;                 //按键状态复位
  26.         for(i=0;i<16;i++)
  27.         {
  28. //                LcdWriteCom(0x80);             //设置数据指针起点为第一行,默认为第一行
  29.                 LcdWriteData(test[i]);        
  30.         }
  31.         while(1)
  32.         {
  33.                 KeyDown();                  //检测按键
  34.                 if(KeyState)                //检测到有按键按下
  35.                 {
  36.                         if(len < 16)                           //一行最多16个字符
  37.                         {
  38.                                 KeyState=0;                               //状态复位
  39.                                 LcdWriteCom(0x80+0x40+len);                //设置数据指针起点为第二行,默认为第一行
  40.                           LcdWriteData(dat[KeyValue]);               //显示数据(按键值)到LCD
  41.                                 LcdWriteCom(0x80 + 0x40 + (++len));        //设置数据指针起点
  42.                    }
  43.            }        
  44. /* 模拟光标闪烁--不重要 */
  45.                 cnt++;
  46.                 if(cnt == 2500)
  47.                 {
  48.                         LcdWriteCom(0x80+0x40 + len);    //光标在当前字符后面显示
  49.                         LcdWriteData(cursor);            //显示光标
  50.                 }
  51.                 else if(cnt == 5000)
  52.                 {
  53.                         cnt = 0;        
  54.                         LcdWriteCom(0x80+0x40 + len);    //不显示光标,闪烁一次
  55.                         LcdWriteData(' ');
  56.                         
  57.                 }
  58.         }                                       
  59. }
  60. /*******************************************************************************
  61. * 函 数 名         : KeyDown
  62. * 函数功能                   : 检测有按键按下并读取键值
  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;        //检测出错回复17意思是把数码管全灭掉。
  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. * 函 数 名         : Delay10ms
  109. * 函数功能                   : 延时函数,延时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. }

复制代码
LCD.C文件

  1. #include"lcd.h"

  2. /*******************************************************************************
  3. * 函 数 名         : Lcd1602_Delay1ms
  4. * 函数功能                   : 延时函数,延时1ms
  5. * 输    入         : c
  6. * 输    出         : 无
  7. * 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
  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. * 函 数 名         : LcdWriteCom
  23. * 函数功能               : 向LCD写入一个字节的命令
  24. * 输    入          : com
  25. * 输    出          : 无
  26. *******************************************************************************/
  27. #ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
  28. void LcdWriteCom(uchar com)          //写入命令
  29. {
  30.         LCD1602_E = 0;     //使能
  31.         LCD1602_RS = 0;           //选择发送命令
  32.         LCD1602_RW = 0;           //选择写入
  33.         
  34.         LCD1602_DATAPINS = com;     //放入命令
  35.         Lcd1602_Delay1ms(1);                //等待数据稳定

  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; //发送低四位
  53.         Lcd1602_Delay1ms(1);

  54.         LCD1602_E = 1;         //写入时序
  55.         Lcd1602_Delay1ms(5);
  56.         LCD1602_E = 0;
  57. }
  58. #endif
  59. /*******************************************************************************
  60. * 函 数 名         : LcdWriteData
  61. * 函数功能                   : 向LCD写入一个字节的数据
  62. * 输    入         : dat
  63. * 输    出         : 无
  64. *******************************************************************************/                  
  65. #ifndef         LCD1602_4PINS                  
  66. void LcdWriteData(uchar dat)                        //写入数据
  67. {
  68.         LCD1602_E = 0;        //使能清零
  69.         LCD1602_RS = 1;        //选择输入数据
  70.         LCD1602_RW = 0;        //选择写入

  71.         LCD1602_DATAPINS = dat; //写入数据
  72.         Lcd1602_Delay1ms(1);

  73.         LCD1602_E = 1;   //写入时序
  74.         Lcd1602_Delay1ms(5);   //保持时间
  75.         LCD1602_E = 0;
  76. }
  77. #else
  78. void LcdWriteData(uchar dat)                        //写入数据
  79. {
  80.         LCD1602_E = 0;          //使能清零
  81.         LCD1602_RS = 1;          //选择写入数据
  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. * 函 数 名       : LcdInit()
  97. * 函数功能                 : 初始化LCD屏
  98. * 输    入       : 无
  99. * 输    出       : 无
  100. *******************************************************************************/                  
  101. #ifndef                LCD1602_4PINS
  102. void LcdInit()                                                  //LCD初始化子程序
  103. {
  104.          LcdWriteCom(0x38);  //开显示
  105.         LcdWriteCom(0x0c);  //开显示不显示光标
  106.         LcdWriteCom(0x06);  //写一个指针加1
  107.         LcdWriteCom(0x01);  //清屏
  108.         LcdWriteCom(0x80);  //设置数据指针起点
  109. }
  110. #else
  111. void LcdInit()                                                  //LCD初始化子程序
  112. {
  113.         LcdWriteCom(0x32);         //将8位总线转为4位总线
  114.         LcdWriteCom(0x28);         //在四位线下的初始化
  115.         LcdWriteCom(0x0c);  //开显示不显示光标
  116.         LcdWriteCom(0x06);  //写一个指针加1
  117.         LcdWriteCom(0x01);  //清屏
  118.         LcdWriteCom(0x80);  //设置数据指针起点
  119. }
  120. #endif



复制代码
LCD.H文件
  1. #ifndef __LCD_H_
  2. #define __LCD_H_
  3. /**********************************
  4. 当使用的是4位数据传输的时候定义,
  5. 使用8位取消这个定义
  6. **********************************/
  7. //#define LCD1602_4PINS

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

  12. //---重定义关键词---//
  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. 函数声明
  28. **********************************/
  29. /*在51单片机12MHZ时钟下的延时函数*/
  30. void Lcd1602_Delay1ms(uint c);   //误差 0us
  31. /*LCD1602写入8位命令子函数*/
  32. void LcdWriteCom(uchar com);
  33. /*LCD1602写入8位数据子函数*/        
  34. void LcdWriteData(uchar dat)        ;
  35. /*LCD1602初始化子程序*/               
  36. void LcdInit();                                                  

  37. #endif
复制代码

LM016.jpg

评分

参与人数 1黑币 +30 收起 理由
admin + 30 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1064915 发表于 2023-7-23 15:12 | 显示全部楼层
LCD1602_4PINS如何使用?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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