C - 按钮按下一次,注册两次 - MSP430

标签 c embedded microcontroller interrupt msp430

我想创建一款游戏,玩家必须使用 MSP430 上的按键重复随机的闪烁模式。随机模式由 ADC 创建 - 0 代表 P1.0 上的红灯闪烁,1 代表 P4.7 上的绿灯闪烁。

在我自己玩过之后,我注意到有时当我按一次按钮时,它会被记录为按了两次。

例如:图案为红/红/红/绿(0/0/0/1),然后按左按钮两次,右按钮一次就足够了,因为左按钮的第一次按下被注册为两次按下。< br/> 我将游戏代码缩减为更小的程序,只需重复上面示例的模式即可:

#include <msp430.h> 

int pattern[4];
unsigned int index = 0;
unsigned int button;
unsigned int buttonPressed = 0;

void Initialize_LED(void)
{
  P4DIR = P4DIR | 0x80; 
  P4OUT &= ~0x80;
  P1DIR = P1DIR | 0x01;   
  P1OUT &=~0x01;                                                       
  pattern[0] = 0;
  pattern[1] = 0;
  pattern[2] = 0;
  pattern[3] = 1;
}  

void Initialize_Buttons(void){
  P1REN |= 0x02;                         
  P1OUT |= 0x02;                          
  P2REN |= 0x02;                          
  P2OUT |= 0x02;                          
  P1IFG &= ~0x02;                        
  P2IFG &= ~0x02;                         
  P1IE |= 0x02;                           
  P2IE |= 0x02;                           
                                      //Timer:----------------------------     
  TA1CTL = TASSEL_1+ID_0+MC_2+TACLR;  // 
  TA1R = 40000;                       // 
                                      // ----------------
  _BIS_SR(GIE);                            

}

void main(void)                                                         
{                                                               
  WDTCTL = WDTPW + WDTHOLD;                                                                                                             
  Initialize_LED();   
  Initialize_Buttons();

  int done = 0;
  while(done == 0){
    if(buttonPressed == 1){
      if(pattern[index] != button){
          P1OUT ^= 0x01;
          done++;                       //wrong button --> green light on
      } else {
          index++;
          buttonPressed = 0;
          if (index == 4){
            done++;
          }
      } 
    }     
   }
    P1OUT ^= 0x01;                      // correct pattern --> both lights on
    P4OUT ^= 0x80;
}


#pragma vector=PORT1_VECTOR // ----------- Interrupt Service Routine -----------
__interrupt void Port1_Interrupt (void) {

  buttonPressed = 1;                                      
  if (P1IFG&0x02){                          
    button = 1;
    P1IE &= ~0x02;                          
    TA1CTL |= TAIE;                        
    TA1R = 50000;                           
  }                                         
}

#pragma vector=PORT2_VECTOR // ----------- Interrupt Service Routine -----------
__interrupt void Port2_Interrupt (void) {

  buttonPressed = 1;                        
  if (P2IFG&0x02){                          
    button = 0;
    P2IE &= ~0x02;                          
    TA1CTL |= TAIE;                         
    TA1R = 50000;                           
  }                                         
}

#pragma vector=TIMER1_A1_VECTOR             // Timer1_A3 Interrupt Vector(TAIV) handler
__interrupt void TIMER1_A1_ISR(void)
{
    switch (__even_in_range(TA1IV, 14))
    {
    case  0: break;                          
    case  2: break;                          
    case  4: break;                          
    case  6: break;                          
    case  8: break;                          
    case 10: break;                          
    case 12: break;                          
    case 14:                                 
                 P1IFG &= ~0x02;                
                 P1IE |= 0x02;                  
                 P2IFG &= ~0x02;                
                 P2IE |= 0x02;                  
                 TA1CTL &= ~TAIE;                
                 break;
    default: break;
    }  
}

我使用调试器检查了代码,但找不到这种情况持续发生的原因。有人可以帮助我吗?
感谢您的宝贵时间!

最佳答案

每个机械触点都会产生脉冲 - 在开关打开和关闭期间反弹。您需要为此创建一个去抖过滤器。

我的建议是让您完全避免中断读取按钮状态。

通过软件对按钮进行去抖的最佳方法是使用比按钮生成弹跳脉冲更长的采样时间进行采样(通常约为 1-10ms)。

您可以通过每 10 毫秒读取一次按钮的实际状态并将其与之前的状态进行比较来做到这一点。然后您将拥有完全去抖的按钮。

我在许多项目中使用这种方法,在这些项目中我不需要硬件过滤器,并且在任何 PC 键盘中都使用相同的原理,其中不可能添加硬件过滤器,因为所有按钮都是复用的,但这是最好在https://electronics.stackexchange.com上讨论

关于C - 按钮按下一次,注册两次 - MSP430,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50588451/

相关文章:

c++ - 嵌入式设备的有限状态机

c - 再次收集2 : ld returned 1 exit status

谁能解释一下这个复杂的指针表达式?

c - gnu c on_exit - 段错误

c - 从文件中查找子字符串索引的程序

c - 嵌入式-C :How to perform division between 2 unsigned integers and display the answer in decimal format

c - 微 Controller 编程要学什么语言?

c++ - 如何将boost随机数生成器的状态存储为const char *?

c - 我如何用我的内核创建可引导 CD 镜像?

c++ - 关键任务实时应用程序中的安全 C++