Detailed Explanation of STM32 Delay Functions

In embedded development, delay operations are one of the most common and fundamental tasks. Whether initializing peripherals, waiting for sensor responses, or handling simple task scheduling, delay functions play a crucial role. This article will provide a detailed explanation of how to use the SysTick timer to achieve microsecond, millisecond, and second-level delays based on the STM32 series (taking STM32F103 as an example).

Detailed Explanation of STM32 Delay Functions

1. Delay Function Interface Definition

In <span>delay.h</span>, we define the following three delay function interfaces:

#ifndef __DELAY_H
#define __DELAY_H

void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);

#endif

Interface Description:

  • <span>Delay_us()</span>: Implements microsecond-level delay
  • <span>Delay_ms()</span>: Implements millisecond-level delay
  • <span>Delay_s()</span>: Implements second-level delay

2. Using SysTick to Implement Delays

1. Microsecond-level Delay:<span>Delay_us()</span>

void Delay_us(uint32_t xus)
{
 SysTick->LOAD = 72 * xus;
 SysTick->VAL = 0x00;
 SysTick->CTRL = 0x00000005;
 while(!(SysTick->CTRL & 0x00010000));
 SysTick->CTRL = 0x00000004;
}

Implementation Principle:

  • Utilizes the Cortex-M3 core’s built-in SysTick 24-bit timer
  • Assuming the system clock is 72MHz, then 1 microsecond ≈ 72 clock cycles
  • Set <span>LOAD = 72 * xus</span>, SysTick starts decrementing until it reaches 0

Notes:

  • Maximum delay time ≈ 233015 microseconds (24-bit maximum value)
  • High precision, suitable for short delay scenarios

2. Millisecond-level Delay:<span>Delay_ms()</span>

void Delay_ms(uint32_t xms)
{
 while(xms--)
 {
  Delay_us(1000);
 }
}

Implementation Principle:

  • Calls <span>Delay_us(1000)</span> to achieve a 1 millisecond delay
  • Loops xms times to achieve millisecond-level delay

Notes:

  • Will occupy CPU (blocking)
  • When high precision is required, consider error accumulation

3. Second-level Delay:<span>Delay_s()</span>

void Delay_s(uint32_t xs)
{
 while(xs--)
 {
  Delay_ms(1000);
 }
}

Implementation Principle:

  • Based on <span>Delay_ms()</span> to implement a delay of one second
  • Loops to achieve multiple seconds of delay

Notes:

  • Not suitable for long delay scenarios
  • CPU will be blocked during the entire delay period, resulting in low efficiency

3. Advantages and Disadvantages of SysTick Delays

✅ Advantages:

  • Simple implementation, suitable for rapid development and testing
  • High precision (microsecond-level), strong controllability

❌ Disadvantages:

  • Blocking delay: CPU cannot perform other tasks during the delay
  • Non-interruptible: Not suitable for multitasking or systems requiring real-time response
  • Not suitable for long delays

4. Advanced Optimization Suggestions

In practical engineering, if there are higher requirements for performance, power consumption, or response speed, it is recommended to use the following methods instead of blocking delays:

  • Use hardware timer (TIM) interrupt method: Achieve non-blocking delays
  • Use RTOS (such as FreeRTOS) provided <span>vTaskDelay()</span>
  • Utilize <span>HAL_GetTick()</span><span> combined with time difference polling</span>, to achieve delays without blocking

Example (non-blocking polling):

uint32_t start = HAL_GetTick();
while(HAL_GetTick() - start < 1000) {
    // Execute other tasks, wait for 1 second
}

Leave a Comment