独立按键检测
按键检测
1 独立按键检测
按键检测的核心是消抖,这里用一个10ms的延时来处理按键抖动,按键按下为0,先判断一次按键值是否为0,若是,延时10ms,再判断一次,如果两次检测的键值都是0,按键就是按下的状态。
普中51开发板上,独立按键的电路图如下:
下面给出一个案例,结合之前的定时器应用,四个按键,实现60进制计数器的计数结果的显示,K1做加计数的输入时钟,K2做减计数的时钟,K3复位,K4按一次是自动隔1秒加计数,再按一次,暂停计数。代码如下
//用数码管的前两位显示一个十进制数,变化
//范围是00~59,开始时显示00,每按一次K1键
//数值加1;每按一次K2键,数值减1;每按一次K3
//键,数值归零;按一次K4键,利用定时器,使
//数值每秒加1,再按一次K4键,数值停止加1,保
//持不变。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit k1=P3^1; //按键端口
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;
sbit A2=P2^4; //位选控制,74138的输入信号
sbit A1=P2^3;
sbit A0=P2^2;
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
void delayms(uint);
uchar numt0,num; //定时器的计数值和60的计数值
void display(uchar numdis) //显示子函数
{
uchar shi,ge; //数码管要显示的数字
shi=numdis/10;
ge=numdis%10;
A2=1; //显示十位
A1=1;
A0=1;
P0=table[shi];
delayms(5);
P0=0x00; //消隐
A2=1; //显示个位
A1=1;
A0=0;
P0=table[ge];
delayms(5);
P0=0x00;
}
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void init() //初始化函数
{
TMOD=0x01; //T0,方式1
TH0=(65536-45872)/256; //装入初值50ms一次中断
TL0=(65536-45872)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
}
void keyscan()
{
if(k1==0) //判断K1键是否按下
{
delayms(10); //延时消抖
if(k1==0) //再确认K1按下
{
num++; //加计数
if(num==60) //计满60归0
num=0;
while(!k1); //等待按键释放
}
}
if(k2==0) //判断K2键是否按下
{
delayms(10); //延时消抖
if(k2==0) //再确认K2按下
{
if(num==0) //计满0归60
num=60;
num--;
while(!k2); //等待按键释放
}
}
if(k3==0) //判断K3键是否按下
{
delayms(10); //延时消抖
if(k3==0) //再确认K3按下
{
num=0;
while(!k3); //等待按键释放
}
}
if(k4==0) //判断K4键是否按下
{
delayms(10); //延时消抖
if(k4==0) //再确认K4按下
{
while(!k4); //等待按键释放
TR0=~TR0; //启动或停止T0
}
}
}
void main()
{
init(); //定时器初始化
while(1)
{
keyscan();
display(num);
}
}
void T0_time() interrupt 1
{
TH0=(65536-45872)/256; //装入初值50ms一次中断
TL0=(65536-45872)%256;
numt0++;
if(numt0==20) //计到1秒
{
numt0=0; //请0,重计20次
num++;
if(num==60)
num=0;
}
}
代码分析,用子函数实现定时器初始化,数码管动态显示,延时,按键扫描。延时函数还是用的两个for语句嵌套。初始化就是把参数列出来即可,动态扫描,就是位选和段选的控制。这里用74138位选,给段选编码,延时5ms,消隐,换下一位。难点主要是按键扫描,除了前述的先后检测两次是否键值为0,还需要处理按下后的不同操作。这里K4的处理最需要技巧,利用定时器的开或关,来实现每次按下后不同的操作。