Jump to content
43oh

TimerPrescaleSet and TimerPrescaleMatchSet


Recommended Posts

Hi!

Can anyone tell me about the difference between TimerPrescaleSet() and TimerPrescaleMatchSet()? 

When do we have to call them? In what order? After which function?

I am having trouble using them. I appreciate any help!

 

Here is the example, I want to use it to extend my PWM signal period 2 times.

*******.............******.......
TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);
  // 0x0001 - value according to datasheet //
TimerPrecaleSet(WTIMER0_BASE, TIMER_B, 0x0001);
*******............********......

I know, Ther program doesn't have much sense, but I want to check it with simple program.

 

When I give 1 second period, external LED should blink every 2 second, because of the prescaler.

 

I am including whole code snippet. Without prescaler it works just fine. But with prescaler, LED is not blinking every 2 second as expected, It is blinking approximately every 5 minutes.



/******************************************************
* Use Wide Timer, split 64-bit Timer and use only TimerB-32bit as PWM generator.
******************************************************/
#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c123gh6pm.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/pin_map.h"

//initialize WideTimer-0 as PWM with given period and dutyCycle
void WideTimer0_PWM(uint32_t period, uint32_t matchval);

int main(void)
{
uint32_t ui32Period, matchValue;
//Clock at 40 MHz
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
//Set period of the timer - 2sec
ui32Period = SysCtlClockGet() * 2;
matchValue = ui32Period / 100;
matchValue = matchValue * 50;
//initilize WideTimer0 as PWM, output - PC5
WideTimer0_PWM(ui32Period, matchValue);

while(1)
{
}
}

void WideTimer0_PWM(uint32_t period, uint32_t matchval)
{
//Output will be PC-5
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
SysCtlDelay(3);
GPIOPinConfigure(GPIO_PC5_WT0CCP1);
GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_5);
//Configure WideTimer-0 as PWM generator
SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0); SysCtlDelay(3);

TimerConfigure(WTIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);
TimerPrecaleSet(WTIMER0_BASE, TIMER_B, 0x0001);
TimerLoadSet(WTIMER0_BASE, TIMER_B, period-1);

TimerMatchSet(WTIMER0_BASE, TIMER_B, matchval);

/* This sets the 8th bit in the GPTMTBMR.
* This makes it so the match value only updates after the next timeout */
HWREG(WTIMER0_BASE+TIMER_TBMR_TBILD) =1;

TimerEnable(WTIMER0_BASE, TIMER_; SysCtlDelay(3);
}
Link to post
Share on other sites

Just a bit of explanation on how to use the Prescaler Match:

 

in PWM mode the prescaller holds the most significant bits, working as a timer extension.

 

if you have a wide timer in PWM, it has 32bits and the prescaler has 16bits. If you have the Load value of the timer at 0 and the prescaler value at 1, then it means you have a number of 48bits, witht the 32st bit being 1, number 4294967296, At 80Mhz this would mean that the timer would have a period of

1/80Mhz * 4294967296  53s, less than 0.02Hz.

 

The use of the prescaller for the wide timer in PWM mode will generally not be the most useful since the wide timer is alredy 32bits and can make any PWM low frequency starting at 1Hz, for the normal timers (which are 16bits in pwm mode) it's more useful to do something like control a servo which requires 50Hz PWM, something impossible with a 16bit timer with a source of 80Mhz system clock.

 

If you want to set a match, which in PWM mode is when a signal turns from 1 to 0, setting the duty, you need to not only use TimerMatch, but also do so for the prescaler. This is because TimerMatch only sets the match for the 32bits of the timer, for the prescaler bits you need to change other register (hence the different function).

 

Now the 2s blink.

If you want the LED to change state every 2 second you can set the PWM to a period of 4s, and a duty of 50%, this will make it change from 1-0 and back to 1, every 2s.

At 40MHz, you do 4s * 1/40Mhz = 160000000, which needs 40bits, so the prescaler is needed. This number needs in the prescaler the value 0x9 and in the timert the value, 0x896800 - 1 (-1 because, remember tha the 0 counts). These are the load values.

Now to set the duty to 50%, you have the (160000000-1) /2 = 79999999,5, lets say just 79999999. It's 0x4C4B3FF, which has values in the prescaler. So we do prescaler match with 0x4 TimerMatch with 0xC4B3FF.

With this you have a LED that changes state every 2s by using a 4s period PWM.

 

If you actually need the led to every 2s to do a short blink, i think you now see how the prescaller works to do that.

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...