目前开发STM32普遍使用HAL库,但 HAL 库封装的延时函数目前仅支持 ms 级别的延时,日常很多情况下会用到 us 延时,特别是一些传感器的数据读取过程,对时序要求比较严格,us 延时必不可少,因此我们今天来介绍STM32如何使用定时器实现微秒(us)级延时。
可通过多个预分频器配置 AHB 频率、高速 APB (APB2) 和低速 APB (APB1)。AHB 域的最 大频率为 168 MHz。高速 APB2 域的最大允许频率为 84 MHz。低速 APB1 域的最大允许频 率为 42 MHz。
STM32的定时器大致分为三种:基本定时器、通用定时器和高级定时器。各个定时器和其时钟源的对应关系为:
其中,TIM1和TIM8是高级定时器;TIM2-TIM5、TIM9-TIM14是通用定时器;TIM6和TIM7为基本定时器。
实现一个us级延时
定时器频率为 =TIMxCLK/(TIM_Prescaler+1)。定时器按照此频率计数,累计 TIM_Period 个后产生一个更新或者中断。
定时器相关配置程序都由STM32CubeMX帮助我们生成了,我们主要来编写一下微秒级延时函数。
void delay_us(uint32_t us)
{
// Set timer period for desired delay in microseconds
__HAL_TIM_SET_AUTORELOAD(&htim2, us - 1);//定时器响应时间为period*定时器频率
HAL_TIM_Base_Start(&htim2);//start the timer
//通过轮询的方式等待定时器的更新事件
//当定时器溢出并计数器更新时,TIM_FLAG_UPDATE标志会被置位。
while(__HAL_TIM_GET_FLAG(&htim2,TIM_FLAG_UPDATE)==RESET);
__HAL_TIM_CLEAR_FLAG(&htim2,TIM_FLAG_UPDATE);//清楚更新标志位
HAL_TIM_Base_Stop(&htim2);//Stop the timer
}
上述程序首先通过__HAL_TIM_SET_AUTORELOAD设定延时周期,之后打开定时器,等待事件标志位更新后关闭定时器。