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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...