1. 程式人生 > >STM32F207Cube庫函式USART中斷接收

STM32F207Cube庫函式USART中斷接收

USART初始化部分就不介紹了,直接看官方給的例程就能知道,現在主要將自己在學習過程中遇到的問題以及解決方法記錄一下。

首先,如果使用了串列埠接收中斷,就需要在初始化中開啟中斷以及設定中斷優先順序等常規操作。
HAL_UART_Init(&UartHandle) -> HAL_UART_MspInit(huart)->
/* Set Interrupt Group Priority */
HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);

/* Enable the TIMx global Interrupt */
HAL_NVIC_EnableIRQ(USARTx_IRQn);
然後需要呼叫串列埠接收終端初始化函式:
/**
* @brief Receives an amount of data in non blocking mode
* @param huart: UART handle
* @param pData: Pointer to data buffer
* @param Size: Amount of data to be received
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

各個引數都有英文解釋。
根據網上資料顯示,這個函式只能對串列埠中斷接收進行一次接收,而且接收的位元組大小是固定的uint16_t Size,但是在實際使用中,不可能完全滿足每次接收到的位元組數都是一樣的,而且是確定的。所以大家採用的方法都是令uint16_t Size = 1;這樣的話,每接收到一個位元組就中斷一次。

那麼中斷處理函式處理的規則應該是
1、關閉此接收中斷
2、將接收到的資料轉移至快取器
3、再次開啟中斷

根據Cube庫函式給的函式以及示例,中斷處理函式是:
void USARTx_IRQHandler(void)
{
HAL_UART_IRQHandler(&UartHandle);
}
其中void USARTx_IRQHandler(void)對應的是不同的中斷處理函式,但是終端中呼叫的都是HAL_UART_IRQHandler(&UartHandle); 因為HAL_UART_IRQHandler(&UartHandle);函式的引數不同,所以不會產生異常。

大家仔細看HAL_UART_IRQHandler(&UartHandle)這個函式,應該能發現兩個問題:
1、使用者自己的中斷處理函式在哪裡不會影響庫函式的完整性
2、中斷如何再次開啟
自己是新手,最初急於求成,沒有認真學習函式中每一步,導致自己一直在糾結第一個問題:使用者中斷處理函式放在什麼地方不影響庫函式的完整性,後來詳細閱讀了原始碼,發現庫函式提供了一個可供使用者重新定義的弱定義函式__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
可以供使用者重新定義函式內容,使用者直接將自己的中斷快取資料部分放在此函式中,使用者只需要在stm32f2xx_hal_msp_.c中重新定義此函式即可。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UART1RxBuff[UART1RxBuffCount++] = aRxBuffer;
}
同理,使用者可以在
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
中再次呼叫
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
這樣的話,就可以實現連續中斷接收USART資料。

而且當需要多個串列埠中斷接收的時候,上述中斷處理函式如何進行中斷快取資料,如何區別時哪一個串列埠傳送過來的資料。這裡可以利用中斷初始化中的UartHandle.Instance 這個成員變數,加上判斷就能實現串列埠區別,最後產生的HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)函式應該如下:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1)
{
UART1RxBuff[UART1RxBuffCount++] = aRxBuffer;
}
HAL_UART_Receive_IT(huart, (uint8_t *)&aRxBuffer, 1) ;
}

資料參考了:http://www.stm32cube.com/question/115
謝謝admin的解決,謝謝每一個願意為想我這樣新手解決問題的人,謝謝每一個願意幫助別人的人。
所以這裡做一個記錄,以幫助那些可能遇到和我一樣問題的人。