键盘是单片机与用户交互设备之一,用户通过键盘输入数据或命令到单片机。最简单的键盘仅有一个按键,复杂一些的键盘有多个按键。在单片机的外围电路中,通常用到的按键都是机械弹性开关,当用户按下按键时,按键闭合,用户松开按键后,按键断开,单片机如何检测到按键被按下或释放呢?
按键一般与单片机的I/O口连接,按键的一端连接I/O口,另一端接地,与按键连接的I/O端口会被赋值为高电平,单片机键盘检测程序会持续检测该I/O端口的电平,若检测到该端口由高电平变为低电平,说明与该端口连接的按键被按下,因为按键闭合后,相当于I/O端口通过按键与地直接连接,导致该I/O端口变为低电平。
按键的连接非常简单,如下图所示,按键的一端与任一I/O端口相连,另一端与地连接。
机械按键被按下后,会发生抖动现象,导致电平在按下阶段和释放阶段不会立即变为低电平,而是呈现锯齿状。下图是按键按下时的电压变化。
机械按键被按下或释放后,抖动时间大约为5~10ms,此时电压不稳定,呈锯齿形,检测程序无法检测按键是否被按下,因此编写按键检测程序时,需要进行抖动延时处理。按键检测流程如下图所示:
检测程序持续检测与键盘连接的I/O端口,当检测到I/O端口电压出现波动时,延时10ms,然后再次检测I/O端口,若I/O端口为低电平,说明按键被按下,同时还要检测按键是否被释放,检测按键是否被释放时,就不需要对抖动进行延迟处理了。
按键检测应用案例:应用两个按键分别控制发光二极管D1和D2的通断,按键1与单片机P2.0连接,按键2与P2.1端口连接,D1和D2分别与单片机P1.0、P1.1口连接,按下按键1,D1状态反转,按下按键2,D2状态反转。
下图是按键检测案例电路设计图:
在P2.0和P2.1端口分别接入两个按键,按键的另一端接地。D1和D2发光二极管分别连接到单片机的P1.0和P1.1端口。
单片机内运行的完整C程序如下:
#include < reg51.h >
#include < stdio.h >
sbit key_one = P2^0;
sbit key_two = P2^1;
sbit led_one = P1^0;
sbit led_two = P1^1;
void delay(unsigned int millisecond)
{
unsigned int i,j;
for(i=millisecond;i >0;i--)
for(j=120;j >0;j--);
}
void key_scan()
{
if( key_one == 0 )
{
delay(10);
if( key_one == 0 )
{
while(!key_one);
led_one = !led_one;
}
}
if( key_two == 0 )
{
delay(10);
if( key_two == 0 )
{
while(!key_two);
led_two = !led_two;
}
}
}
void main(void)
{
unsigned int i;
led_one = 1;
led_two = 1;
while(1)
{
key_scan();
}
}
位变量key_one和key_two为单片机P2.0端口和P2.1端口,用于检测按键状态。位变量led_one和led_two为单片机P1.0和P1.1端口,用于控制D1和D2的状态。函数delay()是延迟函数,参数millisecond用于设置延迟的毫秒数。
key_scan是按键检测函数,分别检测P2.0端口和P2.1端口电平变化,若检测到端口电平为低电平时,延时10ms后,若该端口依然是低电平,则确认与该端口连接的按键被按下,然后使用while循环等待按键的释放,循环条件是端口变换为高电平,最后取反led_one或led_two的电平。
main()函数主要完成按键的循环检测,具体实现方法是在函数内部实现一个无限循环结构,在循环结构内调用key_scan()函数。
全部0条评论
快来发表一下你的评论吧 !