STM32F429第十篇之systick
发布日期:2021-05-14 11:31:20 浏览次数:19 分类:精选文章

本文共 2657 字,大约阅读时间需要 8 分钟。

systick在STM32F429上的应用方法

前言

systick是Cortex-M内置的一个节拍定时器功能,主要用于实时定时和中断控制。在STM32F429开发中,该功能具有很强的灵活性和便捷性。本文将详细介绍systick的寄存器结构以及在STM32F429上的实现方法。


导出寄存器与功能

systick在HAL库中通过一个结构体表示,其主要包含以下寄存器:

TypeDef SysTick_Type = {
uint32_t CTRL; // 控制和状态寄存器
uint32_t LOAD; // 重载值寄存器
uint32_t VAL; // 当前计数值寄存器
uint32_t CALIB; // 校准寄存器
};

在STM32F429中,systick的寄存器结构与标准Cortex-M系列相似,但有以下不同时之处:

STK_CTRL寄存器

STK_CTRL是systick的核心控制寄存器,具体功能包括:

  • 位16:上一次读取该位以后,计数器重新到达过0,该位置1。
  • 位2:选择时钟源。支持以下选项:
    • 0:AHB/8时钟
    • 1:AHB时钟
  • 位1:systick中断使能。
  • 位0:计数器使能。
  • STK_LOAD寄存器

    STK_LOAD用于设置计数器的重载值,写入该寄存器后,计数器将重新加载指定的值。

    STK_VAL寄存器

    STK_VAL用于读取当前计数器值, 并清零计数器。


    systick初始化与编程

    在STM32F429开发中,正点原子使用了时钟窃取法来实现systick定时功能。主要步骤包括以下几个方面:

    时钟源设置

    systick的时钟源通常设置为AHB时钟,具体实现如下:

    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_AHB);

    计数器初始化

    在HAL库中,通过HAL_InitTick函数来初始化systick计数器,支持不同的中断优先级。

    定时功能实现

    正点原子开发的延时函数主要包括delay_usdelay_ms两种接口,实现原理如下:

  • 初始化函数:

    void delay_init(void) {
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
    fac_us = HAL_RCC_GetSysClockFreq() / 1000000;
    }
  • 微秒延时函数:

    void delay_us(uint32_t nus) {
    uint32_t told = SysTick_VAL;
    uint32_t ticks = nus * fac_us;
    while (1) {
    uint32_t tnow = SysTick_VAL;
    if (tnow != told) {
    uint32_t tcnt = 0;
    if (tnow < told) {
    tcnt += told - tnow;
    } else {
    tcnt += (reload - tnow) + told;
    }
    told = tnow;
    if (tcnt >= ticks) {
    break;
    }
    }
    }
    }
  • 毫秒延时函数:

    void delay_ms(uint16_t nms) {
    for (uint16_t i = 0; i < nms; i++) {
    delay_us(1000);
    }
    }

  • HAL库实现细节

    在HAL库中,systick的初始化和管理通过以下函数实现:

    HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) {
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
    HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0);
    return HAL_OK;
    }
    • HAL_SYSTICK_Config函数用于设置systick的计数周期、重载值和时钟源。
    • HAL_NVIC_SetPriority函数用于设置systick中断的优先级。

    delay.c的优化实现

    为了减少全局变量的耦合性,正点原子对delay.c进行了优化,实现了三种不同的写法:

    第三种写法优化

    delay_us函数进行了进一步优化:

    void delay_us(uint32_t nus) {
    uint32_t told = SysTick_VAL;
    uint32_t fac_us = HAL_RCC_GetSysClockFreq() / 1000000;
    uint32_t ticks = nus * fac_us;
    uint32_t tnow, tcnt = 0;
    uint32_t reload = SysTick_LOAD;
    while (1) {
    tnow = SysTick_VAL;
    if (tnow < told) {
    tcnt += told - tnow;
    } else {
    tcnt += (reload - tnow) + told;
    }
    told = tnow;
    if (tcnt >= ticks) {
    break;
    }
    }
    }

    该实现优化省去了外层循环结构,提高了代码的执行效率。


    总结

    systick在STM32F429开发中是一个强大的工具,支持多种定时和中断控制功能。通过HAL库和正点原子开发的延时函数,我们可以轻松实现精确的时延控制。在实际开发中,可以根据具体需求选择合适的定时接口,并通过优化代码实现更高效的时间管理。

    上一篇:STM32F429第十二篇之位带操作
    下一篇:STM32F429第九篇之stm32f4xx_hal_rcc_ex

    发表评论

    最新留言

    路过,博主的博客真漂亮。。
    [***.116.15.85]2025年04月09日 08时08分22秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章