首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

STM32 SysTick 定時器實現精準微秒/毫秒延遲函數詳解

     編輯:關於C語言

前言

STM32 核心內建的 SysTick 定時器是實現精準延遲的首選工具。本文詳細解析基於 SysTick 普通倒數模式的 delay_us、delay_ms 實現原理與代碼細節。

一、 核心參數初始化

static uint8_t  fac_us = 0; // us 延遲倍乘數
static uint16_t fac_ms = 0; // ms 延遲倍乘數

void delay_init(uint8_t SYSCLK) {
    // SYSCLK: 系統時鐘頻率 (MHz),例如 72
    SysTick->CTRL &= 0xFFFFFFFB; // bit2=0,選擇外部時鐘源 (HCLK/8)
    fac_us = SYSCLK / 8;         // 每個計數器脈衝週期 = 8/SYSCLK us
    fac_ms = (uint16_t)fac_us * 1000; // 1ms 對應的計數值
}

關鍵點:設定 CTRL bit2=0 選擇 HCLK/8 作為時鐘源,此時 SysTick 頻率 = 系統頻率 / 8。fac_us 代表 1us 需要的計數個數。

二、 毫秒延遲 delay_ms

void delay_ms(uint16_t nms) {
    uint32_t temp;
    SysTick->LOAD = (uint32_t)nms * fac_ms; // 載入重裝值
    SysTick->VAL  = 0x00;                   // 清空計數器
    SysTick->CTRL = 0x01;                   // 啟用定時器,無中斷

    do {
        temp = SysTick->CTRL;
    } while ((temp & 0x01) && !(temp & (1 << 16))); // 等待 COUNTFLAG (bit16) 置 1

    SysTick->CTRL = 0x00; // 關閉計數器
    SysTick->VAL  = 0x00; // 清空計數器
}

關鍵邏輯解析

  • LOAD:24 位寄存器,最大延遲受限。72MHz 下 nms <= 1864。
  • 輪詢 CTRL 寄存器:
    - bit 0 (ENABLE) = 1 表示正在計數。
    - bit 16 (COUNTFLAG) = 1 表示計數歸零。讀取後自動清零。
  • 迴圈條件 (temp & 0x01) && !(temp & (1<<16)):計數器仍啟用 且 尚未溢位時持續等待。

三、 微秒延遲 delay_us

void delay_us(uint32_t nus) {
    uint32_t temp;
    SysTick->LOAD = nus * fac_us; // 載入 us 計數值
    SysTick->VAL  = 0x00;
    SysTick->CTRL = 0x01;

    do {
        temp = SysTick->CTRL;
    } while ((temp & 0x01) && !(temp & (1 << 16)));

    SysTick->CTRL = 0x00;
    SysTick->VAL  = 0x00;
}

四、 進階注意事項

  1. 最大延遲限制:LOAD 為 24 位,最大值 0xFFFFFF。若需更長延遲,請改用通用定時器(TIM)或迴圈調用。
  2. 中斷影響:若中斷服務時間過長,會影響延遲精度。關鍵場合可暫時關中斷 __disable_irq()。
  3. 時鐘源選擇:本文用 HCLK/8。若選 HCLK (bit2=1),fac_us = SYSCLK,精度更高但最大延遲縮短 8 倍。
  4. HAL 庫替代:HAL 庫提供 HAL_Delay() (ms) 和 HAL_SYSTICK_Callback(),但裸機開發常用上述獨立實現。

總結

SysTick 延遲函數核心在於:正確配置時鐘源 → 計算倍乘因子 → 載入 LOAD → 啟動 → 輪詢 COUNTFLAG → 關閉清理。掌握 CTRL 寄存器 bit0/bit16 交互邏輯,即可靈活移植到任何 Cortex-M 內核單片機。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved