簡體   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