普通函數與回調函數的區別:就是ST將中斷封裝,給使用者的API,就是標准庫的中斷函數
對普通函數的調用:
調用程序發出對普通函數的調用后,程序執行立即轉向被調用函數執行,直到被調用函數執行完畢后,再返回調用程序繼續執行。從發出調用的程序的角度看,這個過程為“調用-->等待被調用函數執行完畢-->繼續執行”
對回調函數調用:
調用程序發出對回調函數的調用后,不等函數執行完畢,立即返回並繼續執行。這樣,調用程序執和被調用函數同時在執行。當被調函數執行完畢后,被調函數會反過來調用某個事先指定函數,以通知調用程序:函數調用結束。這個過程稱為回調(Callback),這正是回調函數名稱的由來。
位置:stm32f4xx_hal_xxx.c 中
定義為虛函數
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
串口回調: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 */