XMEGA AVR中的按钮消除

时间:2016-11-15 10:26:52

标签: c avr

我试图在xmega中进行简单的开/关切换。例如,如果我按一下,就应该说

  

如果我再次按它,​​应该说

  

依旧......

我知道如何在Arduino中进行按钮去抖动,但我真的不知道AVR。有人可以帮助我,或者给我一些示例代码来学习吗?

到目前为止,这是我的代码:

if (!(PORTH_IN&PIN0_bm)) 
{
    if (Mode1 != 1)
    {
        Mode1 = 1;
        printf("%d\n", Mode1);   
    }
}

if (!(PORTH_IN&PIN0_bm))
{
    if (Mode1 != 0)
    {
        Mode1 = 0;
        printf("%d\n", Mode1);
    }
}

2 个答案:

答案 0 :(得分:1)

我会为此创建一个小型状态机:

static int debounce_guard;
static int button_has_been_pressed;

void read_button_state()
{   
    switch(button_is_pressed)
    {
        case YES:
            if(debounce_guard == 0)
            {
                button_has_been_pressed = 1;
            }
            break;
        case NO:
            if(button_has_been_pressed)
            {
                /* Do stuff here */
                debounce_guard = 10000;
                button_has_been_pressed = 0;
            }
            break;
    }

    if(debounce_guard > 0)
        debounce_guard--;
}

(button_is_pressed变量应该反映gpio引脚的状态)

这个想法是debounce_guard应该让你忽略按钮的冗余弹跳,这个变量应该用一些定时器或者只是在函数本身中减少,就像在显示的代码中一样。状态机将作出反应然后用户释放按钮。

答案 1 :(得分:0)

使用软件解决方案去除按钮的基本问题是了解CPU频率。 XMegas可以在32MHz甚至更高的频率下运行。 staringlizard在这里提出的解决方案:

debounce_guard = 10000;
...
if(debounce_guard > 0)
    debounce_guard--;
如果您以后决定使用更高的CPU速率运行应用程序,则

不好。 让我们说你的XMega运行@ 32MHz,上面的循环将在不到1/3毫秒的时间内执行。不好,如果一个人按下按钮。 更好的解决方案如下:

void read_button_state(){
    ...do your logic here

    _delay_ms(500);//delay for 500 ms
}

在这种情况下,您将总是有大约500毫秒的时间来摆脱硬件弹跳问题。