Dear all,
I'm developing on a LM4F232 eval board and try to output two PWM signals on pins PF0 and PF2.
For this I use Timer0 and Timer1.
This works fine for frequencies from 245Hz and up (16MHz / 65536, timer clock divided by 16bit counter range).
For frequencies below that a prescaler has to be used.
Here's the problem using the prescaler:
The frequency and duty cycle of the PWM signal get extremely inaccurate (e.g. 150Hz instead of 200Hz).
Here's the initalization code:
ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
// Unlock PF0 so it can be used for PMW output.
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;
HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= GPIO_PIN_0;
HWREG(GPIO_PORTF_BASE + GPIO_O_AFSEL) &= 0xfe;
HWREG(GPIO_PORTF_BASE + GPIO_O_DEN) &= 0xfe;
HWREG(GPIO_PORTF_BASE + GPIO_O_PCTL) = 0x00;
ROM_GPIOPinConfigure(GPIO_PF0_T0CCP0);
ROM_GPIOPinConfigure(GPIO_PF2_T1CCP0);
ROM_GPIOPinTypeTimer(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_2);
ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
ROM_TimerEnable(TIMER0_BASE, TIMER_A);
ROM_TimerEnable(TIMER1_BASE, TIMER_A);
This is the code to set the frequency and duty cycle for TIMER0:
uint16 frequency = 200;
uint16 dutyCycle = 50;
uint16 prescaler = 2;
ROM_TimerPrescaleSet(TIMER0_BASE, TIMER_A, prescaler - 1);
float32 timerLoad = static_cast<float32>(ROM_SysCtlClockGet()) / (frequency * prescaler);
float32 timerMatch = timerLoad - (timerLoad / 100) * dutyCycle;
ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, static_cast<uint32>(timerLoad));
ROM_TimerMatchSet(TIMER0_BASE, TIMER_A, static_cast<uint32>(timerMatch));
Am I doing something wrong?
The current MCU is a LM4F232HQ5D but the target will be a LM4F111B2QR.
Thanks for your help,
Stefan