Jump to content
mnowator

[LM4F120H5QR] Wide timers dont work in PWM mode.

Recommended Posts

Hello, im barely new in ARM programming. What i want to do is to run four independent PWM channels to manage my things. I wrote some code and as i supposed it didint work. In debug process i checked registers and it seems to be ok. Load and match values are corerct so i think error is somewhere in timers configuration. Can someone help me out ? Thanks in advance for reply.

 

Here is my code that i ran on my launchpad.

#define PART_LM4F120H5QR 1

#include <inc/hw_types.h>
#include <inc/hw_memmap.h>
#include <driverlib/sysctl.h>
#include <driverlib/gpio.h>
#include <driverlib/pin_map.h>
#include <driverlib/timer.h>

#define PWM_FREQ 20000


void InitGPIOs()
{
	// running clock for gpio C
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
}

void InitPWMs()
{
	// runing clock for timers: wide timer 0 and wide timer 1, both 64 bits
	SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER1);

	TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM); // timer0 A
	TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PWM); // timer0 B
	TimerConfigure(WTIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM); // timer1 A
	TimerConfigure(WTIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PWM); // timer1 B

	// 20 khz freq
	TimerLoadSet(WTIMER0_BASE, TIMER_A, (SysCtlClockGet()/PWM_FREQ)-1 );
	TimerLoadSet(WTIMER0_BASE, TIMER_B, (SysCtlClockGet()/PWM_FREQ)-1 );
	TimerLoadSet(WTIMER1_BASE, TIMER_A, (SysCtlClockGet()/PWM_FREQ)-1 );
	TimerLoadSet(WTIMER1_BASE, TIMER_B, (SysCtlClockGet()/PWM_FREQ)-1 );

	// initial width value
	TimerMatchSet(WTIMER0_BASE, TIMER_A, (SysCtlClockGet()/PWM_FREQ)/2);
	TimerMatchSet(WTIMER0_BASE, TIMER_B, (SysCtlClockGet()/PWM_FREQ)/2);
	TimerMatchSet(WTIMER1_BASE, TIMER_A, (SysCtlClockGet()/PWM_FREQ)/2);
	TimerMatchSet(WTIMER1_BASE, TIMER_B, (SysCtlClockGet()/PWM_FREQ)/2);

	// enabling timers
	TimerEnable(WTIMER0_BASE, TIMER_A);
	TimerEnable(WTIMER0_BASE, TIMER_;
	TimerEnable(WTIMER1_BASE, TIMER_A);
	TimerEnable(WTIMER1_BASE, TIMER_;

	// pin muxing for pwms
	GPIOPinConfigure(GPIO_PC4_WT0CCP0);
	GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_4);
	GPIOPinConfigure(GPIO_PC5_WT0CCP1);
	GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_5);
	GPIOPinConfigure(GPIO_PC6_WT1CCP0);
	GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_6);
	GPIOPinConfigure(GPIO_PC7_WT1CCP1);
	GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_7);
}

int main()
{
	// setting clock to maximum speed 80 Mhz
	SysCtlClockSet(SYSCTL_USE_PLL | SYSCTL_SYSDIV_2_5 | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);


	InitGPIOs();
	InitPWMs();

	while(true)
	{

	}

	return 0;
}

Share this post


Link to post
Share on other sites

SysCtlClockGet is broken in some versions of the library (Tivaware) for some clock speeds (e.g. 80 MHz).

Check that it is returning what you expect it to return.

 

Did you check the values of the configuration registers?  It sort of looks to me like the code for TimerConfigure may overwrite the timer A configuration when you are writing the timer B configuration.  (i.e. it might be that you need to do one TimerConfigure call for each timer, combining the information for the split timers).

TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM)

Might also consider configuring the pins before enabling the timer.  (Not sure it makes any difference.)

 

Enabling the timers one at a time should work, but more concise to say

TimerEnable(WTIMER0_BASE, TIMER_BOTH);

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×