我们所用的按键一般都是机械式的按键,因此在按下的时候并不立即导通,都有一定的抖动过程。在单片机的学习过程中,大家都有了这样一个按键消抖的概念。记得博主的单片机老师在上课的时候苦口婆心地反复提这。
一、软件消抖:
其实包括课本,很多课外的资料都有些偷工减料的意思,按键消抖消得不科学。仅仅通过间隔一段时间的两次检测一般是无法确定的一个按键确实按下是还是松开了。下面博主贴的软件消抖是通过一段时间内多次持续检测的方法来确定一个键值,这段时间中如果有一次是高电平,就从头开始计,直到记够连续低电平的次数足够才确定按键按下,同样按键松开也是如此。
这个思路新手一般比较困惑,不过等以后遇到这类问题时候就会恍然大悟了。(当然大神们用脚趾头想想就get了。。。说得好像大声脚趾头里有脑袋。。囧。)
下面介绍下编程的思路:
我们写这个按键函数取名为:MnKey(),倘若以后要用到按键的都可以偷懒调用这个按键函数啦~这个函数由下面这三个小函数组成:
void KeyIn(void); voidKeyChk(void); voidKeyCvt(void)
(1)首先在编写程序的时候先定义一个键值:#define KeyTime 10 //防抖定时时间
(2)一些是这三个函数的具体内容及简单介绍:
//============================================
//函数功能:读入按键,并取反;
//输出参数:Keyport;输出参数:KeyInBuff
void KeyIn(void)
{
KeyInBuff = KeyPort;
KeyInBuff ^=0xff;
}
//============================================
//函数功能:按键防抖;
//输入参数:KeyInBuff;输出参数:KeyCvtBuff
void KeyChk(void)
{
if(KeyInBuff==KeyChkBuff)
{
if(KeyInFlag==0)
return;
else
{
DeKeyTime();
if(KeyTimeBuff!=0)
return;
else
{
KeyInFlag = 0;
KeyCvtBuff = KeyChkBuff;
}
}
}
else
{
KeyChkBuff = KeyInBuff;
KeyTimeBuff = KeyTime;
KeyInFlag = 1;
}
}
//============================================
//函数功能: 键值转换
//输入参数: KeyCvtBuff;输出参数:EventFIFO
void KeyCvt(void)
{
if(KeyCvtBuff==KeyOldBuff)
return;
else
{
KeyOldBuff = KeyCvtBuff;
//你想做的事,,,yeah~
}
}
//============================================
//函 数 名: DeKeyTime()
//功能描述: 按键防抖时间处理函数
void DeKeyTime(void)
{ uchar i;
i=50000;
while(i--)
{
if(KeyTimeBuff!=0)
KeyTimeBuff--;//调整键盘按下有效判定时间
}
}
(3)因此,在按键函数中调用这几个函数就行啦~
//============================================
void MnKey(void)
{
KeyIn();
KeyChk();
KeyCvt();
}
其实让新手一下子写出这个按键防抖的程序是蛮难的,这个时候硬件消抖更为方便快捷。
二、硬件防抖
硬件防抖可以通过触发器和电容。依博主之见:最快捷的办法就是通过电容消抖。
如下图所示:当按键松开的时候,单片机的引脚为高电平,当按键按下时,单片机的引脚为低电平。
和按键并联的电容作用就是消除按键的抖动。画个图来解释下这个电容的巨大的作用,就是:(这个抖动有点豪放,请不要介意,,,)