打印
[应用相关]

STM32的延时函数

[复制链接]
25|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
观海|  楼主 | 2025-3-13 21:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在 STM32 微控制器中,实现延时函数通常有两种常见方法:

使用循环空转(阻塞式延时):通过循环计数实现延时,简单但会占用 CPU 资源。
使用定时器(非阻塞式延时):利用硬件定时器实现精确延时,效率更高。
以下分别介绍这两种方法的实现。

方法 1:使用循环空转实现延时(阻塞式)
这种方法通过循环计数实现延时,适用于简单的应用场景。

#include "stm32f10x.h"  // 根据你的 STM32 型号包含对应的头文件

// 简单延时函数(单位:毫秒)
void Delay_ms(uint32_t ms)
{
    for (uint32_t i = 0; i < ms; i++)
    {
        for (volatile uint32_t j = 0; j < 7200; j++);  // 调整循环次数以适配你的时钟频率
    }
}

// 简单延时函数(单位:微秒)
void Delay_us(uint32_t us)
{
    for (uint32_t i = 0; i < us; i++)
    {
        for (volatile uint32_t j = 0; j < 7; j++);  // 调整循环次数以适配你的时钟频率
    }
}



说明:
Delay_ms 和 Delay_us 是通过空循环实现的延时函数。
循环次数需要根据你的系统时钟频率进行调整。例如,如果系统时钟是 72MHz,可以通过实验调整循环次数以达到准确的延时。
这种方法的缺点是会占用 CPU 资源,无法在延时期间执行其他任务。
方法 2:使用定时器实现延时(非阻塞式)
利用 STM32 的硬件定时器可以实现更精确的延时,同时释放 CPU 资源。

步骤:
配置一个定时器(如 TIM2)。
在延时函数中启动定时器并等待定时器标志位。
以下是实现代码:

#include "stm32f10x.h"  // 根据你的 STM32 型号包含对应的头文件

// 初始化定时器(以 TIM2 为例)
void Timer_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  // 使能 TIM2 时钟

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_TimeBaseStructure.TIM_Period = 7200 - 1;          // 自动重装载值
    TIM_TimeBaseStructure.TIM_Prescaler = 1000 - 1;       // 预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_Cmd(TIM2, ENABLE);  // 使能 TIM2
}

// 毫秒级延时函数
void Delay_ms(uint32_t ms)
{
    for (uint32_t i = 0; i < ms; i++)
    {
        TIM_SetCounter(TIM2, 0);  // 清零计数器
        while (TIM_GetCounter(TIM2) < 72);  // 等待计数器达到 72(1ms)
    }
}

// 微秒级延时函数
void Delay_us(uint32_t us)
{
    TIM_SetCounter(TIM2, 0);  // 清零计数器
    while (TIM_GetCounter(TIM2) < us);  // 等待计数器达到指定值
}



说明:
Timer_Init 初始化 TIM2 定时器,配置为 1ms 的定时周期(假设系统时钟为 72MHz)。
Delay_ms 和 Delay_us 通过读取定时器的计数器值实现精确延时。
这种方法的优点是可以释放 CPU 资源,适合需要同时执行其他任务的场景。
方法 3:使用 SysTick 定时器实现延时
SysTick 是 Cortex-M 内核提供的一个系统定时器,非常适合用于实现延时函数。

实现代码:
#include "stm32f10x.h"  // 根据你的 STM32 型号包含对应的头文件

// 初始化 SysTick 定时器
void SysTick_Init(void)
{
    SysTick_Config(SystemCoreClock / 1000);  // 配置 SysTick 为 1ms 中断
}

// 毫秒级延时函数
void Delay_ms(uint32_t ms)
{
    uint32_t start = SysTick->VAL;  // 获取当前 SysTick 计数器值
    while (ms--)
    {
        while ((start - SysTick->VAL) < (SystemCoreClock / 1000));  // 等待 1ms
        start = SysTick->VAL;  // 更新起始值
    }
}

// 微秒级延时函数
void Delay_us(uint32_t us)
{
    uint32_t start = SysTick->VAL;  // 获取当前 SysTick 计数器值
    while (us--)
    {
        while ((start - SysTick->VAL) < (SystemCoreClock / 1000000));  // 等待 1us
        start = SysTick->VAL;  // 更新起始值
    }
}



说明:
SysTick_Config(SystemCoreClock / 1000) 将 SysTick 定时器配置为 1ms 中断。
Delay_ms 和 Delay_us 通过读取 SysTick 计数器的值实现精确延时。
SysTick 是 Cortex-M 内核的功能,因此代码具有较好的可移植性。
总结
如果对延时精度要求不高,可以使用 循环空转 的方法。
如果需要精确延时且不占用 CPU 资源,建议使用 定时器 或 SysTick 实现。
SysTick 是最常用的延时实现方式,适合大多数 STM32 应用场景。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_73063976/article/details/146108102

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

114

主题

4208

帖子

1

粉丝