[应用相关] stm32定时器实现非阻塞延时

[复制链接]
 楼主| xiaoqizi 发表于 2025-7-11 22:10 | 显示全部楼层 |阅读模式
我们在写stm32程序时总会用到delay_ms或者hal_delay函数,这种延时函数的实现是依靠系统滴答定时器实现的,大量使用会导致系统阻塞,这时候我们可以使用定时器代替delay以实现非延时阻塞,直接封装成函数进行使用,现在我提供标准库和hal库的代码。
首先是标准库的:
.C文件
#include "stm32f10x.h"
volatile uint32_t timerOverflowCount = 0;

void Timer2_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
    TIM_TimeBaseStructure.TIM_Period = 1000 - 1;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&NVIC_InitStructure);
    TIM_Cmd(TIM2, ENABLE);
}

void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
    {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
        timerOverflowCount++;
    }
}

void delay_ms(uint32_t milliseconds)
{
    uint32_t startCount = timerOverflowCount;
    while ((timerOverflowCount - startCount) < milliseconds)
    {
                               
    }
}



.h文件
#ifndef __DELAY_H
#define __DELAY_H
void Timer2_Init(void);
void delay_ms(uint32_t milliseconds);
#endif


在主函数中我们直接调用即可
int main(void)
{
        Led_Init();
        OLED_Init();
        Timer2_Init();
        while(1)
        {
                Led_On();
                delay_ms(300);
                Led_Off();
                delay_ms(300);
        }
}



接下来是hal库版本的

24954686f50d3794df.png

97320686f50cd970c6.png

然后是代码
#include "stm32f1xx_hal.h"

TIM_HandleTypeDef htim2;
volatile uint32_t timerOverflowCount = 0;


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM2)
    {
        timerOverflowCount++;
    }
}

void delay_ms(uint32_t milliseconds)
{
    uint32_t startCount = timerOverflowCount;
    while ((timerOverflowCount - startCount) < milliseconds)
    {
        // 等待
    }
}



在主函数直接调用
int main(void)
{
        Led_Init();
        OLED_Init();
        while(1)
        {
                Led_On();
                delay_ms(300);
                Led_Off();
                delay_ms(300);
        }
}


————————————————

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

原文链接:https://blog.csdn.net/2301_80143498/article/details/149121524

小小蚂蚁举千斤 发表于 2025-7-28 23:11 | 显示全部楼层
stm32定时器实现非阻塞延时
您需要登录后才可以回帖 登录 | 注册

本版积分规则

126

主题

4320

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部