②註冊中斷函數 數組
1 void USART1_IRQHandler(void) 2 { 3 HAL_UART_IRQHandler(&UartHandle); //該函數會清空中斷標誌,取消中斷使能,並間接調用回調函數 4 }
③在文件「stm32l4xx_hal_uart.h」中,咱們能夠看到串口接收回調函數的定義。使用「_weak」關鍵字定義的函數,其具備以下特性: 通常狀況下和通常函數相同。可是當有一個同名函數可是不帶__weak被定義時,全部對這個函數的調用都是指向後者(不帶__weak那個)。也就是說,ST官方提供的這個回調函數須要咱們本身進行改寫。 函數
1 /** 2 * @brief Rx Transfer completed callback. 3 * @param huart UART handle. 4 * @retval None 5 */ 6 __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 7 { 8 /* Prevent unused argument(s) compilation warning */ 9 UNUSED(huart); 10 11 /* NOTE : This function should not be modified, when the callback is needed, 12 the HAL_UART_RxCpltCallback can be implemented in the user file. 13 */ 14 }
咱們在主函數所在的文件中對回調函數進行改寫: 學習
1 uint8_t myBuffer[] = "I have gotten your message: "; //用戶提示信息 2 uint8_t Enter[] = "\r\n"; //回車換行 3 uint8_t getBuffer[100]; //用戶自定義的緩衝區 4 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) 5 { 6 while(HAL_UART_Transmit(UartHandle, (uint8_t*)myBuffer, COUNTOF(myBuffer), 5000)!= HAL_OK); //發送字符串,用戶提示信息 7 while(HAL_UART_Transmit(UartHandle, (uint8_t*)getBuffer, 10, 5000)!= HAL_OK); //發送用戶自定義緩衝區中的數據 8 while(HAL_UART_Transmit(UartHandle, (uint8_t*)Enter, COUNTOF(Enter), 5000)!= HAL_OK); //發送回車換行 9 }
以上代碼的做用是把用戶發送給單片機數據再返回給用戶。運行效果以下圖:ui
1 void USART1_IRQHandler(void) 2 { 3 HAL_UART_IRQHandler(&UartHandle); //該函數會清空中斷標誌,取消中斷使能,並間接調用回調函數 4 HAL_UART_Receive_IT(&UartHandle, (uint8_t *)&value,1); //添加的一行代碼 5 }
這樣就能夠實現屢次數據返回了,新的執行結果以下圖:spa
可見,函數HAL_UART_Receive_IT還有中斷使能的做用。這一功能的實現咱們能夠在HAL_UART_Receive_IT函數中找到。code
②註冊中斷函數 blog
1 uint8_t myBuffer[] = "I have gotten your message: "; 2 uint8_t getBuffer[10]; 3 uint8_t Enter[] = "\r\n"; 4 void USARTx_IRQHandler(void) 5 { 6 HAL_UART_IRQHandler(&UartHandle); //該函數會清空中斷標誌,取消中斷使能,並間接調用回調函數 7 8 getBuffer[countOfGetBuffer++] = value; 9 if(countOfGetBuffer == 10) 10 { 11 while(HAL_UART_Transmit(&UartHandle, (uint8_t*)myBuffer, COUNTOF(myBuffer), 5000)!= HAL_OK); 12 while(HAL_UART_Transmit(&UartHandle, (uint8_t*)getBuffer, countOfGetBuffer, 5000)!= HAL_OK); 13 while(HAL_UART_Transmit(&UartHandle, (uint8_t*)Enter, COUNTOF(Enter), 5000)!= HAL_OK); 14 countOfGetBuffer = 0; 15 } 16 HAL_UART_Receive_IT(&UartHandle, (uint8_t *)&value,1); //因爲接收中斷是每接收一個字符便進入一次,因此這一行代碼必須添加,不然只能接收一個字符,而沒法接收整個字符串 17 }
以上代碼的做用是接收每一個來自用戶的字符,並依次存入用戶自定義的緩衝區中,數量達到10個後,將緩衝區中的全部數據返回給用戶,同時清空計數,準備接下來10個字符的接收。運行效果以下圖:開發
看完本文,你們可能對回調函數和中斷處理函數的關係產生了疑問。實際上是這樣的,單片機每完成接收一個字符,就會進入一次中斷處理函數,而在中斷處理函數中,咱們又調用了函數「void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)」,該函數會間接調用回調函數,也就是說回調函數是由中斷處理函數間接調用的。而函數「HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)」決定了中斷處理函數調用回調函數的頻率,若Size爲1,則每進入一次中斷處理函數都會調用一次回調函數;若Size爲10,則每第十次進入中斷處理函數時,纔會調用回調函數。方法2使用了標準庫中斷處理數據的思想。字符串