對比標准庫的流程使用HAL庫編寫定時器更新中斷
標准庫中使用定時器更新中斷的方式:
1.開時鍾,設置TIM的時鍾
2.初始化定時器石基的結構體
3.調用Init初始化函數
4.處理定時器中斷
HAL中使用定時器更新中斷的方式:
1.開時鍾
2.初始化定時器石基的結構體
3.處理定時器中斷
3.1在CubeMx中設置NVIC的搶占優先級和子優先級
3.2 編寫TIM3_IRQHandler //重點
先來看標准庫中怎么處理這個中斷,首先從啟動文件中找到定時器中斷的函數名字,然后再函數里判斷是定時器的哪種中斷(更新?輸入捕獲?輸出比較?),然后清標志位,然后才寫我們在中斷干什么的代碼。HAL中處理的方式有些變化。
stm32fxx_it.c文件中找到了和標准庫中一樣名字的中斷函數。
1 void TIM3_IRQHandler(void) 2 { 3 /* USER CODE BEGIN TIM3_IRQn 0 */ 4 5 /* USER CODE END TIM3_IRQn 0 */ 6 HAL_TIM_IRQHandler(&htim3); 7 /* USER CODE BEGIN TIM3_IRQn 1 */ 8 9 /* USER CODE END TIM3_IRQn 1 */ 10 }
這里面什么都沒做只是調用了一個函數 HAL_TIM_IRQHandler(&htim3);
這個函數中完成了判斷中斷類型,清中斷標志位的操作。我們只要寫真正的處理代碼即可。這也就是回調函數。
HAL_TIM_IRQHandler(&htim3);函數中調判斷了各種定時器的中斷類型,也調用了對應的中斷處理函數(回調函數),包括:
1 /* Callback in non blocking modes (Interrupt and DMA) *************************/ 2 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); 3 void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim); 4 void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim); 5 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); 6 void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim); 7 void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim); 8 void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim); 9 void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim); 10 void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim); 11 void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim);
總結一下思路就是:
啟動文件中有定時器中斷的函數名字:TIM3_IRQHandler 這個名字是不能改的
stm32fxx_it.c中調用: void TIM3_IRQHandler(void),它又調用了HAL_TIM_IRQHandler(&htim3)(這個函數在stm32f1xx_hal_tim.c中由庫實現)
在stm32f1xx_hal_tim.c中 HAL_TIM_IRQHandler(&htim3)這個函數調用了各種定時器的具體中斷類型的函數(回調函數);聲明在stm32f1xx_hal_tim.h中。
具體的回調函數在外設的.c文件中以__weak關鍵字定義但沒實現,我們需要去處理這些回調函數。該回調函數和標准庫中的中斷函數一樣,可在任意文件中實現
在HAL中,無論是串口的中斷,DMA的中斷,定時器的中斷,都是以這種方法組織的。
下面是定時器更新中的回調函數實現:
1 /* USER CODE BEGIN 1 */ 2 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 3 { 4 if(htim==&htim3) 5 { 6 HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5); 7 HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5); 8 } 9 }
別忘了開啟定時器中斷:&htim3就是一個句柄
HAL_TIM_Base_Start_IT(&htim3);