【问题标题】:Button Debouncing in XMEGA AVRXMEGA AVR 中的按钮去抖动
【发布时间】:2016-11-15 10:26:51
【问题描述】:

我正在尝试在 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);
    }
}

【问题讨论】:

  • 如何使用 555 计时器等硬件构建去抖动功能?它比使用软件更可靠。

标签: c avr


【解决方案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 应该让您忽略按钮的多余弹跳,并且应该使用一些计时器或仅在函数本身中减少此变量,如显示的代码中所示。状态机将做出反应,然后用户释放按钮。

【讨论】:

  • 你能再具体一点吗?我的意思是,read_button_state 应该是这样写的还是什么。我现在还是空白。你能给我一个带有实际“代码”的例子吗?
  • 我不确定我理解你的意思。这是实际的“代码”,我认为我不能比这更清楚了。当程序启动时,您可以使用与系统/cpu 的整体速度配合良好的间隔调用此函数。只需记住更改 button_is_pressed 变量以匹配连接按钮的特定硬件的寄存器。你在你的例子中写了 PORTH_IN&PIN0_bm 所以我猜这是按钮的正确寄存器和掩码。
  • 它不起作用,我不知道为什么..我做错了..我在下面发布了代码
  • 我希望你能帮助你更多,但从我现在的位置来看,这很难。您需要进行一些调试以准确了解正在发生的事情。您是否以良好的间隔调用该函数?按下按钮时 PORTH_IN&PIN0_bm 会改变值吗?等
  • 间隔很好..我想。还有那个porth_in&pino_bm,是的..这会改变值。我可以用它做一个简单的按钮功能,但不能用我试图做的这个开/关的事情。如果你愿意,我可以把我的整个代码发给你.. 男孩,我真的像字面意思一样遇到了障碍。自过去 2 周以来,我一直在努力解决这个问题,没有任何变化。
【解决方案2】:

使用软件解决按钮去抖动的基本问题是了解 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 毫秒的时间来解决硬件弹跳问题。

【讨论】:

    猜你喜欢
    • 2021-06-29
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 2017-12-16
    相关资源
    最近更新 更多