【问题标题】:Push Button press not detected in AVRAVR 中未检测到按钮按下
【发布时间】:2014-03-03 15:00:03
【问题描述】:

我编写了一个检测按钮按下的代码,第一次按下按钮时,LED 会发光,下次按下时,LED 应该关闭,同样的,如果第三次按下按钮,LED 应该再次发光。

问题是,控制器能够检测到按钮按下,但不是长时间打开 LED,它只是暂时将其打开,然后再次关闭。并且未检测到进一步的按钮按下。

下面是代码:

#include <avr/io.h>
#include <avr/delay.h>

void glow();
void off();
void switchScan();

int main()
{
DDRA=0x02; // 0000 0010 --> BIT 0=connected to switch whose other pin is connected to   ground,, and BIT 1 is connected to LED with other pin of led connected to ground
PORTA=0x01; // 0000 0001---> Switch Input pulled up and LED output pulled down 

while(1)
{
switchScan();
}

return 0;
}


void glow()
{
PORTA=PORTA|(1<<1);
}

void off()
{
PORTA=PORTA&(~(1<<1));
}

void switchScan()
{
 static int counter=0;
if(~(PINA & 0x01))
{ 
 counter++;
if(counter < 2)
glow();
else
{
counter--;
off();
}
}
}

【问题讨论】:

  • 也许您需要在更改计数器时引入延迟,以消除contact bounce?您可能会在 E-Eng 上获得更多帮助。
  • 感谢您的及时回复。但另一个问题是总是检测到第一次按下,所以在这种情况下,调用 gloom() 函数,因此 LED 应该持续发光..但它只是暂时发光。
  • 我的意思是,如果开关“弹起”,循环可能会将其记录为另一个“按下”。你不会用肉眼看到弹跳,但它几乎总是存在于任何机械开关中。
  • 哦,是的,对,感谢您的宝贵意见.. 我会尝试修复弹跳效果。

标签: avr gpio


【解决方案1】:

switchScan() 函数中的逻辑有缺陷。 glow() 只会执行一次。见代码 cmets:

void switchScan() {
    static int counter=0;

    if (~(PINA & 0x01)) { 
        counter++;
        // 1st button press: counter will be 1
        // 2nd and all following button presses: counter will be 2
        if (counter < 2)
            // can only be called once!
            glow();
        else {
            // counter will always go from 2 to 1 at this point 
            counter--;
            off();
        }
    }
}

但是,您还应该考虑 Brett 在 cmets 中提到的去弹跳。

【讨论】:

  • 感谢回复..我会更正代码并进行去弹跳
  • 作为一个起点:考虑将switchScan() 重写为“bool IsKeyPressed()”之类的东西,并在该函数中实现引脚检查和去弹跳逻辑。通过像“bool LedState;”这样的全局变量来处理开/关之间的切换。这样你可以获得更清晰的代码。哦,如果问题得到解决,请接受这个答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-12
  • 2021-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多