電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 47|回復(fù): 0
收起左側(cè)

STM32CubeMX之串口通信

[復(fù)制鏈接]

454

主題

454

帖子

2398

積分

三級(jí)會(huì)員

Rank: 3Rank: 3

積分
2398
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2020-3-22 19:03:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |正序?yàn)g覽 |閱讀模式
串口通信的基本概念可參考下面的一篇文章,本章將介紹如何使用STM32CubeMX工具快速編寫(xiě)串口通信的程序。

前期準(zhǔn)備
STM32硬件電路板及仿真器(以STM32F407單片機(jī)為例)
Keil v5以上版本(MDK-ARM)
USB轉(zhuǎn)串口工具及驅(qū)動(dòng)
串口調(diào)試助手

STM32CubeMX配置首先,時(shí)鐘等的配置參考之前文章的介紹(STM32CubeMX之GPIO的使用)。串口部分配置如下:

選擇Mode為常用的異步串口Asynchronous,不使能RS232硬件流控制。波特率設(shè)置為115200,數(shù)據(jù)長(zhǎng)度8位,無(wú)校驗(yàn)位,1位停止位。
打開(kāi)中斷和添加發(fā)送和接收的DMA,DMA參數(shù)設(shè)置為默認(rèn)即可,如下圖。




編寫(xiě)程序設(shè)置完成后生成代碼。初始化部分已經(jīng)自動(dòng)生成,用戶(hù)只要添加發(fā)送和接收的代碼就行。串口發(fā)送和接收的函數(shù)包括三種方式:查詢(xún)、中斷和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);查詢(xún)方式相對(duì)比較占用CPU資源,因此中斷和DMA方式使用的比較多。這里不再介紹查詢(xún)方式的收發(fā)程序,只介紹中斷和DMA方式。串口發(fā)送比較簡(jiǎn)單,直接調(diào)用相關(guān)函數(shù)即可,如下:
  • HAL_UART_Transmit_IT(&huart1,"Hello World\r
    ",13);HAL_UART_Transmit_DMA(&huart1,"DMA Test\r
    ",10);HAL庫(kù)的串口接收只支持接收定長(zhǎng)數(shù)據(jù),當(dāng)數(shù)據(jù)長(zhǎng)度不確定時(shí),需要自己處理。中斷方式接收
    首先初始化完成后打開(kāi)串口接收中斷,接收長(zhǎng)度為1字節(jié),即當(dāng)接收到一個(gè)字節(jié)數(shù)據(jù)后產(chǎn)生串口接收中斷。
  • HAL_UART_Receive_IT(&huart1,&RevByte,1);//打開(kāi)串口接收中斷編寫(xiě)中斷回調(diào)函數(shù),由于HAL庫(kù)已經(jīng)在底層做了處理,串口接收的1字節(jié)數(shù)據(jù)已經(jīng)存儲(chǔ)在RevByte中,因此在中斷中直接讀取RevByte的值即可。需要注意的是讀取完成后要重新打開(kāi)中斷接收。
  • //串口接收中斷回調(diào)函數(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+空閑中斷的方式也可以實(shí)現(xiàn)接收不定長(zhǎng)的數(shù)據(jù)。首先初始化完成后打開(kāi)串口空閑中斷和DMA接收。
  •   __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//打開(kāi)串口空閑中斷  HAL_UART_Receive_DMA(&huart1, RevBuf, BUF_LEN); //串口1DMA接收數(shù)據(jù)編寫(xiě)空閑中斷函數(shù),在主程序中判斷標(biāo)志位,進(jìn)行相關(guān)處理
  • 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);//清除標(biāo)志位        /*your own code*/        HAL_UART_DMAStop(&huart1);//停止DMA        DMA_Usart1_RxSize = BUF_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 獲取DMA中傳輸?shù)臄?shù)據(jù)個(gè)數(shù)        RevFlag = 1;        HAL_UART_Receive_DMA(&huart1,RevBuf,BUF_LEN); //開(kāi)啟下次接收      }      }}
    if(RevFlag == 1){   RevFlag = 0;   HAL_UART_Transmit_DMA(&huart1,"DMA RevData\r
    ",13);}在串口中斷函數(shù)中調(diào)用空閑中斷函數(shù)。


    至此,串口的基本使用就介紹完了。需要注意的是,HAL庫(kù)需要考慮不同芯片的兼容性,因此程序編寫(xiě)的比較復(fù)雜,執(zhí)行效率低,從串口中斷部分可以看出,有時(shí)當(dāng)單片機(jī)資源有限且波特率較高時(shí)甚至?xí)霈F(xiàn)一些錯(cuò)誤。所以需要用戶(hù)根據(jù)實(shí)際情況對(duì)中斷部分程序進(jìn)行優(yōu)化或重新編寫(xiě)。
  • 發(fā)表回復(fù)

    本版積分規(guī)則


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表