繁体   English   中英

在 MSP430 中控制电机速度

[英]controlling motor speed in MSP430

#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值正在发生变化。 当我有时按住按钮时,它的工作原理有所不同。

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

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

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

scope 按下按钮时捕获

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

最简单的方法是如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,因此不需要去抖。 这种噪音一旦停止就不会改变结果。

暂无
暂无

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

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