Select Page

Using SysTick with Interrupt

In the previous article, we used SysTick in a blocking mode. In this article, we will use SysTick with interrupt.

The SysTick interrupt can be used to initiate an action on a periodic basis. This action is performed internally at a fixed rate without external signal. For example, in a given application we can use SysTick to read a sensor every 200 msec. SysTick is used widely for an operating system so that the system software may interrupt the application software periodically (often 10 ms interval) to monitor and control the system operations.

If INTEN=1, when the COUNT flag is set, it causes an interrupt via the NVIC. INTEN is D1 of the STCTRL register. Examining interrupt vector table for ARM Cortex, we see the SysTick is the interrupt #15 assigned to the system itself.

Source Code

/* systick_int.c
*
* Toggle the red LED using the SysTick interrupt
*
* This program sets up the SysTick to interrupt at 1 Hz.
* The system clock is running at 16 MHz.
* 1sec/62.5ns = 16,000,000 for RELOAD register.
* In the interrupt handler, the red LED is toggled.
*/

#include <stdint.h>
#include “inc/tm4c123gh6pm.h”

void enable_irq(void);

int main (void)
{
/* enable clock to GPIOF at clock gating control register */
SYSCTL_RCGC2_R |= 0x20;
/* enable the GPIO pins for the LED (PF3, 2, 1) as output */
GPIO_PORTF_DIR_R = 0x0E;
/* enable the GPIO pins for digital function */
GPIO_PORTF_DEN_R = 0x0E;

/* Configure SysTick */
NVIC_ST_RELOAD_R = 16000000-1; /* reload with number of clocks per second */
NVIC_ST_CTRL_R = 7; /* enable SysTick interrupt, use system clock */

enable_irq(); /* global enable interrupt */

while(1) {
;
}
}

void SysTick_Handler(void)
{
GPIO_PORTF_DATA_R ^= 2; /* toggle the red LED */
}

/* global enable interrupts */
void inline enable_irq(void)
{
__asm (” CPSIE I\n”);
}

The above program uses the SysTick to toggle the red LED of PF1 every second. We need the RELOAD value of 16,000,000-1 since 1sec / 62.5nsec = 16,000,000. We assume the CPU clock is 16MHz (1/16MHz=62.5ns). The COUNT flag is raised every 16,000,000 clocks and an interrupt occurs. Then the RELOAD register is loaded with 16,000,000-1 automatically.

Notice the enabling of interrupt in SysTick Control register. Since SysTick is an internal interrupt, the COUNT flag is cleared automatically when the interrupt occurs. Also notice the SysTick is part of INT1-INT15 and not part of IRQ. For this reason we must use the CTLR register to enable it.

Note: Open tm4c123gh6pm_startup_ccs_gcc.c for editing. This file contains the vector table among other things. Open the file and look for the SysTick vector. You need to carefully find the appropriate vector position and replace IntDefaultHandler with the name of your Interrupt handler (SysTick_Handler).

See Also