单片机交流
直播中

廉鼎琮

7年用户 945经验值
私信 关注
[问答]

矩阵按键怎么变成独立按键?

矩阵按键的原理是什么?
矩阵按键怎么变成独立按键?有哪些方法?

回帖(1)

黄敏

2021-7-19 15:41:10
  矩阵按键原理图
  
  矩阵按键怎么变成独立按键
  方法一:
  逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。
  方法二:
  行列扫描:我们可以通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。
  LCD显示部分可以参考我一篇文章
  51单片机DS1302时钟LCD1602显示
  以上是我在学习过程中的一点总结,用的是普中的51单片机·。
  #include《reg51.h》 #define GPIO_KEY P1#define LCD1602_DATAPINS P0typedef unsigned int uint;typedef unsigned char uchar;unsigned char KeyValue;//用来存放读取到的键值unsigned char KeyState;//用来存放按键状态unsigned char PuZh[;unsigned char dat[;***it LCD1602_E=P2^7;***it LCD1602_RW=P2^5;***it LCD1602_RS=P2^6;void DelayMs(unsigned int x);void Delay10ms(); //延时50usvoid KeyDown(); //检测按键函数void LcdInit();void LcdWriteData(uchar dat);void LcdWriteCom(uchar com);void main(void){ unsigned char i; LcdInit(); KeyState=0; for(i=0;i《16;i++) {// LcdWriteCom(0x80); LcdWriteData(PuZh); } while(1) { KeyDown(); LcdWriteCom(0xc0); LcdWriteData(dat[KeyValue]); /* if(KeyState==0) // 此处不能这样用,永远不变 { KeyState=1; LcdWriteCom(0xc0); LcdWriteData(dat[KeyValue]); } */ } }void KeyDown(void){ char a; GPIO_KEY=0x0f; if(GPIO_KEY!=0x0f) { Delay10ms(); if(GPIO_KEY!=0x0f) { KeyState=0; //测试列 GPIO_KEY=0X0F;// Delay10ms(); switch(GPIO_KEY) { case(0X07): KeyValue=0;break; case(0X0b): KeyValue=1;break; case(0X0d): KeyValue=2;break; case(0X0e): KeyValue=3;break;// default: KeyValue=17; //检测出错回复17意思是把数码管全灭掉。 } //测试行 GPIO_KEY=0XF0; Delay10ms(); switch(GPIO_KEY) { case(0X70): KeyValue=KeyValue;break; case(0Xb0): KeyValue=KeyValue+4;break; case(0Xd0): KeyValue=KeyValue+8;break; case(0Xe0): KeyValue=KeyValue+12;break;// default: KeyValue=17; } while((a《50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测 { Delay10ms(); a++; } a=0; } }}void Delay10ms(void) //误差 0us{ unsigned char a,b,c; for(c=1;c》0;c--) for(b=38;b》0;b--) for(a=130;a》0;a--);}void DelayMs(unsigned int x) //0.14ms误差 0us{ unsigned char i; while(x--) { for (i = 0; i《13; i++) {} }}void LcdWriteCom(uchar com) //写入命令{ LCD1602_E = 0; //使能 LCD1602_RS = 0; //选择发送命令 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = com; //放入命令 DelayMs(1); //等待数据稳定 LCD1602_E = 1; //写入时序 DelayMs(5); //保持时间 LCD1602_E = 0;}void LcdWriteData(uchar dat) //写入数据{ LCD1602_E = 0; //使能清零 LCD1602_RS = 1; //选择输入数据 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = dat; //写入数据 DelayMs(1); LCD1602_E = 1; //写入时序 DelayMs(5); //保持时间 LCD1602_E = 0;}void LcdInit() //LCD初始化子程序{ LcdWriteCom(0x38); //开显示 LcdWriteCom(0x0c); //开显示不显示光标 LcdWriteCom(0x06); //写一个指针加1 LcdWriteCom(0x01); //清屏 LcdWriteCom(0x80); //设置数据指针起点}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分