在STM32的HAL库中利用系统节拍定时器SystemTIck实现了毫秒级ms延时,但是在实际的嵌入式编程中,常常需要用到毫秒级us延时,比如DS18B20和DTH11的操作时序。针对这个问题,同时考虑到程序的可移植性,我们可以单独使用一个硬件定时器来实现毫秒级us延时。
具体方法如下:
1、选择MCU中的一个硬件定时器,一般采用基本定时器即可。
2、根据MCU的定时器时钟频率确定分频系数,确保进入核心定时器的时钟频率为1MHz。即计一次数的时间为1us。例如STM32F411的定时器时钟频率为100MHz,就可以设置分频系数PSC为99;而STM32F193的定时器时钟频率为72MHz,就可以设置分频系数PSC为71。

图1 STM32CubeMX中的定时器设置
3、在main.c文件的初始化代码部分,启动定时器运行,工作方式为轮询式,HAL_TIM_Base_Start(&htimx);这里的x表示定时器的序号。

4、编写延时函数,函数如下:
/**
* @brief Delay for microseconds.
* @param Delay: specifies the delay time length, in microseconds.
* @retval None.
* @note Use a hardware timer as the source of time base.
**/
static void DelayUs (uint16_t delay)
{
__HAL_TIM_SET_COUNTER(&htimx, 0);
while (__HAL_TIM_GET_COUNTER(&htimx) < delay);
}
5、工作原理:用于毫秒级us延时的定时器在初始化代码部分启动,一旦启动就不再停止。用户需要延时时,直接调用DelayUs函数,入口参数为us。在函数内部,先把定时器的计数值清为0,然后不断读取定时器的计数值和入口参数delay比较。由于在定时器配置时,设置了分频后送入核心计数器的频率为1MHz,计数时间为1us,因此定时器的计数值就对应了us值。如果小于延时值delay,则继续循环;如果等于延时值delay,表明延时时间到,则退出循环。
6、注意事项:这里使用了一个硬件定时器,并采用阻塞式的延时,延时过程中,MCU不能做其他事情。