|
串口通信的基本概念可參考下面的一篇文章,本章將介紹如何使用STM32CubeMX工具快速編寫串口通信的程序。
前期準備
STM32硬件電路板及仿真器(以STM32F407單片機為例)
Keil v5以上版本(MDK-ARM)
USB轉串口工具及驅動
串口調試助手
STM32CubeMX配置首先,時鐘等的配置參考之前文章的介紹(STM32CubeMX之GPIO的使用)。串口部分配置如下:
ndkawsrf4nk64048944725.png (63.31 KB, 下載次數(shù): 0)
下載附件
保存到相冊
ndkawsrf4nk64048944725.png
2024-10-5 23:00 上傳
選擇Mode為常用的異步串口Asynchronous,不使能RS232硬件流控制。波特率設置為115200,數(shù)據(jù)長度8位,無校驗位,1位停止位。
打開中斷和添加發(fā)送和接收的DMA,DMA參數(shù)設置為默認即可,如下圖。
feuc0ajhkhb64048944825.png (24.04 KB, 下載次數(shù): 0)
下載附件
保存到相冊
feuc0ajhkhb64048944825.png
2024-10-5 23:00 上傳
djevz5gq3rk64048944925.png (31.18 KB, 下載次數(shù): 0)
下載附件
保存到相冊
djevz5gq3rk64048944925.png
2024-10-5 23:00 上傳
編寫程序設置完成后生成代碼。初始化部分已經自動生成,用戶只要添加發(fā)送和接收的代碼就行。串口發(fā)送和接收的函數(shù)包括三種方式:查詢、中斷和DMA方式,函數(shù)如下:HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);查詢方式相對比較占用CPU資源,因此中斷和DMA方式使用的比較多。這里不再介紹查詢方式的收發(fā)程序,只介紹中斷和DMA方式。串口發(fā)送比較簡單,直接調用相關函數(shù)即可,如下:
HAL_UART_Transmit_IT(&huart1,"Hello World\r
",13);HAL_UART_Transmit_DMA(&huart1,"DMA Test\r
",10);HAL庫的串口接收只支持接收定長數(shù)據(jù),當數(shù)據(jù)長度不確定時,需要自己處理。中斷方式接收:
首先初始化完成后打開串口接收中斷,接收長度為1字節(jié),即當接收到一個字節(jié)數(shù)據(jù)后產生串口接收中斷。HAL_UART_Receive_IT(&huart1,&RevByte,1);//打開串口接收中斷編寫中斷回調函數(shù),由于HAL庫已經在底層做了處理,串口接收的1字節(jié)數(shù)據(jù)已經存儲在RevByte中,因此在中斷中直接讀取RevByte的值即可。需要注意的是讀取完成后要重新打開中斷接收。//串口接收中斷回調函數(shù)void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if(huart->Instance==USART1) { RevBuf[Revcnt]=RevByte; Revcnt++; if(Revcnt==BUF_LEN) { Revcnt=0; } HAL_UART_Receive_IT(&huart1, &RevByte, 1); //串口1中斷接收數(shù)據(jù) }}DMA方式接收:DMA+空閑中斷的方式也可以實現(xiàn)接收不定長的數(shù)據(jù)。首先初始化完成后打開串口空閑中斷和DMA接收。
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//打開串口空閑中斷 HAL_UART_Receive_DMA(&huart1, RevBuf, BUF_LEN); //串口1DMA接收數(shù)據(jù)編寫空閑中斷函數(shù),在主程序中判斷標志位,進行相關處理
void UART_IDLECallBack(UART_HandleTypeDef *huart){ uint32_t temp; /*uart1 idle processing function*/ if(huart == &huart1) { if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET)) { __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除標志位 /*your own code*/ HAL_UART_DMAStop(&huart1);//停止DMA DMA_Usart1_RxSize = BUF_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 獲取DMA中傳輸?shù)臄?shù)據(jù)個數(shù) RevFlag = 1; HAL_UART_Receive_DMA(&huart1,RevBuf,BUF_LEN); //開啟下次接收 } }}
if(RevFlag == 1){ RevFlag = 0; HAL_UART_Transmit_DMA(&huart1,"DMA RevData\r
",13);}在串口中斷函數(shù)中調用空閑中斷函數(shù)。
m0lihhe5aex64048945026.png (17.74 KB, 下載次數(shù): 0)
下載附件
保存到相冊
m0lihhe5aex64048945026.png
2024-10-5 23:00 上傳
至此,串口的基本使用就介紹完了。需要注意的是,HAL庫需要考慮不同芯片的兼容性,因此程序編寫的比較復雜,執(zhí)行效率低,從串口中斷部分可以看出,有時當單片機資源有限且波特率較高時甚至會出現(xiàn)一些錯誤。所以需要用戶根據(jù)實際情況對中斷部分程序進行優(yōu)化或重新編寫。 |
|