按键是我们学习单片机时一个重要的器件,我们在按下按键时,难免会一位手抖动或者接触不稳定,但如果不消抖,按键按下的瞬间将会产生成百上千次按键有效的结果,最终的现象不可预料,所以有必要进行消抖。
原理:使用定时器计时产生中断,只要在一定次数的中断内,按键按下有效的次数达到一定次数,就可以认为按键按下了,此时返回一个按键有效的现象。
例子:比如,我们设置200us产生一个中断,定义两个变量:count_times
和 key_pressed_times
,每次中断count_times加一,同时若检测key按键被按下,则key_pressed_times加一。当count_times达到30时,若key_pressed_times>20,则认为按键按下了。
count_times
:计算中断次数
key_pressed_times
:计算中断时按键按下的次数
按键的引脚:KEY1: P3.2、KEY2: P3.3
数码管段选:P0[7…0]
数码管位选:P2[2…0] + P2.3(译码使能)
变量定义:
#define uchar unsigned char
#define uint unsigned int
uchar code duanxuan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code weixuan[4]={0x04,0x05,0x06,0x07};
sbit led_sel=P2^3; //74LH138译码器的使能
sbit key1=P3^2; //按键key1
sbit key2=P3^3; //按键key2
uint number; //显示在数码管上的值
uint flag; //位选的位置
int count_times,key1_pressed_times,key2_pressed_times; //消抖中统计次数的量
bit status_P,status_P2; //按键的钱后两个状态
Init()函数:
void Init()
{
P0M0 = 0XFF; //设置推挽输出,P3不用设置
P0M1 = 0X00;
P2M0 = 0X0F;
P2M1 = 0X00;
led_sel = 0; //位选译码器使能有效
P0 = 0;
number = 5000;
count_times = 0;
key1_pressed_times = 0;
key2_pressed_times = 0;
status_P = 0; //默认前后状态都是按下
status_P2 = 0;
flag = 0;
TMOD = 0X00;
EA = 1;
ET0 = 1;
TH0 = (65536-200)/256; //200us一次中断
TL0 = (65536-200)%256;
TR0 = 1;
}
中断函数:控制数码管显示、统计中断次数、统计key1和key2被按下的次数
void InterruptTimer0()interrupt 1
{
// 控制数码管显示
switch(flag)
{
case 0:P0=0;P2=weixuan[flag];P0=duanxuan[number/1000];break;
case 1:P0=0;P2=weixuan[flag];P0=duanxuan[(number/100)%10];break;
case 2:P0=0;P2=weixuan[flag];P0=duanxuan[(number%100)/10];break;
case 3:P0=0;P2=weixuan[flag];P0=duanxuan[(number%100)%10];break;
}
flag++;
// 中断次数 检测key1、key2是否被按下
count_times++;
if(key1==0)
key1_pressed_times++;
if(key2==0)
key2_pressed_times++;
}
main()函数:每15ms采集一次数据,检测按键是否可以被认为被按下
void main()
{
Init();
while(1)
{
if(flag==4) //该判断放在中断函数外面更合适
flag=0;
if(count_times==30) //每30*0.2ms检测一次按键
{
if(key1_pressed_times>=20){ // 该时间段内,key1按下次数达到2/3
if(status_P==1){
status_P=0;
number++;
}
}
else status_P=1;
if(key2_pressed_times>=20){ // 该时间段内,key2按下次数达到2/3
if(status_P2==1){
status_P2=0;
number--;
}
}
else status_P2=1;
count_times=0; // 所有次数清零
key1_pressed_times=0;
key2_pressed_times=0;
}
}
}
延时消抖:另一种消抖的办法,如果某一时刻检测到按键key为低电平(按下),再10us,如果按键还是低电平,则可认为按键按下是有效的。
if( sbtKey1 == 0 )
{
delay( 10 ); //ÑÓʱÏû¶¶
if( sbtKey1 == 0 )
{
xxx;
}
}
以上就是关于按键消抖的内容啦~
第五篇单片机学习笔记完结,cheers !