开关的抖动处理方法有软件和硬件两种,在常见的为软件延时方法:当开关为某个状态时,延时一段时间再检测开关的状态若它还为这个状态,则说明确实是这个状态,从而处理。
if(S1==0) //P1.0引脚输出低电平,按键S1被按下
{
delay(); //延时一段时间(20ms)再次检测
if(S1==0) {// 按键S1的确被按下
//进行按键处理函数
}
问题1:延时时间怎么算的。在实际应用时要考虑以多快的速度去按开关。
若一个熟练的打字员可以每分钟打120个单词,每个单词5个字母,那么每秒将按下10次,假设有一半的时间用于按下,则这个时间大约为50ms。但实际不要50ms,因为还有状态保持的时间。一般来说抖动时间不超过12.5ms。此外还要估算一下,目标系统要在我们按下多长时间后响应。
问题2:
延时一般采用for循环和while循环,cpu的效率低,。
/*************************************************
函数功能:软件消抖延时
**************************************************/
void delay20ms(void)
{
unsigned char i,j;
for(i=0;i<100;i++)
for(j=0;j<60;j++)
;
}
在延时的这20ms中,cpu一直在for循环中,只有在其它中断到达时,它才会被打断。这样的话,去抖延时,就会浪费cpu的效率。
同时,这个延时对有些编译器来说,什么也没做,可能会被优化掉。
问题3,实时性不高,
当开关与中断引脚相接时,一般采用边沿触发方式。
如开关SW-PB,若INT0设置为电平触发方式,开关按下时, 微处理器进入中断。 若中断程序的执行时间大于开关的抖动时间,则抖动无影响。 然而,
通常中断程序的执
行时间相对较短, 而按键动作的时间相对较长, 因此, 当程序执行完成返回时,若SW-PB仍是低电平, 则相当于按键的又一次动作, 再次执行中断程序。 边沿触发
方式则可以解决上述问题, 这就是一般不采用电平触发而采用边沿触发的依据所在。
在C语言环境下,为了提高代码质量,多写子函数模块
:
(1)void Buttoninit();
(2) boolean ButtonPressed();
(3) void IoConfigureInterrupt(port,pin,trigger_type,trigger_state);
(4) IoInterruptEnable()/Disable();