[英]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
變量。
按鈕本質上是嘈雜的,所以你需要處理它。 例如,如果您要從按鈕對輸入引腳進行采樣,您會發現它會在確定按下的值之前多次切換。 為了處理噪音,您應該在按鈕按下事件中添加一個 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.