键盘的原理
键盘分编码键盘(例如电脑键盘)和非编码键盘(自己用程序去识别)。
非编码键盘分:独立式非编码键盘(独立按键)、行列式非编码键盘(4*4阵列键盘)
因为51单片机的IO口不是双向口而是准双向口,要让IO口具备输入功能,必须将IO口置1,置1之后当按键按下时IO口的电平会被拉低,即被置0。当检测到IO口为0时即可判断该按键已经按下。按键按下时会有一个抖动的过程(弹片会抖动),由于单片机检测 IO口速度非常快,超过弹片抖动的频率,所以当单片机检测到IO口为0时需延时一小段时间再检测IO是否为0,如果仍为0就确认该按钮被按下。因为IO口里面有上拉电阻,所以当松开按钮时,IO口又被拉高。
例程:
#include
#define uint unsigned int
#define uchar unsigned char
sbit Key = P3^4; // 按键
sbit Led = P1^0; // Led 灯
void delay(uint z);
/******** 主函数 ********/
void main()
{
while(1)
{
if(!Key)
{
delay(10); // 消抖操作
if(!Key)
Led = 0; // 按下时 Led亮
else
Led = 1;
}
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
第15集
4*4矩阵键盘
上图中,1个按键占用一个IO口,如果有16个按键就占用了16个IO口。为了减少IO口的使用,就需要用矩阵的方式连线。如下图
矩阵扫描原理
从图可以看出P30、P31、P32、P33 为行(低四位),P34、P35、P36、P37为列(高四位)。
假设我们按下的是S6按钮。[page]
第一步,我们先确定列,给P3口赋值0xF0 = 1111 0000 ,那么P37、P36、P35、P34都被置1,P33、P32、P31、P30 都被置0,当S6被按下时,由于S6按钮的一边P31为0,所以跟S6另一边相连的P35被拉低,即等于0。如下图
此时得到列的值 P3 = 1101 0000 = 0xD0,在程序中只需要判断P3是否等于0xF0,不等说明有按键按下。
第二步,不改变高四位的状态:1101 将低四位全部置1(P3 = P3 | 0x0F)。这时候就变成了 1101 1111,由于单片机扫描列的时候速度非常快,到现在扫描行的时候,按键仍处在按下状态(人的反应没有单片机快)。S6被按下,由于与S6相连的P35为低电平(即0),所以P31由高电平(即1)变成低电平(即0)如下图
此时得到的值为 P3 = 1101 1101 = S6 被按下。这就是检测原理。
完整程序:
#include
#define uint unsigned int
#define uchar unsigned char
sbit Led = P1^0;
sbit Led1 = P1^1;
void delay(uint z);
/******** 主函数 ********/
void main()
{
uchar Key_Temp;
uchar Key; // Key 键值
while(1)
{
Key = 0; // 清0
P3 = 0xF0;
Key_Temp = P3;
Key_Temp &= 0xF0; // 只取高四位 这句需要,因为51IO只是准双向 要使其具备输入功能需要用置1
if(0xF0!=Key_Temp) // 判断是否有按键按下
{
delay(10); // 延时一段时间 跳过抖动的时间
Key_Temp = P3 & 0xF0 ; // 先取P3 然后 和 0xF0与运算得到 高四位
if(0xF0 != Key_Temp) // 再次判断是否确实按下
{
P3 = Key_Temp | 0x0F; // 保留高四位 将低四位全部置1 并输出
Key = P3; // 再读入
}
}
switch(Key)
{
case 0xEE: Led = 0; break; // S1
case 0xDE: Led1 = 0; break;
case 0xBE: break;
case 0x7E: break;
case 0xED: break;
case 0xDD: break;
case 0xBD: break;
case 0x7D: break;
case 0xEB: break;
case 0xDB: break;
case 0xBB: break;
case 0x7B: break;
case 0xE7: break;
case 0xD7: break;
case 0xB7: break;
case 0x77: break; // S16
default:
Led = Led1 = 1;
}
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
上一篇:4*4键盘扫描代码
下一篇:51单片机学习之3-步进电机
推荐阅读最新更新时间:2024-03-16 14:04
设计资源 培训 开发板 精华推荐
- TI隔离技术知多少?答题赢好礼!
- EEworld版主招新啦!欢迎加入我们的队伍
- 领跑2021,你准备好了么?领取下载积分,点燃学习小宇宙!
- 【报名赢小米手环、膳魔师保温杯等好礼】罗德与施瓦茨HDMI 1.4b/2.1 接口测试
- 学《TIVA C Launchpad入门课程》 晒成绩 赢大礼!
- 翻开《射频技术For Dummies系列》书籍,跟帖漫谈射频世界
- 芯币竞价全新回归 抱回惊喜迎接新年
- 有奖问答|ADI MEMS 推动无处不在的倾角监测发展
- 联想栗子工业智能开发板抢先首发!免费申请进行时~另有12 月 22 日深圳技术沙龙邀您莅临!
- 玩儿转电源游戏,赢取800元TI手持POS机开发套件!