MSP430FR6043: TimerB0

Part Number: MSP430FR6043

Tool/software:

Hello,

I am generating the PWM pulse from the Tb0.4. 

    param.clockSource = TIMER_B_CLOCKSOURCE_SMCLK;
    param.clockSourceDivider = TIMER_B_CLOCKSOURCE_DIVIDER_4;
    param.timerPeriod = timePeriod-1;
    param.timerInterruptEnable_TBIE = TIMER_B_CCIE_CCR0_INTERRUPT_DISABLE;
    param.captureCompareInterruptEnable_CCR0_CCIE =
            TIMER_B_CCIE_CCR0_INTERRUPT_DISABLE;
    param.timerClear = TIMER_B_DO_CLEAR;
    param.startTimer = false;
    
    Timer_B_initUpMode(TIMER_B0_BASE, &param);

    //Initialize compare mode to generate PWM1

    param1.compareRegister = TIMER_B_CAPTURECOMPARE_REGISTER_4;
    param1.compareInterruptEnable = TIMER_B_CCIE_CCR0_INTERRUPT_DISABLE;
    param1.compareOutputMode =  TIMER_B_OUTPUTMODE_SET_RESET;
    param1.compareValue = timePeriod*0;
    Timer_B_initCompareMode(TIMER_B0_BASE, &param1);

At every 100us, I have to change the duty cycle 0% to 100% (compare value). Using TimerA0 to generate the 100us loop.

#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR (void){

#if 1
    if(flag==1)
    {

        if(dCuS<50)
        {
            Dutycycle=(timePeriod*dcArray1[dCuS]);
            if(Dutycycle!=0)
            {

                Timer_B_setCompareValue(TB0_BASE,TIMER_B_CAPTURECOMPARE_REGISTER_4,(uint16_t)Dutycycle);
                dCuS+=1;
            }
            else
            {

                Timer_B_setCompareValue(TB0_BASE,TIMER_B_CAPTURECOMPARE_REGISTER_4,0);
                dCuS+=1;
            }
        }
        else
        {
            Timer_B_setCompareValue(TB0_BASE,TIMER_B_CAPTURECOMPARE_REGISTER_4,timePeriod*0.50);

            dCuS=1;
        }

        count+=1;
    }
#endif

    Timer_A_clearTimerInterrupt(TIMER_A0_BASE);
}

When I every the waveform in scope, I observed the one dip/spike in the PWM generation and it is affecting the my overall waveform.

How to rectify this?

Regards,

Sarwath

  • Every 50 TA0 cycles, you inject one TB0 cycle with a duty of 50%. Depending on whether the TB0 count happens to be less or greater than 50% of timePeriod, this may result in a 50% pulse or a 150% pulse, since in the latter case the update "missed" the intended counter value.

    Ordinarily this would be solved by using the CLLD(=1) TimerB feature to coordinate the comparator update with the timer cycle. However, the FR6043 is subject to Erratum TB25 [Ref Errata Sheet (SLAZ715B) p. 14] which says (effectively) that the timer always operates as though CLLD=0 (which is what you have now).

    The next-best solution would be to coordinate the update in software using TB0 itself: Rather than updating TB0CCR4 directly in the TA0_0 interrupt, store the intended value in a variable, then have a (new) TB0_0 ISR copy from that variable to TB0CCR4 at the beginning of the TB0 cycle. This is subject to latency hazard, though if timePeriod is sufficiently large that may not be a practical concern.

    [Edit: Fix some register names.]

**Attention** This is a public forum