独立按键检测

按键检测

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) //计满600

num=0;

while(!k1); //等待按键释放

}

}

if(k2==0) //判断K2键是否按下

{

delayms(10); //延时消抖

if(k2==0)  //再确认K2按下

{

if(num==0) //计满060

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的处理最需要技巧,利用定时器的开或关,来实现每次按下后不同的操作。

 

posted on 2024-04-18 22:26  yf.x  阅读(60)  评论(0编辑  收藏  举报

导航