Systick Timer, taking it further with multiple blinking LEDs

In previous guide (here) we discussed how to handle Systick timer interrupt and blink a single led using interrupt generated by systick and millis function. In this guid, we will take it even further by blinking multiple leds (3 leds) in interrupt itself rather externally and one using crude inefficient delay to demonstrate the capability of interrupt.

In this guide will cover the following:

  • Locating LEDs in STM32F407 Discovery board
  • Configuring GPIO and Systick timer
  • Code

1. Locating LEDs in STM32F407 Discovery Board

In this guide, we shall use STM32F407Discovery (Link), since it has 4 built-in leds which fit perfectly for this experiment.

According to this evaluation board user manual (link), the leds are connected to the following GPIO-pins:

LED color Port connected to
OrangePD13
GreenPD12
RedPD14
BluePD15
LED connection

From the table we concluded that the LEDs are connected to PORTD.

2. Configuring GPIO and SysTick

To enable clock access to GPIOD we need to set bit 3 from AHB1ENR register show here.

Enable Clock to GPIOD

After enabling the clock, we need to set PD12, 13, 14 and 15 as output.

MODER register for GPIO

In order to configure the pins as output, we need set bits 24, 26, 28 and 30.

For configuring Systick timer, it will be as following:

  • Disable Systick Timer (SysTick->CTRL=0;).
  • load value 16000-1 for 1mS operation (SysTick->LOAD=16000-1;).
  • Select clock source to processor clock, enable interrupt and start counter (SysTick->CTRL=7;)

3. Code

#include "stm32f4xx.h"                
// clock access to GPIOD
#define GPIOD_CLOCK    (1<<3)        		
//bits of the pins 
#define LED_red_BIT    (1U<<28)					
#define LED_green_BIT  (1U<<24)
#define LED_orange_BIT (1U<<26)
#define LED_blue_BIT   (1U<<30)
//LED port 
#define	LED_PORT		    GPIOD						
//bit possition for color
#define	LED_red		 		 (1U<<14)         
#define LED_green  		 (1U<<12)
#define LED_blue       (1U<<15)
#define LED_orange     (1U<<13)
//blinking rate
#define Rate_green      200
#define Rate_blue       500
#define Rate_orange     1000
//variable to store time in milliseconds
volatile uint64_t ms;

//ineffecient delay prototype
void delay(int delayms);

int main(void)
{
//enable GPIO clock, configure pins as output and systick
__disable_irq();	
RCC->AHB1ENR |=GPIOD_CLOCK;
GPIOD->MODER |= LED_red_BIT|LED_green_BIT|LED_orange_BIT|LED_blue_BIT;
SysTick->LOAD=16000-1;
SysTick->VAL=0;
SysTick->CTRL=7; //0b00000111;
__enable_irq();
while(1)
{
//toggle red led each 2 seconds
LED_PORT->ODR^=LED_red;
delay(2000);
}

}
//ineffecient delay function
//spin lock the cpu for doing nothing
void delay(int delayms){
int i;
	for(; delayms>0;delayms--){
	for(i=0;i<3192;i++);
	}
}
//systick handler
void SysTick_Handler(void){
ms++;//increment the variable
//check if time to toggle 
if(ms%Rate_blue==0){LED_PORT->ODR^=LED_blue;}	
if(ms%Rate_green==0){LED_PORT->ODR^=LED_green;}	
if(ms%Rate_orange==0){LED_PORT->ODR^=LED_orange;}	
}

Add Comment

Your email address will not be published. Required fields are marked *