使用其他定時器作爲HAL的基礎時鐘

在不使用FreeRTOS的時候,SysTick是默認的HAL基礎時鐘源,但是在SYS模塊中,也可以選擇其他定時器作爲基礎時鐘源,例如可以選擇基礎定時器TIM6作爲HAL的基礎時鐘源。

圖1 選用TIM6作爲HAL的基礎時鐘

選擇TIM6作爲基礎時鐘源後,TIM6就不能在作爲其他用途,在STM32CubeMX中不能再對TIM6做任何設置。在NVIC中,TIM6的中斷被自動啓用,優先級被設置爲最高。可以修改TIM6的中斷優先級,但是不能關閉TIM6的中斷。同時,SysTick定時器的中斷也還是被自動啓用的,且不能關閉,如圖2所示。

圖2 使用TIM6作爲HAL基礎時鐘源時的NVIC設置

1. 基礎時鐘的初始化

在使用定時器TIM6作爲HAL的基礎時鐘源並用STM32CubeMX生成代碼後,\Src目錄下新增了一個文件stm32f4xx_hal_timebase_TIM.c,這個文件裏重新實現了文件stm32f4xx_hal.c中的3個弱函數,用定時器TIM6替代了SysTick的功能。文件stm32f4xx_hal_timebase_TIM.c的完整代碼如下:

	/* 文件: stm32f4xx_hal_timebase_TIM.c    -----------------------------------------*/
	#include "stm32f4xx_hal.h"
	#include "stm32f4xx_hal_tim.h"
	 
	TIM_HandleTypeDef      htim6; 
	
	HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
	{
	  RCC_ClkInitTypeDef    clkconfig;
	  uint32_t              uwTimclock = 0;
	  uint32_t              uwPrescalerValue = 0;
	  uint32_t              pFLatency;
	  
	  HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0);  //設置TIM6的中斷優先級
	  HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);    //開啓TIM6中斷 
	  __HAL_RCC_TIM6_CLK_ENABLE();   //開啓TIM6的時鐘
	  
	  HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); //獲取時鐘配置
	  uwTimclock = 2*HAL_RCC_GetPCLK1Freq();  //計算TIM6的時鐘頻率,是PCLK1的2倍
	   
	  /* 計算分頻係數,使TIM計數器時鐘信號爲1MHz*/
	  uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000) - 1);
	  
	  /* 初始化 TIM6,使其定時週期爲 1ms */
	  htim6.Instance = TIM6;
	  htim6.Init.Period = (1000000 / 1000) - 1;
	  htim6.Init.Prescaler = uwPrescalerValue;
	  htim6.Init.ClockDivision = 0;
	  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
	  if(HAL_TIM_Base_Init(&htim6) == HAL_OK)
	  {
	    return HAL_TIM_Base_Start_IT(&htim6);   //以中斷方式啓動TIM6
	  }
	  return HAL_ERROR;
	}
	
	void HAL_SuspendTick(void)
	{  /* 禁止 TIM6 的UEV中斷 */
	  __HAL_TIM_DISABLE_IT(&htim6, TIM_IT_UPDATE);  
	}
	
	void HAL_ResumeTick(void)
	{
	  /* 卡其 TIM6 的UEV中斷 */
	  __HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE);
	}

函數HAL_InitTick()是在HAL_Init()中被調用的,重新實現的這個函數對定時器TIM6進行了初始化配置,設置其中斷優先級,配置其分頻係數、計數週期等,使其定時器週期爲1ms。

重新實現的函數HAL_ResumeTick()和HAL_SuspendTick()也是對TIM6的操作。

2. 基礎時鐘的中斷處理

在使用定時器TIM6作爲HAL的基礎時鐘源並用STM32CubeMX生成代碼後,在文件stm32f4xx_it.c中沒有了SysTick的ISR函數,有TIM6的ISR函數。TIM6的ISR函數代碼如下:

	void TIM6_DAC_IRQHandler(void)
	{
	  HAL_TIM_IRQHandler(&htim6);
	}

定時器的UEV事件的回調函數是HAL_TIM_PeriodElapsedCallback,在文件main.c中就重新實現了這個函數,其功能就是執行函數HAL_IncTick(),代碼如下:

	void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
	{
	  if (htim->Instance == TIM6) {
	    HAL_IncTick();
	  }
	}

所以,在使用TIM6作爲HAL的基礎時鐘時,TIM6完全替代了SysTick的功能。

下一篇   FreeRTOS的基礎時鐘

主題   HAL和FreeRTOS的基礎時鐘

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