STM32 HAL/LL混合库查询方式实现精确微秒延时

 HAL与LL库查询方式实现精确微秒或毫秒延时,可以用于IO口模拟I2C、SPI通信等。通过HAL实现初始化5us初始化,后面在延时函数中可以再设置延时值。

1. 定时器实现1us延时

在这里插入图片描述
中断Enable不打钩
在这里插入图片描述
在这里插入图片描述
复制必要库文件,.c/.h单独一个文件,设置好。
在这里插入图片描述
生成代码如下:

/* TIM3 init function */
void MX_TIM3_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 72-1;
  htim3.Init.CounterMode = TIM_COUNTERMODE_DOWN;
  htim3.Init.Period = 5-1;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

2. 手动复制stm32f1xx_ll_tim.h文件到工程下

3. 实际的延时函数

//delay_us.c
#include "stm32f1xx_ll_tim.h"
void delay_us(uint16_t us)
{
  //设置更新请求源,只有计数器溢出/下溢才产生更新中断
  LL_TIM_SetUpdateSource(TIM3, LL_TIM_UPDATESOURCE_COUNTER);    //URS=1,默认0
  
  //设置定时时间
  LL_TIM_SetAutoReload(TIM3, us);
    
  /* Force update generation */   //产生一个更新事件,需要下面清FLAG(如果设URS=1,则不需要)
  LL_TIM_GenerateEvent_UPDATE(TIM3);

  /* Clear the update interrupt flag*/  //清除更新,
//  LL_TIM_ClearFlag_UPDATE(TIM3);
  
  /* Enable counter */
  LL_TIM_EnableCounter(TIM3); 

  while(LL_TIM_IsActiveFlag_UPDATE(TIM3) == 0);
  LL_TIM_ClearFlag_UPDATE(TIM3); 
  
  LL_TIM_DisableCounter(TIM3);    
}

//计时开始,us:定时时间,单位微妙
void delay_us_Start(uint16_t us)
{
  //设置定时时间
  LL_TIM_SetAutoReload(TIM3, us);
    
  /* Force update generation */   //产生一个更新事件
  LL_TIM_GenerateEvent_UPDATE(TIM3);

  /* Clear the update interrupt flag*/  //清除更新
  LL_TIM_ClearFlag_UPDATE(TIM3);
  
  /* Enable counter */
  LL_TIM_EnableCounter(TIM3);   
}

//查询延时时间是否已到
//return 0:时间未到,1:时间已到
uint8_t delay_us_IsEnd(void)
{
  if(LL_TIM_IsActiveFlag_UPDATE(TIM3) == 0)
  {
    return 0;    
  }
  else
  {
    LL_TIM_ClearFlag_UPDATE(TIM3);    
    LL_TIM_DisableCounter(TIM3);
    return 1;
  }  
}

//结束定时器计数
void delay_us_Stop(void)
{
  LL_TIM_DisableCounter(TIM3);   

  /* Clear the update interrupt flag*/  //清除更新
  LL_TIM_ClearFlag_UPDATE(TIM3);
}
发布了24 篇原创文章 · 获赞 0 · 访问量 466

猜你喜欢

转载自blog.csdn.net/lljss1980/article/details/105003608