Skip to content

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:

  1. SysTick Timer — A simple, built-in 24-bit timer in the ARM Cortex-M4 core
  2. 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 ​

c
SysTick->LOAD   // Reload (0..0xFFFFFF)
SysTick->VAL    // Current value
SysTick->CTRL   // Enable/Interrupt/Clock flags
Bit NamePositionDescriptionValues
ENABLE0Timer enable/disable0 = off, 1 = on
TICKINT1Interrupt on zero0 = No IRQ, 1 = IRQ
CLKSOURCE2Clock source select0 = external, 1 = core
COUNTFLAG16Timer counted to 0 since last read1 = counted to 0

SysTick Timing ​

T=LOAD+1SystemCoreClock

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 A as 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:

RegisterPurpose/FunctionTypical Values / Usage
TIMERx->CFGWidth select: choose 32-bit or 16-bit mode0x00 = 32-bit, 0x04 = 16-bit
TIMERx->TAMRMode select: periodic or one-shotTAMR[1:0]=2 (periodic), TAMR[1:0]=1 (one-shot)
TIMERx->TAILRInterval load (reload value)0..0xFFFFFFFF (32-bit), 0..0xFFFF (16-bit)
TIMERx->TAPRPrescaler (extends interval in 16-bit mode only)0..255 (16-bit mode only)
TIMERx->CTLControl register (enable, configure timer)Set TAEN (bit 0) to enable
TIMERx->IMRInterrupt mask (enable timeout interrupt)Set bit 0 to enable timeout interrupt
TIMERx->ICRInterrupt clear (clear timeout flag)Write to clear interrupt flag after handling

Instructions for configuring Timer A in periodic mode:

  1. Set TIMERx->CFG to select timer width (32-bit or 16-bit).
  2. Set TIMERx->TAMR to periodic mode (TAMR[1:0]=2).
  3. Load the desired interval into TIMERx->TAILR (and TIMERx->TAPR if using 16-bit mode).
  4. Enable the timer by setting TAEN in TIMERx->CTL.
  5. Enable timeout interrupt in TIMERx->IMR and NVIC.
  6. In your interrupt handler, clear the flag by writing to TIMERx->ICR.

ISR sketch:

c
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):

T=TAILR+1SystemCoreClock

At 50 MHz, max ≈ 23250,000,000≈85.9 s.

16-bit mode (with prescaler):

T=(TAILR+1),(TAPR+1)SystemCoreClock

At 50 MHz, max with TAILR=65535, TAPR=255 ≈ 65536⋅25650,000,000≈0.335 s.


Examples ​

Example 1: Milliseconds Counter with SysTick Timer ​

c
#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 ​

c
#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:

c
volatile uint32_t global_ms;
volatile uint32_t last_ms;
  • Increment global_ms in the SysTick handler.
  • In the GPIOF ISR, check if (global_ms - last_ms) >= 150 before toggling the LED and set last_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