为什么树莓派C程序的if语句被跳过,按下按键仅触发LED闪烁?
问题原因
- 代码采用的是电平触发而非边沿触发逻辑:三个
if为顺序执行结构,当你按住按键时,digitalRead(PIN_BUTTON)持续返回有效电平,第一个if触发后counter变为2,程序立刻进入第二个if判断,此时按键仍未松开,第二个if也触发,counter变为3,紧接着第三个if直接运行闪烁逻辑,单次按键就走完了所有三个分支,所以看起来前两个分支被跳过了。 - 缺少按键消抖处理:机械按键按下、松开的瞬间会产生十几毫秒的电平抖动,极易导致单次物理按压被识别为多次电平触发,加重上面的连续触发问题。
修复方案
修改逻辑为检测按键按下的边沿(仅当按键从松开变为按下的瞬间算一次有效触发),添加消抖,同时将三个if改为else if避免同一次触发执行多个分支,参考修改后的代码:
int main (int argc, char **argv){ wiringPiSetupGpio(); int counter = 1; int lastBtnState = LOW; // 记录上一次按键状态 pinMode(PIN_LED, OUTPUT); pinMode(PIN_BUTTON, INPUT); printf("LED and button pins have beens setup.\n"); while (1) { int currBtnState = digitalRead(PIN_BUTTON); // 检测按键按下的边沿:上次松开,这次按下 if (currBtnState == HIGH && lastBtnState == LOW) { delay(20); // 消抖,20ms后再确认一次 if (digitalRead(PIN_BUTTON) == HIGH) { if (counter == 1) { digitalWrite(PIN_LED, HIGH); counter++; } else if (counter == 2) { digitalWrite(PIN_LED, LOW); counter++; } else if (counter == 3) { // 闪烁3次的逻辑 for(int i=0;i<3;i++){ digitalWrite(PIN_LED, HIGH); delay(500); digitalWrite(PIN_LED, LOW); delay(500); } counter = 1; } } } lastBtnState = currBtnState; // 加小延迟避免循环空转占用过高CPU delay(10); } }
注:如果你的按键按下时输出为低电平,把上面判断的HIGH和LOW反过来即可
内容的提问来源于stack exchange,提问作者Daryl
相关产品推荐
相关产品推荐

