赞
踩
之前写过关于定时器输出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中断即可
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走的距离,即速度。
本次分享就到这里,希望能够多多交流,有错误麻烦大佬们指正!
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。