HAL库和LL库都没有自带的微秒级延时,但是修改SysTick的配置会影响其他部分。经过几天的实验,浏览了不少资料,分享以下三种延时方法。
一、利用定时器实现微秒延时
1. MX配置
2. <tim.c>
/* USER CODE BEGIN 1 */
void delayXus(uint32_t us)
{
(&htim3)->Instance->CNT = (0x0000efff -us*8);// __HAL_TIM_SET_COUNTER(&htim3,differ);
// HAL_TIM_Base_Start(&htim3);
SET_BIT(TIM3->CR1, TIM_CR1_CEN);
//__HAL_TIM_GET_COUNTER(&htim3);
while(((&htim3)->Instance->CNT) < 0x0000effe) // READ_REG(TIM3->CNT)
{
}
// HAL_TIM_Base_Stop(&htim3);
CLEAR_BIT(TIM3->CR1, TIM_CR1_CEN);
}
/* USER CODE END 1 */
二、利用已有的SysTick配置,读取计数判断延迟,精确且不浪费资源
void delay_us(uint32_t udelay)
{
uint32_t startval,tickn,delays,wait;
startval = SysTick->VAL;
tickn = HAL_GetTick();
//sysc = 72000; //SystemCoreClock / (1000U / uwTickFreq);
delays =udelay * 72; //sysc / 1000 * udelay;
if(delays > startval)
{
while(HAL_GetTick() == tickn)
{
}
wait = 72000 + startval - delays;
while(wait < SysTick->VAL)
{
}
}
else
{
wait = startval - delays;
while(wait < SysTick->VAL && HAL_GetTick() == tickn)
{
}
}
}
三、利用指令耗时计算延迟
void RCCdelay_us(uint32_t udelay)
{
__IO uint32_t Delay = udelay * 72 / 8;//(SystemCoreClock / 8U / 1000000U)
//见stm32f1xx_hal_rcc.c -- static void RCC_Delay(uint32_t mdelay)
do
{
__NOP();
}
while (Delay --);
}