TM4C123 provides Genral Purpose Timers Module which is also called hardware timers. This tm4c123 timer example will demonstrate how to use one of Tiva c timers to blink LED with accurate timer interval generated by TM4C123 Timer 0. We will use polling method in this tutorial and will expand this to interrupt based example in our Next TM4C123 Timer Example with Interrupt code.
Introduction to Tiva™ C Timers
Timer modules are one of the crucial resources in any kind of microcontroller. These are built-in in almost all kind of microcontrollers due to their importance in Embedded Systems based real time applications. We need timers to generate accurate timing intervals which could be used to delay a task or to context switching and task scheduling. These timers are sometimes referred as “Hardware Timers” to distinguish them from software-based timing routines. There are three kinds of main usage of these timers, generating accurate timing intervals, counting pulses of various durations on the input or to generate PWM signals. This tutorial is focused on generating accurate time intervals to blink LED on TM4C123 launchpad board.
The GPT Module is one timing resource available on the Tiva™ C Series microcontrollers which we are going to discuss in this tutorial. Another timer resources include the System Timer (SysTick) which we discussed in our previous article, and the PWM timer in PWM modules. There is another special purpose Watchdog timer as well. You can read further details in this official guide from TI in Chapter 3.
Tiva C TM4C123 Timer modes of Operations
The Tiva C TM4C123 microcontroller has two General Purpose timer modules. Timer 0 and Timer 1. Each module with four 16/32-bit timers. Which are labeled A through D. These timers can be configured to operate in various modes.
Such as,
- Periodic mode
- One-shot mode
- Input edge counter mode
- Input edge time,
- PWM, and
- RTC2.
Each timer can also generate an interrupt when it reaches a certain value or conditions.
Timer Initialization without Interrupt
Here is the common flow of initialization of timers in Tiva C TM4C123 microcontrollers.
- First of all, enable the clock source for the timers we want to use. We can do this by enabling the respective bit in the
SYSCTL->RCGCTIMER
register. - Configure the timer
- Set the timer mode, with the help of
TIMER
x->CFG
register - Set periodic mode in
TIMER
x->TAMR
register - Provide Load value in
TIMER
x->TAILR
- Set the timer mode, with the help of
- Enable the timer by setting
TIMER0->CTL |= (1U << 0)
;
Here is the example code to initialize timer 0 to generate 1 second delay for TM4C123 microcontroller. We use SystemCoreClock
variable to determine the actual clock speed for the board to create accurate delay measurements.
void timer0_init(void)
{
SYSCTL->RCGCTIMER |= (1U << 0); // enable clock for timer0
TIMER0->CTL = 0; // disable timer0
TIMER0->CFG = 0; // select 32-bit mode
TIMER0->TAMR = 0x02; // select periodic mode
TIMER0->TAILR = SystemCoreClock - 1; // set reload value for 1 second delay
TIMER0->CTL |= (1U << 0); // enable timer0
}
Code language: Arduino (arduino)
TM4C123 Timer Example Code with Polling
Here is the complete code to use the Timer0 to blink the LED available on the Tiva C TM4C123G launchpad. The GPIO initializations are already explained in our previous article where we discussed the LED blinking code with for loop based delays in our Tiva C launchpad. Here is the complete code to generate 1 second delay using the Timer0 in 32-bit periodic mode configuration on TM4C123GH6PM microcontroller on Tiva C launch pad.
#include "TM4C123.h" // Device header
#define LED_RED (1U << 1)
#define TOGGLE_RED_LED (GPIOF->DATA ^= LED_RED) // toggle LED pin
void timer0_init(void);
void redLED_init(void);
int main()
{
redLED_init();
timer0_init();
while(1)
{
TOGGLE_RED_LED;
while(!(TIMER0->RIS & 1U))
; // wait for timer0 to overflow
TIMER0->ICR = 1U; // clear the timer0 interrupt flag
}
}
void redLED_init(){
SYSCTL->RCGCGPIO |= (1U << 5); // enable clock for GPIOF
GPIOF->DEN |= LED_RED; // enable digital function on pin 1
GPIOF->DIR |= LED_RED; // set pin 1 as output
}
void timer0_init(void)
{
SYSCTL->RCGCTIMER |= (1U << 0); // enable clock for timer0
TIMER0->CTL = 0; // disable timer0
TIMER0->CFG = 0; // select 32-bit mode
TIMER0->TAMR = 0x02; // select periodic mode
TIMER0->TAILR = SystemCoreClock - 1; // set reload value for 1 second delay
TIMER0->CTL |= (1U << 0); // enable timer0
}
Code language: Arduino (arduino)
TM4C123 Timer with Interrupt
Now that we had set the timer in polling mode without interrupt. We are ready to configure the timer in interrupt mode. All the initializations are similar to the above except the interrupt enabling which is done with:
// Enable Timer0 interrupt
TIMER0->IMR |= (1U << 0);
// Enable the NVIC interrupt for Timer0
NVIC_EnableIRQ(TIMER0A_IRQn);
Code language: Arduino (arduino)
This will enable the Timer 0 Interrupt in the IMR
Register and set a NVIC IRQ with by making use of weak definition of TIMER0A_IRQn
. The complete code of blinking on board LED with TIMER 0 using the Timer Interrupt and the blink rate is now changed to 500 milliseconds. Here is the complete code:
#include "TM4C123.h" // Device header
#define LED_RED (1U << 1)
#define TOGGLE_RED_LED (GPIOF->DATA ^= LED_RED) // toggle LED pin
void Timer0_Init(void);
void redLED_init(void);
int main()
{
redLED_init();
Timer0_Init();
while(1)
{
}
}
void redLED_init(){
SYSCTL->RCGCGPIO |= (1U << 5); // enable clock for GPIOF
GPIOF->DEN |= LED_RED; // enable digital function on pin 1
GPIOF->DIR |= LED_RED; // set pin 1 as output
}
void Timer0_Init(void) {
// Enable Timer0 clock
SYSCTL->RCGCTIMER |= (1U << 0);
// Disable Timer0
TIMER0->CTL &= ~(1U << 0);
// Configure Timer0 as a 32-bit timer in periodic mode
TIMER0->CFG = 0x00000000; // 32-bit mode
TIMER0->TAMR = 0x00000002; // Periodic mode
// Set the Reload Value for a 500 milliseconds delay (assuming a 16MHz clock)
//Reload Value=Clock Frequency×Desired Delay-1
TIMER0->TAILR = (SystemCoreClock / 2) - 1;
// Enable Timer0 interrupt
TIMER0->IMR |= (1U << 0);
// Enable the NVIC interrupt for Timer0
NVIC_EnableIRQ(TIMER0A_IRQn);
// Enable Timer0
TIMER0->CTL |= (1U << 0);
}
void TIMER0A_Handler(void) {
// Your code to handle Timer0 interrupt goes here
TOGGLE_RED_LED;
// Clear the Timer0 interrupt flag
TIMER0->ICR |= (1U << 0);
}
Code language: Arduino (arduino)