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.

Stellaris Launchpad (LM4F120H5QR) PWM problem

Hi guys 
I'm tryng to realize a pwm modulation to drive a servo motor and I have found something strange.
The following code works well as you can see in image1.

//This code will PWM the leds
#define PART_LM4F120H5QR true
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/pin_map.h"
int main(void) {
unsigned long ulPeriod_led_f1, dutyCycle_led_f1, ulPeriod_led_f2, dutyCycle_led_f2, ulPeriod_led_f3, dutyCycle_led_f3;
unsigned long ciao;
// 40 MHz system clock
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
ciao = SysCtlClockGet();

//ulPeriod_led_f3 = 20000;
//dutyCycle_led_f3 = 11500;

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinConfigure(GPIO_PF2_T1CCP0);
GPIOPinConfigure(GPIO_PF3_T1CCP1);
GPIOPinTypeTimer(GPIO_PORTF_BASE, GPIO_PIN_2 );
GPIOPinTypeTimer(GPIO_PORTF_BASE, GPIO_PIN_3 );
// Configure timer 0  this timer outputs to pf1 (led)
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE, (TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM|TIMER_CFG_B_PWM));
TimerControlLevel(TIMER1_BASE, TIMER_BOTH, 0);
TimerPrescaleSet(TIMER1_BASE, TIMER_A, 0);
TimerMatchSet(TIMER1_BASE,TIMER_A, 400);
TimerLoadSet(TIMER1_BASE,TIMER_A, 800);
//24000

ciao = TimerLoadGet(TIMER1_BASE,TIMER_A);

TimerEnable(TIMER1_BASE, TIMER_BOTH);
while(1) {
// TimerMatchSet(TIMER1_BASE, TIMER_A, dutyCycle_led_f2 = dutyCycle_led_f2+1);
// TimerMatchSet(TIMER1_BASE, TIMER_B, dutyCycle_led_f3 = dutyCycle_led_f3+2);
// if (dutyCycle_led_f2 >= ulPeriod_led_f2 - 1) dutyCycle_led_f2 = 0;
// if (dutyCycle_led_f3 >= 1000) dutyCycle_led_f3 = 0;

}

}

A simple variation in the prescaler (1 instead of 0) causes a different behaviour as you can see in image2.

TimerPrescaleSet(TIMER1_BASE, TIMER_A, 1);

what's wrong?

Can you help me?

Thank you so much

Matteo

  • Matteo,

    What are you trying to acheive by setting the prescaler to 1? Before touching the prescaler, I would look at the section 11.3 of the datasheet for the LM4F120H5QR, http://www.ti.com/lit/ds/spms294d/spms294d.pdf

    You can think of the combination of the 16-bit timer (timer 1A) with the 8-bit prescaler as a 24-bit timer, with the prescaler being the most significant 8 bits. In the situation when the prescaler is 0, your 24-bit timer is loaded with the value 0x00000320 (decimal value of 800), which has a difference of 400 clock cycles to your match value of decimal 400. This means that the PWM will output a 1 for the first 400 cycles (the time from 800 to 400), then low for the last 400 cycles (400 to 0).

    Now when you set the prescaler as 1, your 24-bit load value then becomes 0x01000320, which is the decimal value of  16778016. Now this means that timer will count-down from that value to 400, which will take 16777616 cycles, staying high for that entire time. Once it hits 400, it will stay low for 400 cycles. It will continue that pattern, which is why you're seeing such a long period of a high PWM, with a short low-time.

    Just for clarity, if you changed the prescaler match value to 1 as well, you would see the exact opposite: a waveform that basically stays low with short spikes. That would stem from the high value lasting from 0x01000320 to 0x01000160, while the waveform stays low from 0x01000160 to 0x0.

    Regards,

    Reagan

  • Thank you for your quick and clear answer!