STM32 延时函数优化:使用定时器实现精确延时

在使用 STM32 开发时,经常需要使用延时函数来控制程序执行流程。但传统的循环延时函数会受到系统时钟频率的影响,导致延时精度不高。为了实现精确的延时控制,推荐使用定时器来实现延时功能。

使用定时器实现延时

以下是一个使用 SysTick 定时器来实现毫秒级延时的示例程序:

#include "stm32f4xx.h"

// 定义LED灯连接的引脚
#define LED_PIN GPIO_Pin_13
#define LED_PORT GPIOA

void delay_ms(uint32_t ms) {
    // 使用SysTick定时器实现毫秒级延时
    SysTick_Config(SystemCoreClock / 1000); // 配置SysTick为1ms中断一次

    uint32_t start = SysTick->VAL;
    uint32_t totalDelay = ms;

    while (totalDelay > 0) {
        if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0) {
            totalDelay--;
        }
    }

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭SysTick定时器
}

int main(void) {
    // 启用GPIOA的时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    // 配置引脚为推挽输出模式
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin = LED_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(LED_PORT, &GPIO_InitStruct);

    while (1) {
        // 点亮LED灯
        GPIO_SetBits(LED_PORT, LED_PIN);

        // 延时1秒
        delay_ms(1000);

        // 关闭LED灯
        GPIO_ResetBits(LED_PORT, LED_PIN);

        // 延时1秒
        delay_ms(1000);
    }
}

在修改后的程序中,我们定义了一个delay_ms函数,它使用 SysTick 定时器来实现毫秒级的延时。在 main 函数中,我们调用 delay_ms 函数来进行精确的延时。

**注意:**在使用定时器延时时,需要根据具体的系统时钟频率进行配置。在示例程序中,我们使用 SystemCoreClock 来获取系统时钟频率,并配置 SysTick 定时器为 1ms 中断一次。

代码解释

  1. delay_ms 函数使用 SysTick_Config 函数配置 SysTick 定时器,使其每 1ms 中断一次。
  2. 函数使用 SysTick->VAL 获取当前 SysTick 定时器的计数器值,并记录开始时间。
  3. 通过循环等待,直到经过 ms 毫秒,并使用 SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk 判断是否发生了中断。
  4. 中断发生后,将 totalDelay 变量减 1,直到 totalDelay 为 0,表示延时结束。
  5. 延时结束后,关闭 SysTick 定时器。

总结

使用定时器可以实现精确的延时控制,避免了循环延时函数在不同系统时钟频率下延时不准确的问题。本示例程序展示了如何使用 SysTick 定时器来实现毫秒级延时,您可以根据实际情况进行适当的调整。

STM32 延时函数优化:使用定时器实现精确延时

原文地址: https://www.cveoy.top/t/topic/b8Ai 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录