STM32F030R8Tx HAL库实现TIM延时及时间测量

  • 工程准备,在以下链接的例程上实现TIM延时及时间测量,参考链接如下:

https://blog.csdn.net/mygod2008ok/article/details/106749721

  • 在工程中增加stm32f0xx_hal_tim.c和stm32f0xx_hal_tim_ex.c

  • 在stm32f0xx_hal_conf.h文件中打开HAL_TIM_MODULE_ENABLED宏

  • 新建BSP文件夹并新建BSP_delay.c和BSP_delay.h文件并加入到工程中

  • 添加路径

BSP_delay延时初时化函数实现,这里采用TIM3定时器


#define SYSTEM_CLOCK    (SystemCoreClock / 1000000)


static TIM_HandleTypeDef    TimHandle;

void delay_init(void)
{
	
  /* Set TIMx instance */
  TimHandle.Instance = TIM3;
  __HAL_RCC_TIM3_CLK_ENABLE();

  TimHandle.Init.Period            = 100-1;				//比较值
  TimHandle.Init.Prescaler         = (SYSTEM_CLOCK-1);///uwPrescalerValue;//预分频值
  TimHandle.Init.ClockDivision     = 0;
  TimHandle.Init.CounterMode       = TIM_COUNTERMODE_DOWN;
  TimHandle.Init.RepetitionCounter = 0;
  TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  HAL_StatusTypeDef err_code = HAL_TIM_Base_Init(&TimHandle);
  APP_ERROR_CHECK(err_code);

	
}

上面初时化每个时钟时间为1us,因为时钟频率为48MHz,经过48分频(48000000/1000000-1),则Prescaler值为47,经过分频后的TIM3的时钟频率为1MHz,那么1个时钟时间为1us

  • 硬延时微秒级函数


void delay_us(volatile uint32_t us_cnt)
{
    TIM3->CNT = us_cnt-1;
    TIM3->CR1 |= TIM_CR1_CEN;            // 启动计数
    while((TIM3->SR & TIM_FLAG_UPDATE)!=SET);
    TIM3->SR = (uint16_t)~TIM_FLAG_UPDATE;
    TIM3->CR1 &= ~TIM_CR1_CEN;         // 停止计数
}
  •  硬延时毫秒级函数


void delay_ms(volatile uint32_t nms)
{     
	volatile uint32_t ms = nms;
        while(nms--)
	 {
		 delay_us(1000);
	 }
}

硬延时采用TIM3定时器,给定的计数据后,启动定时器,等待计数据向下计数到0产生中断来达到延时的目的

  • 定时器TIM14实现测量时间,初时化函数如下


volatile uint32_t tim14_tick_count;
static TIM_HandleTypeDef    Tim14Handle;


void BSP_tim14_init(void)
{

  /* Set TIMx instance */
  Tim14Handle.Instance = TIM14;
  __HAL_RCC_TIM14_CLK_ENABLE();
  /* Initialize TIMx peripheral as follows:
       + Period = 10000 - 1
       + Prescaler = (SystemCoreClock/10000) - 1
       + ClockDivision = 0
       + Counter direction = Up
  */
	//f = (system clock/prescaler)/Period  :(32=48M/15000)/100
  Tim14Handle.Init.Period            = 65535;				//比较值
  Tim14Handle.Init.Prescaler         = (SYSTEM_CLOCK-1);///uwPrescalerValue;//预分频值
  Tim14Handle.Init.ClockDivision     = 0;
  Tim14Handle.Init.CounterMode       = TIM_COUNTERMODE_UP;
  Tim14Handle.Init.RepetitionCounter = 0;
  Tim14Handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
	HAL_StatusTypeDef err_code = HAL_TIM_Base_Init(&Tim14Handle);
	APP_ERROR_CHECK(err_code);
  __HAL_TIM_SET_COUNTER(&Tim14Handle,0);
	
	HAL_NVIC_SetPriority(TIM14_IRQn,3,0);
	HAL_NVIC_EnableIRQ(TIM14_IRQn);
	HAL_TIM_Base_Start_IT(&Tim14Handle);
	tim14_tick_count = 0;
}
  • 得到微秒级计数值并反初时化TIM14 


/**
* @brief tim14返初时化
*/
uint32_t BSP_tim14_deinit(void)
{
	uint32_t tim14_cnt;
	tim14_cnt = tim14_tick_count * 65536;
	tim14_cnt += __HAL_TIM_GET_COUNTER(&Tim14Handle);
	HAL_TIM_Base_Stop_IT(&Tim14Handle);
	HAL_NVIC_DisableIRQ(TIM14_IRQn);
	HAL_TIM_Base_DeInit(&Tim14Handle);
	__HAL_RCC_TIM14_CLK_DISABLE();
	
	return tim14_cnt;
}
  • TIM14中断


void TIM14_IRQHandler(void)   //TIM3中断
{
	if((TIM14->SR & TIM_FLAG_UPDATE)!=RESET)
	{
		TIM14->SR = (uint16_t)~TIM_FLAG_UPDATE;
		tim14_tick_count++;
	}

}

测量时间采用TIM14定时器,定时期周期设定为65536微秒产生一次中断,每产生一次中断令 tim14_tick_count计数值增1,

每次启动测量前会将tim14_tick_count清0,测量完后停此定时器并计算时间,公式如下:

测量时间 = tim14_tick_count * 65536 + __HAL_TIM_GET_COUNTER(&Tim14Handle)

在main.c中包含BSP_delay.h,添加测试代码

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	RTT_INIT();
  HAL_Init();
  SystemClock_Config();
 
  BSP_wdt_init(5000);
   
	delay_init();
	BSP_tim14_init();
	delay_ms(1500);
	uint32_t time_count = BSP_tim14_deinit();
	NRF_LOG_INFO("time_count = %d us",time_count);
	delay_ms(1000);
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		BSP_wdt_feed();
		tick_25hz_handler();
	
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
  • 在tick_25hz_handler函数中添加测量代码


/**
* @brief 25Hz handler
*
*/
void tick_25hz_handler(void)
{
	if((s_wakeup_flag & TICK_FOR_25HZ) == 0)
	  return;
	s_wakeup_flag &= CLEAR_TICK_FOR_25HZ;
//####################################################################################
	//---------TODO this to add 25hz event handler-----------
	static uint8_t test_flag;
	if(test_flag == 0) // 丢弃上电的第一次tick标志测量
	{
		test_flag = 1;
	}
        else if(test_flag == 1) 
	{
		test_flag = 2;
		BSP_tim14_init();
	}
	else 
	{
		test_flag = 1;
		uint32_t tick = BSP_tim14_deinit();
		NRF_LOG_INFO("tick_25hz = %d us",tick);
	
	}
  
}
  • 运行结果如下:

例程下载链接:

https://download.csdn.net/download/mygod2008ok/12522665 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章