繁体   English   中英

微控制器中的按钮按下和保持检测

[英]Button press and hold detection in microcontroller

我正在尝试实现一种逻辑来检测来自射频遥控器的按键和按住。 目前,我能够检测到 controller RF 接收器中的按钮按下。 每次按下我都会收到中断回调。 现在如何检测代码中的按住 5 秒?

我检查了示波器,当我按住遥控器的一个键时,我每 34 毫秒在接收器中获取一次射频数据。

我能想到的就是在 5 秒内用相同的数据计算连续中断的数量并验证它,但我不确定它是正确的方法。

任何建议如何实施。 我会试试。

谢谢

首先,根据您使用的射频技术,您可能无法获得实时响应。 一些射频技术具有相对较长的延迟/传播延迟,并且许多根本无法保证实时性。 您可能需要通过使用 scope 测量发射器中的物理按键与接收器中检测到该按键之间的时间来考虑这一点。

此外,我们必须假设按钮在发射器侧已正确消除抖动,否则您将收到大量通过空气发送的垃圾。

可能的方法1:

  • 使用循环定时器中断,每 50 毫秒左右读取一次按钮的 state。 您可以使用计数器变量,如果按下按钮,则该变量增加 1,如果释放按钮,则该变量设置为零。

可能的方法2:

  • 获得第一个键盘中断后,假设它在上升沿触发,将中断更改为现在在下降沿触发。 然后启动一个计时器并确保在计时器运行期间没有中断触发。

    一些 MCU 定时器外设支持两个边沿的输入捕获,因此您可以基于此实现上述各种替代方法。

可能的方法3:

  • 如果使用一些简单的 OOK 东西并且发射器在按下按钮之前一直处于休眠状态,那么您可以使用 RFIC 提供的任何 RSSI 功能来简单地记录 RSSI。 但是这样你需要一些方法来检测实际上是你的发射器导致了 RSSI 到 go 上升。

使用任何按钮、直接按钮或在这种情况下为遥控器的一个好主意是检测按下和释放。 然后在此之上应用按住时间。 这样,物理按钮和远程按钮可以以相同的方式处理。

在这种情况下,您可以通过设置一个 50 毫秒的计时器来检测释放,该计时器在每 35 毫秒按钮中断时重新启动。 然后,如果 50 毫秒计时器到期,则按钮已被释放(或超出范围)。

然后对于 5 秒保持,您可以有 5 秒计时器,可以在按钮按下时启动,并在按钮释放时取消。 同样,如果该计时器到期,您将触发保持事件。

计时器可以在软件或硬件中实现,尽管将两个硬件计时器专用于一个按钮可能会浪费资源。

另请参阅按下按钮 3 秒以及如何使用 Atmega8 1MHz 测量其时间? . 给定如上所述的按下/释放检测,您可以应用更高级别的保持时间,如该问题的已接受答案中所示。

非常感谢大家的建议。 我根据用户“the busybee, Clifford and Lundin”的建议实现了这个逻辑,它现在正在运行。 请看一看。

void ISR_callback(uint32_t value) //Button press ISR
{
   button_data = (uint8_t)((value>>8) & 0xF);
   
   if(button_data == 0xB) //required button pressed
   {
      button_pressed = 1;
      button_timer_50ms = 0; //reset the independent 50ms counter, if button pressed
   }
 }

void main(void)
{
    while(1)
    {
        if (one_ms_time_expired()) //1ms timer loop
        {
          if(button_pressed) //is set in ISR, if button is pressed
          {
              timer_5sec++; //Counter to check if key is pressed for 5 sec
              button_timer_50ms++; //Independent counter to reset status if button is released

              if(button_timer_50ms==50) //if no key pressed for 50ms, reset all status
              {
                    button_timer_50ms = 0;
                    button_pressed = 0;
                    timer_5sec = 0;
                    button_data = 0;
              }
              if(timer_5sec == 5000) //5sec done
              {
                    timer_5sec = 0;
                    button_data = 0;
                    button_pressed = 0;
                    button_timer_50ms = 0;
                    //Buzzer_ON
              }
           }
        }
     }
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM