System Timers and General-Purpose Timer Modules ​
Introduction ​
Whether you're blinking an LED, reading sensors, or creating delays, precise timing control is essential. The TM4C123 provides two powerful timing mechanisms:
- SysTick Timer — A simple, built-in 24-bit timer in the ARM Cortex-M4 core
- General-Purpose Timer Module (GPTM) — Flexible peripheral timers with advanced features
In this experiment, you'll use both, understand their strengths/limits, and apply them to real scenarios.
SysTick Timers ​
The SysTick is a 24-bit down-counter inside the Cortex-M4 core. It's designed to provide a consistent time base for operating systems and applications.
SysTick Configuration ​
SysTick->LOAD // Reload (0..0xFFFFFF)
SysTick->VAL // Current value
SysTick->CTRL // Enable/Interrupt/Clock flags| Bit Name | Position | Description | Values |
|---|---|---|---|
| ENABLE | 0 | Timer enable/disable | 0 = off, 1 = on |
| TICKINT | 1 | Interrupt on zero | 0 = No IRQ, 1 = IRQ |
| CLKSOURCE | 2 | Clock source select | 0 = external, 1 = core |
| COUNTFLAG | 16 | Timer counted to 0 since last read | 1 = counted to 0 |
SysTick Timing ​
Max LOAD is 24-bit → at 50 MHz, max period ≈ 0.335 s. For longer periods, accumulate ticks in software or use GPTM.
Note
The CMSIS helper SysTick_Config(ticks) sets the entire SysTick up with interrupts enabled. It configures LOAD, clears VAL, and enables the timer with core clock and interrupts.
GPTM (General-Purpose Timers) ​
The TM4C123 includes TIMER0-TIMER5 (standard) and WTIMER0-WTIMER5 (wide). Each module provides Timer A and Timer B. You can run:
- Two 16-bit timers (A & B) with 8-bit prescalers (standard timers), or
- One 32-bit timer (A+B concatenated) without prescaler (standard timers) accessible through
Timer Aas a single 32-bit timer. - Wide timers extend width further (32/64-bit with larger prescalers).
Common modes: One-Shot, Periodic, PWM, Input Capture/Edge Time.
GPTM Registers (Timer A, Periodic Mode) ​
Below is a summary table of key GPTM registers for configuring Timer A in periodic mode:
| Register | Purpose/Function | Typical Values / Usage |
|---|---|---|
TIMERx->CFG | Width select: choose 32-bit or 16-bit mode | 0x00 = 32-bit, 0x04 = 16-bit |
TIMERx->TAMR | Mode select: periodic or one-shot | TAMR[1:0]=2 (periodic), TAMR[1:0]=1 (one-shot) |
TIMERx->TAILR | Interval load (reload value) | 0..0xFFFFFFFF (32-bit), 0..0xFFFF (16-bit) |
TIMERx->TAPR | Prescaler (extends interval in 16-bit mode only) | 0..255 (16-bit mode only) |
TIMERx->CTL | Control register (enable, configure timer) | Set TAEN (bit 0) to enable |
TIMERx->IMR | Interrupt mask (enable timeout interrupt) | Set bit 0 to enable timeout interrupt |
TIMERx->ICR | Interrupt clear (clear timeout flag) | Write to clear interrupt flag after handling |
Instructions for configuring Timer A in periodic mode:
- Set
TIMERx->CFGto select timer width (32-bit or 16-bit). - Set
TIMERx->TAMRto periodic mode (TAMR[1:0]=2). - Load the desired interval into
TIMERx->TAILR(andTIMERx->TAPRif using 16-bit mode). - Enable the timer by setting
TAENinTIMERx->CTL. - Enable timeout interrupt in
TIMERx->IMRand NVIC. - In your interrupt handler, clear the flag by writing to
TIMERx->ICR.
ISR sketch:
void TIMER1A_Handler(void){
if (TIMER1->MIS & 0x01){ // Check if timeout interrupt
// do work (e.g., toggle LED)
TIMER1->ICR = 0x01; // clear timeout flag
}
}GPTM Timing ​
32-bit mode (no prescaler):
At 50 MHz, max ≈
16-bit mode (with prescaler):
At 50 MHz, max with TAILR=65535, TAPR=255 ≈
Examples ​
Example 1: Milliseconds Counter with SysTick Timer ​
#include "TM4C123.h"
#define GREEN_LED 0x08 // PF3 - Green LED
volatile uint32_t systick_counter = 0; // Global counter for SysTick interrupts
int main(void)
{
SYSCTL->RCGCGPIO |= (1<<5); // Enable clock to GPIOF
__asm__("NOP");
__asm__("NOP");
__asm__("NOP");
GPIOF->DIR |= GREEN_LED; // Set green LED as output pin
GPIOF->DEN |= GREEN_LED; // Enable digital function for green LED
SysTick->LOAD = 5000000 - 1; // Set reload value for 1ms
SysTick->VAL = 0; // Clear current value
SysTick->CTRL = 0x07; // Enable SysTick with processor clock and interrupt
while(1) // Main loop
{
}
}
void SysTick_Handler(void)
{
systick_counter++; // Increment counter every 1ms
GPIOF->DATA ^= GREEN_LED; // Toggle green LED
}Example 2: Maximum 16-bit Delay with GPTM ​
#include "TM4C123.h"
#define BLUE_LED 0x04
int main(void)
{
SYSCTL->RCGCGPIO |= (1<<5); // Enable clock to GPIOF
SYSCTL->RCGCTIMER |= (1<<1); // Enable clock to Timer1
__asm__("NOP"); // Wait for clock stabilization
__asm__("NOP"); // Wait for clock stabilization
__asm__("NOP"); // Wait for clock stabilization
GPIOF->DIR |= BLUE_LED; // Set blue LED as output pin
GPIOF->DEN |= BLUE_LED; // Enable digital function for blue LED
TIMER1->CTL = 0; // Disable the timer
TIMER1->CFG = 0x4; // Choose 16-bit mode
TIMER1->TAMR = 0x02; // Periodic mode
TIMER1->TAPR = 256 - 1; // Set prescaler value
TIMER1->TAILR = 65536 - 1; // Set initial reload value
TIMER1->ICR = 0x1; // Clear any prior interrupts
TIMER1->IMR |=(1<<0); // Enable timeout interrupt
NVIC->ISER[0] |= (1<<21); // Enable Timer1A interrupt in NVIC
TIMER1->CTL |= 0x01; // Enable the timer
while(1) // Main loop
{
}
}
void TIMER1A_Handler()
{
if(TIMER1->MIS & 0x1) { // Check if timer timeout interrupt occurred
GPIOF->DATA ^= BLUE_LED; // Toggle blue LED
TIMER1->ICR = 0x1; // Clear timer interrupt flag
}
}Tasks ​
Task 1: Debouncing a Push Button with SysTick ​
Update your SysTick program so that the RED LED (PF1) toggles only when SW1 (PF4) is pressed and properly debounced.
Use
SysTick_Config(SystemCoreClock/1000)to generate a 1 ms tick. Accumulate these ticks in a counter to measure longer intervals (e.g., 2000 ticks for 2 seconds).
- Debouncing requirement: Use the 1 ms SysTick counter to debounce SW1 (PF4) with a 150 ms interval. When a valid press is detected (after debouncing), toggle the RED LED (PF1).
Hint
Declare global variables:
volatile uint32_t global_ms;
volatile uint32_t last_ms;- Increment
global_msin the SysTick handler. - In the GPIOF ISR, check if
(global_ms - last_ms) >= 150before toggling the LED and setlast_ms = global_ms;.
Task 2: Multiple Blinking LEDs with GPTM ​
Use three external LEDs alongside 3 GPTM timers to blink each LED at different intervals:
- RED LED (PF1): Blink every 250 ms
- BLUE LED (PF2): Blink every 500 ms
- GREEN LED (PF3): Blink every 1000 ms