普通函數與回調函數的區別:就是ST將中斷封裝,給使用者的API,就是標準庫的中斷函數
對普通函數的調用:
調用程序發出對普通函數的調用後,程序執行當即轉向被調用函數執行,直到被調用函數執行完畢後,再返回調用程序繼續執行。從發出調用的程序的角度看,這個過程爲「調用-->等待被調用函數執行完畢-->繼續執行」web
對回調函數調用:
調用程序發出對回調函數的調用後,不等函數執行完畢,當即返回並繼續執行。這樣,調用程序執和被調用函數同時在執行。當被調函數執行完畢後,被調函數會反過來調用某個事先指定函數,以通知調用程序:函數調用結束。這個過程稱爲回調(Callback),這正是回調函數名稱的由來。函數
位置:stm32f4xx_hal_xxx.c 中ui
定義爲虛函數spa
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)code
串口回調:stm32f4xx_hal_uart.c
voidHAL_UART_IRQHandler(UART_HandleTypeDef*huart); voidHAL_UART_TxCpltCallback(UART_HandleTypeDef*huart); //發送回調 voidHAL_UART_TxHalfCpltCallback(UART_HandleTypeDef*huart); voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart); //接收回調 voidHAL_UART_RxHalfCpltCallback(UART_HandleTypeDef*huart); voidHAL_UART_ErrorCallback(UART_HandleTypeDef*huart); voidHAL_UART_AbortCpltCallback(UART_HandleTypeDef*huart); voidHAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef*huart); voidHAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef*huart);
舉例:
我使用的stm32的兩路串口收發,兩個串口接收中斷處理有問題,我如今的處理方式是這樣的
/* USER CODE BEGIN 4 */ voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart) { if(huart==&huart2) { uRX_buf[RX_cont++]=RX_buf; // HAL_UART_Transmit_DMA(&huart2, uTX_buf, 8); if(RX_cont>63) { RX_cont=0; } } else if(huart==&huart4) { uRX_buf[RX_cont++]=RX_buf4; if(RX_cont>63) { RX_cont=0; } // HAL_UART_Receive_IT(&huart4,&RX_buf4,1);//¡ä??¨²?¨®¨º¨¹?D?? }
定時器回調:stm32f4xx_hal_tim.c
voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim); //週期運行回調,配置定時進入中斷 voidHAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef*htim);//輸出比較回調 voidHAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef*htim); voidHAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef*htim); voidHAL_TIM_TriggerCallback(TIM_HandleTypeDef*htim); voidHAL_TIM_ErrorCallback(TIM_HandleTypeDef*htim);
GPIO:
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin);//讀引腳狀態 voidHAL_GPIO_WritePin(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin,GPIO_PinState PinState); //寫狀態 voidHAL_GPIO_TogglePin(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin); //翻轉電平 HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin); //鎖存引腳狀態 voidHAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin); //實際調用的是下邊的中斷回調函數 voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); //引腳觸發以後的回調函數,按鍵中斷函數
舉例; cube配置時開啓中斷觸發模式
/* USER CODE BEGIN 4 */ voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { /* NOTE: This function Should not be modified, when the callback is needed, the HAL_GPIO_EXTI_Callback could be implemented in the user file */ switch(GPIO_Pin) { caseGPIO_PIN_12:LED0_Toggle();break; caseGPIO_PIN_13:LED1_Toggle();break; caseGPIO_PIN_14:LED2_Toggle();break; caseGPIO_PIN_15:LED3_Toggle();break; default:break; } } /* USER CODE END 4 */