微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机学习之5-独立按键和矩阵键盘

51单片机学习之5-独立按键和矩阵键盘

时间:11-30 来源:互联网 点击:
第14集

键盘的原理

键盘分编码键盘(例如电脑键盘)和非编码键盘(自己用程序去识别)。

非编码键盘分:独立式非编码键盘(独立按键)、行列式非编码键盘(4*4阵列键盘)

独立键盘的电路图。

因为51单片机的IO口不是双向口而是准双向口,要让IO口具备输入功能,必须将IO口置1,置1之后当按键按下时IO口的电平会被拉低,即被置0。当检测到IO口为0时即可判断该按键已经按下。按键按下时会有一个抖动的过程(弹片会抖动),由于单片机检测IO口速度非常快,超过弹片抖动的频率,所以当单片机检测到IO口为0时需延时一小段时间再检测IO是否为0,如果仍为0就确认该按钮被按下。因为IO口里面有上拉电阻,所以当松开按钮时,IO口又被拉高。

例程:

#include

#defineuintunsignedint

#defineucharunsignedchar

sbitKey=P3^4;//按键

sbitLed=P1^0;//Led灯

voiddelay(uintz);

/********主函数********/

voidmain()

{

while(1)

{

if(!Key)

{

delay(10);//消抖操作

if(!Key)

Led=0;//按下时Led亮

else

Led=1;

}

}

}

voiddelay(uintz)

{

uintx,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按钮。

第一步,我们先确定列,给P3口赋值0xF0=11110000,那么P37、P36、P35、P34都被置1,P33、P32、P31、P30都被置0,当S6被按下时,由于S6按钮的一边P31为0,所以跟S6另一边相连的P35被拉低,即等于0。如下图

此时得到列的值P3=11010000=0xD0,在程序中只需要判断P3是否等于0xF0,不等说明有按键按下。

第二步,不改变高四位的状态:1101将低四位全部置1(P3=P3|0x0F)。这时候就变成了11011111,由于单片机扫描列的时候速度非常快,到现在扫描行的时候,按键仍处在按下状态(人的反应没有单片机快)。S6被按下,由于与S6相连的P35为低电平(即0),所以P31由高电平(即1)变成低电平(即0)如下图

此时得到的值为P3=11011101=S6被按下。这就是检测原理。

完整程序:

#include

#defineuintunsignedint

#defineucharunsignedchar

sbitLed=P1^0;

sbitLed1=P1^1;

voiddelay(uintz);

/********主函数********/

voidmain()

{

ucharKey_Temp;

ucharKey;//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)

{

case0xEE:Led=0;break;//S1

case0xDE:Led1=0;break;

case0xBE:break;

case0x7E:break;

case0xED:break;

case0xDD:break;

case0xBD:break;

case0x7D:break;

case0xEB:break;

case0xDB:break;

case0xBB:break;

case0x7B:break;

case0xE7:break;

case0xD7:break;

case0xB7:break;

case0x77:break;//S16

default:

Led=Led1=1;

}

}

}

voiddelay(uintz)

{

uintx,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top