按键输入是人机对话不可缺少的一部分,对于消抖设计,一种是软件消抖,一种是硬件消抖。但在单片机电路设计中,采用电容消抖才是最佳的选择,其次才是定时器消抖。
1、按键输入采用软件消抖
1)、通过定时器方式定时读取按键输入
根据固定的采集周期,通常为10ms,需要读两次,若前后两次均相同,则认为按键被按下。需要占用CPU的定时器,优点:不占用CPU执行时间,程序执行速度快。缺点:需要一个全局变量Key来辅助完成。
定时器中断程序:
Key=(u8)(Key<<1);
if(KeyPin=0) Key=(u8)(Key|0x01); //将key的最低位置1
else Key=(u8)(Key&0xFE); //将key的最低位置0
按键读取程序
if( (key&0x03) ==0x03 ) 按键被按下
else 无按键被按下
2)、完全采用软件延时,每隔10ms周期采集一次,需要读两次,若前后两次均相同,则认为按键被按下。缺点:占用CPU执行时间,影响程序的执行速度,当有中断发送时,读取按键的时间变长,不适合用于中断频繁的程序中。
if(KeyPin=0)
{
delay_ms(10);
if(KeyPin=0)//确认有键按下
{
}
}
2、按键输入采用硬件消抖
1)、电容消抖
注意:KEY_UP,KEY_Left,KEY_OK连接到CPU引脚。
采用定时器轮询读取
先置SetCOL1=0,SetCOL2=0,SetCOL3=0,SetCOL4=0,延时10ms让电容完成放电,然后执行 读ReadROW1,ReadROW2,ReadROW3,ReadROW4,如果出现低电平,则记录ROW的值为x;没有出现低电平,表示无按键按下。
当SetCOL1=1,SetCOL2=0,SetCOL3=0,SetCOL4=0时,延时10ms让电容完成充电,然后执行 读ReadROW1,ReadROW2,ReadROW3,ReadROW4,如果全部为高电平,则记录COL的值为y=1,表示读到按键所在的列值;
同理
当SetCOL1=1,SetCOL2=1,SetCOL3=0,SetCOL4=0,时,延时10ms让电容完成充电,然后执行 读ReadROW1,ReadROW2,ReadROW3,ReadROW4,如果全部为高电平,则记录COL的值为y=2,表示读到按键所在的列值;
当SetCOL1=1,SetCOL2=1,SetCOL3=1,SetCOL4=0,时,延时10ms让电容完成充电,然后执行 读ReadROW1,ReadROW2,ReadROW3,ReadROW4,如果全部为高电平,则记录COL的值为y=3,表示读到按键所在的列值;
当SetCOL1=1,SetCOL2=1,SetCOL3=1,SetCOL4=1时,延时10ms让电容完成充电,然后执行 读ReadROW1,ReadROW2,ReadROW3,ReadROW4,如果全部为高电平,则记录COL的值为y=4,表示读到按键所在的列值;
if(x=1 && y==1) SW1被按下;
if(x=1 && y==2) SW2被按下;
if(x=1 && y==3) SW3被按下;
if(x=1 && y==4) SW4被按下;
等等,按照坐标去决定哪个按键被按下。
2)、专用芯片消抖
在有很多按钮输入的情况下,使用专用芯片。缺点:增加硬件成本。
3、总结
在单片机电路设计中,采用电容消抖是最佳的选择,其次才是定时器消抖。