上一节学习的是独立按键控制LED亮灭
这一节我们先来讲一下按键的抖动:
对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。
看一下下面这个波形,按键没有按下的时候,它就是高电平1,然后突然按下按键,就变成低电平0并且由于机械触点,它会弹开,然后上下抖动一下,之后才稳定得变成0。这个抖动的时间大概是5-10ms,不同的开关抖动的时间是不一样的。
当抖动消失的时候,它就是进入一个稳定的低电平0状态。
松手的时候它也产生抖动,大概也是5-10ms。最后稳定地变成1。
那么我们知道这个抖动对按键的检测进行一些干扰,这就涉及一个东西,叫做消抖。
消抖有两种方法,一种是硬件的消抖,就是加个电路,把这些线通过这个电路里面经过一些触发器等等一些电路来进行操作,把这个抖动进行过滤,这个波形就变成直的,然后点亮LED。但是这种比较麻烦,需要硬件资源。
还有一种方法就是通过软件来处理,就是写程序。怎么办?
当检测到按键按下的时候,来个Delay,直接延时个20ms,而抖动产生的时间大概也才5-10ms,我们延时20ms,就足够覆盖这个抖动时间了。当抖动过去的时候,我们再继续操作,松手的时候我们也Delay 20ms,然后再继续操作。
那么这个程序怎么写呢?
我们要延时20ms的话,要先在STC生成一个延时1ms的程序
注意:系统频率和指令集一定要改成和自己的单片机一致的。
然后复制过来改造一下,完整的代码如下:
编译无错误后下载下来测试一下,重启板子看看效果
我们看到D1的确是在以1秒为周期在闪烁(500ms为半秒)。这就证明我们的Delay函数写的没有错。
那么我们继续往下写
接下来我们要写一个按键判断的程序,昨天我们学过了,是用if语句来判断按键
按键操作有3步:
- 按下按键要消抖
- 判断松手
- 松开按键要消抖
最后要记得LED的状态取反
完整代码如下:
#include <REGX52.H>
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms)
{
//以下这段代码是Delay1ms的代码
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
//每次延时1ms结束后,xms就减1
xms--;
//直到减到0的时候就会跳出while循环
//如此就可以实现给xms传多少秒,Delay函数就延时了多少毫秒
}
}
void main()
{
while(1)
{
//判断按键有3步
if(P3_1==0)//K1按键连接的是P3的1口
{
//1.按下按键消抖
Delay(20);//延时20ms
//2.判断松手
//延时20ms后,到了稳定状态
//接下来要检测是否松手
//因为我们要实现的是当按下的时候,没有亮,只有当松手的时候才亮
//用while语句判断并循环
//如果K1还是按下的状态,它就一直循环
//一旦松手即P3_1==1,就跳出循环
while(P3_1==0);
//3.松开按键消抖
Delay(20);//延时20ms
//LED状态取反:
//为什么要取反?
//是因为上面判断松手那一步,当P3_1==1时跳出循环了
//此时P3_1==1,则P2_0也等于1,想要P2_0==0,就得取反,1变成0,灯就亮了
P2_0=~P2_0;
}
}
}
编译无错误,看看效果
按下K1的时候没有反映
松手后的效果:
只有检测到松手的时候才变亮了。
以上即这节要实现的效果!