1,查询法延时模式
cpp
u8 key0=1;
u8 x=0;
KEY=1;
while(1)
{
if(KEY==0) //"按键按下"
{
delay(10); //延时10ms
if(KEY==0 && kdy0==1) //按下有10ms 且上状态是1。即下降沿时
{
key0=0; //将上状态置0.防止按住不放时,重复执行按下程序语句。
x++; //按下执行语句
}
key0=KEY; //弹起按键时将上一状态置1.否则保持为0.
}
P0=~smgduan[x];
}
10ms延时时,程序是阻塞停止的,以下程序就不会停止主程序,
2,查询法不需要延时
cpp
u8 keyx=0xFF;
u8 x=0;
KEY=1;
while(1)
{
keyx = keyx<<1 | KEY; //左移并将KEY状态写入第0位,下一次执行时会被继续左移
if(keyx !=0) //8位没有全部为0,即没有8次检测全为"按键按下"
{
key0=1; //上一状态
}
else if(key0==1) //8次全0且上状态是1。即下降沿时
{
key0=0; //将上状态置0.防止按住不放时,重复执行按下程序语句。
x++; //按下执行语句
}
P0=~smgduan[x];
}
key0的作用是备份上一状态,使按下按键产生**"下降沿"**作用。
每一次循环检测一次,8次皆为0时确定为"按下";如果整个程序很长,一次循环占用时间超过几十毫秒,8次就是上百几百毫秒了,这样按下时间略快时就被认为是没按下了。所以程序总时长不超过10ms时好用,超过就要这样:
将按键检测程序放在 一个2ms的定时器中断函数中,程序每2ms 就会检测一下按键的状态。虽然这个检测程序占用CPU时间,但不到0.03ms而已,0.03ms vs 2ms,不到2%占用。
3,中断法 非阻塞程序
cpp
void Int0() interrupt 0 //外部中断0 必须用P3.2口
{
delay(10); //与1例中都是有按下信号时延时10ms;区别是这里不需要主程序查询而已。
if(KEY==0)
{
x++; //执行语句
}
}
因为3.2中断输入已设置为**"下降沿触发方式了",**一直按下也不会再有中断发生的。
非阻塞也是相对的,中断也是延时了10ms.
总结:
中断法最好,但占用一个外部中断资源。