MSP430 Timer模块应用——输出比较编码器测速(五)

之前写过关于定时器输出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走的距离,即速度。

本次分享就到这里,希望能够多多交流,有错误麻烦大佬们指正!

物联沃分享整理
物联沃-IOTWORD物联网 » MSP430 Timer模块应用——输出比较编码器测速(五)

发表评论