简体   繁体   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;
}

I want to control motor speed by slow, fast, stop with clicking switch P2.1(external interrupt) and keep turned on LED when motor is working.我想通过慢,快来控制电机速度,点击开关P2.1(外部中断)停止并在电机工作时保持打开LED。

But some problem is coming out.但是一些问题正在出现。 It seems like forward_cnt value is changing while I release button sometimes.当我有时释放按钮时,似乎forward_cnt值正在发生变化。 It works different while I keep hold on button sometimes.当我有时按住按钮时,它的工作原理有所不同。

For example, It should change its speed once when I click button once with my expectation but sometimes it changes its speed when I push, and also changes when I release button.例如,当我按预期单击一次按钮时它应该改变它的速度,但有时它会在我按下时改变它的速度,并且在我释放按钮时也会改变。 I think interrupt is not working well.我认为中断不能很好地工作。 How can I fix this clearly?我怎样才能清楚地解决这个问题?

The interrupt may be working as intended the issue is more likely with the button itself.中断可能按预期工作,问题更可能与按钮本身有关。 It seems you are running into the classic switch bouncing problem.您似乎遇到了经典的开关弹跳问题。 When a button is clicked it is not a clean transition from one logic state to the next.单击按钮时,它不是从一个逻辑 state 到下一个逻辑的干净过渡。 Referencing the picture posted below a single press of the button can cause multiple rising and falling edges.参考下面发布的图片,单次按下按钮可能会导致多个上升沿和下降沿。 Which in the case of your code will cause multiple interrupts to occur changing your forward_cnt variable almost unpredictably.在您的代码的情况下,这将导致发生多个中断,几乎无法预测地更改您的forward_cnt变量。

There are many different solutions to this problem but the most straightforward is to add in a delay after the button is pressed to allow for the bouncing of the switch to settle.这个问题有很多不同的解决方案,但最直接的方法是在按下按钮后添加延迟,以使开关的弹跳稳定下来。 After the bouncing has settled you can then increment you forward_cnt variable.反弹完成后,您可以增加forward_cnt变量。

scope capture of button when pressed scope 按下按钮时捕获

Push buttons are noisy by nature, so you need to deal with that.按钮本质上是嘈杂的,所以你需要处理它。 For example, if you were to sample the input pin from the push button, you would find it will toggle many times before settling down on the pressed value.例如,如果您要从按钮对输入引脚进行采样,您会发现它会在确定按下的值之前多次切换。 To deal with the noise, you should add a debouce function to the button press event.为了处理噪音,您应该在按钮按下事件中添加一个 debouce function。

The easiest way to do this is as mmeadwell mentioned, which is to add some delay.最简单的方法是如mmeadwell所述,即增加一些延迟。 Normally, a good design would use hardware timer for this, but in a pinch, you can just implement a software delay.通常,一个好的设计会为此使用硬件定时器,但在紧要关头,您可以只实现软件延迟。 For example, in your Port_2_1(void) interrupt routine, add this code:例如,在您的 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){

Since the button P1.1 is only used to stop the PWM, then no debounce is necessary.由于按钮 P1.1 仅用于停止 PWM,因此不需要去抖。 This noise will not change the outcome once stopped.这种噪音一旦停止就不会改变结果。

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

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