在STC89C52RC中,键盘接口分为独立式按键和矩阵式键盘。如果项目中需要的交互较少,使用独立式键盘即可;如果输入参数较多,比方说打印机什么的,功能复杂的系统,则需要采用矩阵式键盘进行输入控制。
键盘的可靠输入要考虑两个方面的问题:
- 去抖动:目前的单片机键盘按键均为机械式触点,由于触点的机械弹性效应,在按键闭合和断开的时候,接触点的电压并不是立即变化,而是会出现抖动。根据按键的不同机械特性,抖动的时间长短不等,大致在5ms~20ms。
- 一次按键处理:当键盘按下之后,相应的按键编码以高电平的方式输入到单片机的I/O接口。按键闭合是有一定时间的。一般来说的,大致是0.1us~0.5us。因为单片机的执行速度很快,如果处理不当,就有可能一次按键操作被执行多次。
一般来说,硬件解决以上两个问题比较复杂,成本也高,而软件处理择简单实用。软件处理的方法是:当程序检测到有键按下时,执行一个10ms的延时程序,然后再监测一次,看是否该键仍然闭合。如果仍然闭合择可以确认确实有键按下,从而可以消除抖动的影响。
单片机对键盘的输入检测可以有查询和中断两种方式。查询适合用于一般用途的程序;中断适合一些较为复杂的单片机系统。
在程序中,对键盘的处理包括以下几个方面:
- 检测按键是否按下;
- 如果检测到按键被按下,可以执行软件去抖动,消除抖动的影响;
- 准确判断是哪个按键被按下;
- 转向相应的程序处理子程序
1、独立式按键实验
/*************************************************************************
用实验板上的独立按键K1、K2、K3和K4这四个按键控制8位红色LED灯,按一下K1,L1
亮,其他灯都不亮;按一下K2,L3亮,其他灯都不亮;按一下K3,L5亮,其他灯都不
亮;按一下K4,L7亮,其他灯都不亮。
*************************************************************************/
#include<reg52.h>
sbit K1=P1^0; //位定义P1.0引脚为K1
sbit K2=P1^1; //位定义P1.1引脚为K2
sbit K3=P1^2; //位定义P1.2引脚为K3
sbit K4=P1^3; //位定义P1.3引脚为K4
char key_scan(); //声明返回值为char型的独立按键检索函数key_scan()
void display(char a); //声明无返回值的显示函数display()
void delay(unsigned int z); //声明延时函数
/*主函数开始*/
void main()
{
while(1) //进入大循环
{
display(key_scan()); //检索并显示
}
}
/*定义返回值为char型的独立按键检索函数*/
char key_scan()
{
char i; //声明char型变量i,作为返回标志
P1=0xff; //P1口全部置高电平,等待读取引脚数据
if(K1==0) //判断是否K1键被按下
{
delay(20); //延时20ms,消抖
if(K1==0) //再次确认按键K1是否真的被按下
{
while(!K1); //确认按键K1真的被按下后,等待松手
delay(20); //延时20ms,消抖
i=1; //返回标志为1
}
}
if(K2==0) //判断是否K2键被按下
{
delay(20); //延时20ms,消抖
if(K2==0) //再次确认按键K2是否真的被按下
{
while(!K2); //确认按键K2真的被按下后,等待松手
delay(20); //延时20ms,消抖
i=2; //返回标志为2
}
}
if(K3==0) //判断是否K3键被按下
{
delay(20); //延时20ms,消抖
if(K3==0) //再次确认按键K3是否真的被按下
{
while(!K3); //确认按键K3真的被按下后,等待松手
delay(20); //延时20ms,消抖
i=3; //返回标志为3
}
}
if(K4==0) //判断是否K4键被按下
{
delay(20); //延时20ms,消抖
if(K4==0) //再次确认按键K4是否真的被按下
{
while(!K4); //确认按键K4真的被按下后,等待松手
delay(20); //延时20ms,消抖
i=4; //返回标志为4
}
}
return i; //返回char型变量i的值
}
/*定义显示函数*/
void display(char a)
{
switch(a) //判断返回值对应的是哪一个键被按下
{
case 1:
P0=0xfe; //K1键被按下,点亮L1灯
break;
case 2:
P0=0xfb; //K2键被按下,点亮L2灯
break;
case 3:
P0=0xef; //K3键被按下,点亮L3灯
break;
case 4:
P0=0xbf; //K4键被按下,点亮L4灯
break;
default:
P0=0xff; //其他状态时,所有灯都不亮
break;
}
}
/*定义延时函数*/
void delay(unsigned int z)
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}