[英]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.