STM32-实现us延时

STM32-实现us延时


1.当在cubemx配置时基源SysTick时可以使用以下函数直接进行us延时,当用TIM时以下函数会失效,如果使用freertos使用tim也可以用以下函数

void HAL_Delay_us(uint32_t us)//延时us函数
{//需要cubemx配置时SYS时基源选择SysTick
    __IO uint32_t currentTicks = SysTick->VAL;
  /* Number of ticks per millisecond */
  const uint32_t tickPerMs = SysTick->LOAD + 1;
  /* Number of ticks to count */
  const uint32_t nbTicks = ((us - ((us > 0) ? 1 : 0)) * tickPerMs) / 1000;
  /* Number of elapsed ticks */
  uint32_t elapsedTicks = 0;
  __IO uint32_t oldTicks = currentTicks;
  do {
    currentTicks = SysTick->VAL;
    elapsedTicks += (oldTicks < currentTicks) ? tickPerMs + oldTicks - currentTicks :
                    oldTicks - currentTicks;
    oldTicks = currentTicks;
  } while (nbTicks > elapsedTicks);
}

2.使用额外的定时器单独进行us延时

缺点:需要额外的外设资源
cubemx配置
目标将TIM分频到1Mhz,即1us加一次
stm32f4:
TIM1–168M,我们就168分频,填168-1;
普通定时器,84M,填84-1

STM32-实现us延时_第1张图片
STM32-实现us延时_第2张图片

代码实现


us函数实现
#define US_TIM htim7 //定义需要的定时器 只需要修改这个就可以了,记得包含tim.h就可以了
void HAL_TimDelay_us(uint32_t us)//注意不要超过65535,一般大于10ms用HAL_Delay()函数
{
  __HAL_TIM_SetCounter(&US_TIM,0);//清零
  HAL_TIM_Base_Start(&US_TIM);//开启定时器
  while(__HAL_TIM_GetCounter(&US_TIM)<us){};
  HAL_TIM_Base_Stop(&US_TIM);//关闭定时器
}

同时我们还可以封装一个延时ms的函数,下次可以不用HAL_Delay()了
void HAL_TimDelay_ms(uint32_t ms)
{
	for(uint32_t Delay_Cnt=0;Delay_Cnt<ms;Delay_Cnt++)
	HAL_TimDelay_us(997);//考虑实际代码运行损耗,不写1000,差一点点补上
}

实测延时1ms和延时300ms时误差可以在0.2%内,就算写1000其实误差也很小,无所谓的


最后总的代码汇总如下

void HAL_TimDelay_us(uint32_t us);//延时us函数
void HAL_TimDelay_ms(uint32_t ms);//延时ms函数

#define US_TIM htim7//修改定时器,注意两点,第一需要定时器分频到1M,第二记得包含tim.h,否则找不到htimx

void HAL_TimDelay_us(uint32_t us)//延时us函数
{
  __HAL_TIM_SetCounter(&US_TIM,0);//清零
  HAL_TIM_Base_Start(&US_TIM);//开启定时器
  while(__HAL_TIM_GetCounter(&US_TIM)<us){};
  HAL_TIM_Base_Stop(&US_TIM);//关闭定时器
}
void HAL_TimDelay_ms(uint32_t ms)//延时ms函数
{
	for(uint32_t Delay_Cnt=0;Delay_Cnt<ms;Delay_Cnt++)
	HAL_TimDelay_us(997);//考虑实际代码运行损耗,不写1000,差一点点补上
}

你可能感兴趣的:(stm32基础,stm32,单片机,arm)