【问题标题】:controlling motor speed in MSP430在 MSP430 中控制电机速度
【发布时间】:2021-06-08 08:18:14
【问题描述】:
#include <msp430.h> 

int forward_cnt = 0;
int reverse_cnt = 0;
void main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    P1DIR |= BIT0;
    P1OUT &= ~BIT0; //LED 1.0
    
    P1REN |= BIT1;
    P1OUT |= BIT1;
    P2REN |= BIT1;
    P2OUT |= BIT1; //switches
    
    P1IE |= BIT1;
    P1IES |= BIT1; //falling edge(when button is pushed)
    P1IFG &= ~BIT1;
    
    P2IE |= BIT1;
    P2IES |= BIT1;
    P2IFG &= ~BIT1;
    
    //PWM Settings
    P2DIR |= (BIT5 | BIT4);
    P2SEL |= (BIT5 | BIT4); //SET TO 1
    
    TA2CTL = TASSEL_2 + MC_1 + TACLR;
    TA2CCR0 = 1000;
    
    TA2CCTL2 = OUTMOD_6;
    TA2CCR2 = 0;
    TA2CCTL1 = OUTMOD_6;
    TA2CCR1 = 0;
    
    __bis_SR_register(GIE);
    
    while(1)
    {
      
    }
}

#pragma vector = PORT2_VECTOR
__interrupt void Port_2_1(void)
{
    
    forward_cnt++;
    switch(forward_cnt % 3){
    
    case 0 : 
        TA2CCR2 = 400;
        TA2CCR1 = 0;
        P1OUT |= BIT0;
    break;
    
    case 1 :
        TA2CCR2 = 800;
        TA2CCR1 = 0;
        P1OUT |= BIT0;
    break;
    
    case 2 : 
        TA2CCR2 = 0;
        TA2CCR1 = 0;
        P1OUT &= ~BIT0;
    break;
    }
    
    P2IFG &= ~BIT1; //interrupt end, so go back with IFG clear
}

#pragma vector = PORT1_VECTOR
__interrupt void Port_1_1(void)
{
    TA2CCR2 = 0;
    TA2CCR1 = 0;
    forward_cnt = 0;
    
    P1IFG &= ~BIT1;
}

我想控制电机速度慢,快,点击开关P2.1(外部中断)停止并在电机工作时保持点亮LED。

但是出现了一些问题。有时我释放按钮时,forward_cnt 的值似乎正在发生变化。当我有时按住按钮时,它的工作原理会有所不同。

例如,当我按预期单击一次按钮时它应该改变它的速度,但有时它会在我按下时改变它的速度,并且在我释放按钮时也会改变。我认为中断不能很好地工作。我怎样才能清楚地解决这个问题?

【问题讨论】:

    标签: msp430


    【解决方案1】:

    中断可能按预期工作,问题更可能与按钮本身有关。您似乎遇到了经典的开关弹跳问题。单击按钮时,它不是从一个逻辑状态到下一个逻辑状态的干净转换。参考下面发布的图片,单次按下按钮可能会导致多个上升沿和下降沿。就您的代码而言,这将导致发生多个中断,几乎无法预测地更改您的 forward_cnt 变量。

    对于这个问题有很多不同的解决方案,但最直接的方法是在按下按钮后添加延迟,以使开关的弹跳稳定下来。反弹完成后,您可以增加 forward_cnt 变量。

    scope capture of button when pressed

    【讨论】:

      【解决方案2】:

      按钮本质上是嘈杂的,所以你需要处理它。例如,如果您要对按钮的输入引脚进行采样,您会发现它会在确定按下的值之前多次切换。为了处理噪音,您应该在按钮按下事件中添加一个 debouce 函数。

      最简单的方法是如mmeadwell 所述,即增加一些延迟。通常,一个好的设计会为此使用硬件计时器,但在紧要关头,您可以只实现软件延迟。例如,在您的 Port_2_1(void) 中断例程中,添加以下代码:

      #pragma vector = PORT2_VECTOR
      __interrupt void Port_2_1(void)
      {
          // Variable for button state
          int button_now = 0;
          int button_last = 0;
          // Implement a debounce delay for 150 ms
          for (int delay = 0; delay < 150; delay++)
          {
              // Sample the current button state
              button_now = (P2IN & BIT1) ? 1 : 0;
              // Reset delay when state of button changes
              if (button_now != button_last) delay = 0;
              // delay 1 ms (must know your CPU clock rate)
              // using MSP430 compiler intrinsic function
              __delay_cycles(CPU_CLOCKS_PER_US * 1000);
              button_last = button_now;
          }
          // Only continue if button is currently pressed
          if (button_now == 0) return;
          // now process the button press event
          // remaining code is unchanged
          forward_cnt++;
          switch(forward_cnt % 3){
      

      由于按钮 P1.1 仅用于停止 PWM,因此无需去抖。这种噪音一旦停止就不会改变结果。

      【讨论】:

        猜你喜欢
        • 2011-10-13
        • 2018-12-15
        • 1970-01-01
        • 2014-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多