This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Wide Timer PWM with variabile frequency problem.

Other Parts Discussed in Thread: TM4C123AE6PM

Hello everyone, 

I have searched over forum but I believe I haven't found right answer to my problem. Basically, what I have, I have made PD6 to use its WT5CCP0 function, to generate PWM signal using the wide timer (TM4C123AE6PM is MCU used). I'm using the wide timer since the frequency of signal goes from 2Hz up. This signal has variable frequency and duty cycle. Duty cycle I change with changing value of the variable in TimerMatchSet, and for the frequency, I assumed in changing value of period and in TimerLoadSet and then resetting match value.

For duty cycle is fine, but problem is when I'm changing frequency and monitoring signal in oscilloscope, signal is quite unstabile it even seems that duty cycle is changing in blinks, I tried to disable timer when reconfiguring and enabling it, and also setting TIMER_TAMR_TAMRSU bit to 1 to get match value update after next timeout but still it's unstable when freq is changing.

Frequency is changed on user interaction with the potentiometer. Do you have some kind of advice or note of what I'm doing wrong? Maybe you have some better idea on how to change frequency for timer generated PWM.

Here is code snippet: 

SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER5);

	GPIOPinConfigure(GPIO_PD6_WT5CCP0);

	GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_6);

	ulPeriod = SysCtlClockGet()/200;	//200Hz default 	sysclk/freq

	ui32PWMFreq_prev = 200.0;

	dutyCyclePWM2 = (unsigned long)(ulPeriod-1)*(1-(5.0/100.0));	//5% default

	ui32PWMPlsWidth_prev=dutyCyclePWM2;

	TimerConfigure(WTIMER5_BASE, (TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM));

	TimerLoadSet(WTIMER5_BASE, TIMER_A, ulPeriod-1);

	TimerMatchSet(WTIMER5_BASE, TIMER_A, dutyCyclePWM2);

        HWREG(WTIMER5_BASE+0x00000400) =1;

	TimerEnable(WTIMER5_BASE, TIMER_A);

  • Djedjica said:
    when I'm changing frequency and monitoring signal in oscilloscope, signal is quite unstabile it even seems that duty cycle is changing in blinks...

    Had not one here - on multiple occasions - advised that PWM at so low a frequency may descend into, "On-Off" keying?

    Suspect your post would benefit from your limiting the PWM frequency to 100Hz (no lower) and then reporting your results...

  • Hello Djedica,

    I do not see that you have enabled TimerUpdateMode with either TIMER_UP_LOAD_TIMEOUT or TIMER_UP_MATCH_TIMEOUT

    They can be used to update the values when either a Load event or a Match event occur. So any changes made till then will not be reflected on the output

    Regards
    Amit
  • Hello Mr. cb1,
    Thank You for a quick response. Yes, I used this wide timer specifically for the need for low-frequency PWM. Feel bad that I haven't thought to that before, just use gpio for low frequencies and use PWM outputs for higher ones. So I now have this problem since PD6 in this controller hasn't got PWM function. Nevertheless, I tried with just higher frequencies, the problem remains. What comes to my mind, I use 12-bit resolution potentiometer, and when changing frequency I reconfigure timer too many times so signal is this messy when spinning potentiometer, when it is released signal is ok with right duty cycle and right frequency. So maybe timer shouldn't be changed this many times in realtime or something... That is why I tried to set bit in GPTMTAMR register, to keep the the match value only updates after the next timeout , should something be set for setting timer period also?
  • Yes, that was it. Now the signal is not messy while frequency is changing. Thank you all very much. Just in future if someone is interesed, I know it helps me in searching for answers, I only put another line in timer configuration function before enabling timer, now it seems it goes well.

            SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER2);
    	GPIOPinConfigure(GPIO_PD0_WT2CCP0);
    	GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_0);
    	dutyCyclePWM2 = (unsigned long)(ulPeriod-1)*(1-(5.0/100.0));	//5% default
    	TimerConfigure(WTIMER2_BASE, (TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM));
    
    	TimerUpdateMode(WTIMER2_BASE, TIMER_A, TIMER_UP_LOAD_TIMEOUT | TIMER_UP_MATCH_TIMEOUT);
    
    	TimerLoadSet(WTIMER2_BASE, TIMER_A, ulPeriod-1);
    	TimerMatchSet(WTIMER2_BASE, TIMER_A, dutyCyclePWM2);
    	TimerEnable(WTIMER2_BASE, TIMER_A);

  • Hello Djedjica

    The synchronization mechanism is a very "under" used feature on almost all timers, PWM and ADC modules. glad it worked for you.

    Regards
    Amit