之前写过关于定时器输出PWM波的简便方法和利用定时器测量频率,由于之前采用的测周法,这个方法当时测量的频率是非常精准的,但是对于测速度而言,我们采用PID算法的话,就会使得轮子停止响应非常的迅速,在之前算法的基础上,这个当轮子突然停止,也就是说突然一下没有外来脉冲了,会导致频率计算出错,维持一个定值,按理来说应该是零的(如果能够从算法上解决这个问题的话,麻烦大佬们评论区传授一下方法),因此,今天开始尝试利用测频法进行速度测量,相应的使用的就是定时器的输出比较功能,即开一定时间的定时器,再打开IO中断捕捉上升沿或者下降沿,每隔一定时间,获取IO中断捕获的上升沿或者下降沿的脉冲数,从而达到计算速度的目的。
第一步:初始化对应定时器
Timer_A_initContinuousModeParam initContParam = {0};//定义连续模式结构体变量
initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;//选择SMCLK
initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_16;//不分频
initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;//暂时不使能中断
initContParam.timerClear = TIMER_A_DO_CLEAR;//清除定时器
initContParam.startTimer = false;//暂时不开始计时
Timer_A_initContinuousMode(TIMER_A0_BASE, &initContParam);
//Initiaze compare mode
Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,//清楚定时器的中断标志位
TIMER_A_CAPTURECOMPARE_REGISTER_4
);
Timer_A_initCompareModeParam initCompParam = {0};
initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_4;//选择对应的捕获比较寄存器
initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;//使能定时器中断
initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;//选择输出模式
initCompParam.compareValue = COMPARE_VALUE;//确定比较值
Timer_A_initCompareMode(TIMER_A0_BASE, &initCompParam);//初始化比较模式
Timer_A_startCounter( TIMER_A0_BASE,//开始计数
TIMER_A_CONTINUOUS_MODE
);
//Enter LPM0
__bis_SR_register(LPM0_bits);
//For debugger
__no_operation();
第二步:中断服务函数
#pragma vector=TIMER0_A1_VECTOR//中断 TIMER1_A0_VECTOR
__interrupt void TIMER0_A1_ISR (void)
{
unsigned int compval;
switch(__even_in_range(TA0IV,14))
{
case 8:
compval = Timer_A_getCaptureCompareCount(TIMER_A0_BASE,
TIMER_A_CAPTURECOMPARE_REGISTER_4)
+ 50000;
//Toggle P1.0
GPIO_toggleOutputOnPin(
GPIO_PORT_P1,
GPIO_PIN6
);
//Add Offset to CCR0
Timer_A_setCompareValue(TIMER_A0_BASE,
TIMER_A_CAPTURECOMPARE_REGISTER_4,
compval
);
break;
}
_BIC_SR_IRQ(LPM0_bits);
}
根据所选的定时器的频率,确定所需要的定时器时长,即上述代码中的50000.
接下来就是打开IO中断即可
第三步:打开IO中断
void IO_IT_Init(void)//IO中断初始化
{
GPIO_setAsInputPinWithPullUpResistor(
GPIO_PORT_P2,
GPIO_PIN3);
GPIO_enableInterrupt(
GPIO_PORT_P2,
GPIO_PIN3
);
GPIO_selectInterruptEdge(
GPIO_PORT_P2,
GPIO_PIN3,
GPIO_HIGH_TO_LOW_TRANSITION
);
//P2.3 IFG cleared
GPIO_clearInterrupt(
GPIO_PORT_P2,
GPIO_PIN3
);
//Enter LPM4 w/interrupt
__bis_SR_register(LPM4_bits + GIE);
//For debugger
__no_operation();
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT2_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(PORT2_VECTOR)))
#endif
void Port_2 (void)
{
num++;
//P2.3 IFG cleared
GPIO_clearInterrupt(
GPIO_PORT_P2,
GPIO_PIN3
);
}
IO中断需要手动清除中断标志位。
接下来就是计算了,计算的原理很简单。比如定时50ms产生了100个脉冲,即1ms产生2个脉冲,即1s产生2000个脉冲。再根据编码电机的减速比等参数,即可得出1s走的距离,即速度。文章来源:https://www.toymoban.com/news/detail-614399.html
本次分享就到这里,希望能够多多交流,有错误麻烦大佬们指正!文章来源地址https://www.toymoban.com/news/detail-614399.html
到了这里,关于MSP430——Timer(输出比较编码器测速)(五)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!