通用定时器实现STM32单片机微秒级延时函数

本文介绍如何使用STM32CubeMX配置TIM3实现微秒级精确延时,避免HAL库毫秒级延时带来的问题,适用于多种STM32芯片。通过实例讲解了时钟配置、定时器设置和相关代码编写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

在实际应用中,经常用到微秒级延时函数,而HAL库的延时函数是毫秒级的,虽然可以自行修改,但该函数使用的地方较多,修改不慎可能会引起其他问题,所以本文使用一个定时器,实现微秒级精确延时,不影响其他使用。
该方法使用STMCubeMX配置,基本适用于所有STM32系列芯片。

二、STMCubeMX配置

1. 时钟配置

我们使用TIM3实现延时函数,首先看手册中,TIM3是挂在APB1上的
在这里插入图片描述
在STM32CubeMX中,配置完时钟频率,找到APB1的定时器的频率。本例中为48MHz。
在这里插入图片描述

2.定时器配置

定时器配置,将定时器配置为(48-1)分频,即1MHz,则每记1个数,时间为1us;
此处不需要打开中断。
在这里插入图片描述

3. 代码

初始化TIM3

MX_TIM3_Init();

编写delay_us函数

/*******************************************************************************
  * 函数名:delay_us
  * 功  能:us延时
  * 参  数:x延时us
  * 返回值:无
  * 说  明:使用TIM3
*******************************************************************************/
void delay_us(uint16_t x)
{
	HAL_TIM_Base_Start(&htim3);
	__HAL_TIM_SetCounter(&htim3,0);// 先把计数清零
	while( x > __HAL_TIM_GetCounter(&htim3) ) 
	{
	}
	HAL_TIM_Base_Stop(&htim3);
}

当调用delay_us函数时,即可实现延时x微秒。该函数只在调用延时时打开TIM3,延时完成,关闭TIM3。

### 实现STM32微秒级延时函数的方法 对于STM32系列单片机而言,实现精确的微秒级延迟通常依赖于内部定时器或者SysTick定时器。由于不同型号的STM32具有不同的核心频率,在编写延时函数时需考虑当前系统的时钟配置。 #### 使用TIMx定时器实现微秒级延时 一种常见做法是采用硬件定时器来完成高精度延时功能。下面是一个基于通用定时器(如TIM2)的例子: ```c #include "stm32f4xx_hal.h" void TIM_Delay_us(uint32_t us) { __IO uint32_t temp; // 配置定时器参数 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitTypeDef TIM_InitStruct; TIM_InitStruct.TIM_Period = (SystemCoreClock / 8000000) * us - 1; // 设置自动重装载值 TIM_InitStruct.TIM_Prescaler = 79; // 分频系数设置为80分之一 TIM_InitStruct.TIM_ClockDivision = 0; TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_InitStruct); TIM_SetCounter(TIM2, 0); // 计数器清零 TIM_Cmd(TIM2, ENABLE); // 启动计数 while ((temp = TIM_GetFlagStatus(TIM2, TIM_FLAG_Update)) == RESET);// 等待更新标志位被置位 TIM_ClearFlag(TIM2, TIM_FLAG_Update); // 清除更新事件标志位 } ``` 此代码片段展示了如何初始化并使用一个通用定时器来进行指定时间长度内的等待操作[^1]。需要注意的是这段程序假设系统已经完成了必要的外设初始化工作,并且`SystemCoreClock`定义了CPU的工作频率。 另一种更为简便的方式则是利用HAL库中的APIs: ```c #include "stm32f4xx_hal.h" ... __HAL_TIM_SET_COUNTER(&htim2, 0); // 将计数值设定为0 while (__HAL_TIM_GET_COUNTER(&htim2) < us); // 循环直到达到所需的us数量 ``` 这种方法同样适用于其他支持HAL库的MCU平台,只需替换对应的句柄即可[^2]。 此外,如果项目中已集成了SEGGER RTT组件,则可以直接调用其提供的高效数据传输机制,这不仅能够减少调试串口打印所带来的额外开销,而且还能确保极低的数据发送延迟[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值