STM32 HAL库开发学习5. 系统滴答定时器

STM32 HAL库开发学习5. 系统滴答定时器

  • 一、滴答定时器概述
    • [1. 概述](#1. 概述)
    • [2. 时钟源](#2. 时钟源)
    • [3. 寄存器](#3. 寄存器)
      • [(1)控制与状态寄存器 STK_CTRL](#(1)控制与状态寄存器 STK_CTRL)
      • [(2)重载寄存器 STK_LOAD](#(2)重载寄存器 STK_LOAD)
      • [(3)当前值寄存器 STK_VAL](#(3)当前值寄存器 STK_VAL)
  • 二、HAL库滴答定时器初始化
  • 三、SysTick实现微秒级延时
    • [1. 使用 STM32CubeMX创建工程](#1. 使用 STM32CubeMX创建工程)
    • [2. 代码实现](#2. 代码实现)

一、滴答定时器概述

1. 概述

滴答定时器是Cortext-M内核的一个简单定时器。

滴答定时器是一个24位的递减计数器,主要用于为嵌入式系统提供基本的定时功能,也为实时操作系统RTOS提供系统节拍。

2. 时钟源

滴答定时器有两个可选的时钟源,一个是处理器内核时钟: HCLK,另一个是外部参考时钟。

当定时器启动后,它会从设定的初始值开始递减计数。每经过一个时钟周期,计数器值减1.当计数器减到0,会产生一个中断请求,并且可以根据设置重新加截初始值。

3. 寄存器

(1)控制与状态寄存器 STK_CTRL

该寄存器用于控制滴答定时器的主要功能。其中包含了启动 / 停止定时器的位(ENABLE 位),如果将此位置 1,则启动定时器;若置 0,则停止定时器。

还有用于控制中断使能的位(TICKINT 位),当这个位置 1 时,定时器计数到 0 时会产生中断;置 0 则禁止中断。

另外,有一个位用于指示定时器当前是否正在计数(COUNTFLAG 位),可以通过读取这个位来确定定时器是否已经完成了一次计数循环。

(2)重载寄存器 STK_LOAD

这个寄存器用于设置滴答定时器的初始计数值。因为定时器是 24 位的,所以可以设置的最大值为 。通过设置这个寄存器的值,可以确定定时器每次计数循环的时长。例如,根据所选的时钟源频率和想要实现的定时周期,计算出相应的初始值并写入这个寄存器。

(3)当前值寄存器 STK_VAL

可以读取当前定时器计数器的剩余值。不过需要注意的是,在某些情况下读取这个寄存器的值可能会受到限制或者需要特殊的操作顺序。例如,在一些芯片中,可能需要先暂停定时器(通过清除 ENABLE 位)才能准确读取当前值。

二、HAL库滴答定时器初始化

使用 STM32CubeMX 生成的项目里,main函数会调用 HAL_Init();

进入该函数,可以看到如下调用 :

c 复制代码
  /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
  HAL_InitTick(TICK_INT_PRIORITY);

// 宏的值
#define  TICK_INT_PRIORITY            15U    /*!< tick interrupt priority (lowest by default)  */

这里即实现了滴答定时器的初始化。

三、SysTick实现微秒级延时

本实验实现微秒及翻转IO端口。

1. 使用 STM32CubeMX创建工程

GPIO里,配置PA8为输出,

SYS里,配置时间基准源为SysTick,Debug 为Serial Wire。

RCC,时钟源,把 High Speed Clock(HSE) 选择: Crystal/Ceramic Resonator。

然后把时钟配置 HCLK设置为72MHz:

回车,提示窗口选择OK,系统自动把PLL设置好。

打开生成的项目。

2. 代码实现

c 复制代码
/**
 * @brief 微秒级延时
 * @param us
 */
void my_delay_us(uint32_t us) {
    uint32_t ticks_per_us = SystemCoreClock / 1000000;
    uint32_t start_ticks = SysTick->VAL;
    uint32_t delay_ticks = us * ticks_per_us;
    if (delay_ticks > start_ticks) {
        delay_ticks = delay_ticks - start_ticks + SysTick->LOAD;
    } else {
        delay_ticks = delay_ticks + SysTick->LOAD - start_ticks;
    }
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) {
        if ((SysTick->LOAD - SysTick->VAL) > delay_ticks) {
            break;
        }
    }
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

/**
 * @brief 毫秒级延时
 * @param ms
 */
void my_delay_ms(uint32_t ms) {
    while (ms--) {
        my_delay_us(1000);
    }
}

main函数:

c 复制代码
int main(void) {

    /* USER CODE BEGIN 1 */

    /* USER CODE END 1 */

    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    /* USER CODE BEGIN 2 */

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1) {
        /* USER CODE END WHILE */
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);
        my_delay_ms(1);
        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

在PA8观察输出的波形:

相关推荐
嗯嗯=33 分钟前
STM32单片机学习篇9
stm32·单片机·学习
ooo-p2 小时前
FPGA学习篇——Verilog学习之“呼吸灯”
学习·fpga开发
求真求知的糖葫芦2 小时前
微波工程4.2节阻抗与导纳矩阵学习(自用)
笔记·学习·线性代数·矩阵·射频工程
炽烈小老头2 小时前
【 每天学习一点算法 2026/01/26】缺失数字
学习·算法
子夜江寒4 小时前
OpenCV 学习:图像拼接与答题卡识别的实现
python·opencv·学习·计算机视觉
wdfk_prog4 小时前
[Linux]学习笔记系列 -- [drivers][base]platform
linux·笔记·学习
小范馆5 小时前
ESP各模组的引脚图-小智接线图
stm32
松涛和鸣5 小时前
DAY63 IMX6ULL ADC Driver Development
linux·运维·arm开发·单片机·嵌入式硬件·ubuntu
W_a_i_T5 小时前
【Coding日记】菜鸟编程C语言100例——第一题
c语言·学习·编程思维·菜鸟编程
朔北之忘 Clancy6 小时前
2025 年 12 月青少年软编等考 C 语言二级真题解析
c语言·开发语言·c++·学习·算法·青少年编程·题解