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 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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