加入星計劃,您可以享受以下權益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 一、配置底層引腳
    • 二、編寫應用層代碼
    • 三、進階學習
    • 四、常見問題解答
    • 五、結束語
  • 推薦器件
  • 相關推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

RT-Thread零基礎快速入門第9講——串口(UART/RS485)

07/11 14:34
6523
閱讀需 19 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

串口是單片機最常用的通訊方式之一,關于串口的介紹在RT-thread官網(wǎng)上已經(jīng)有非常詳細的介紹了,我這里就不多講了,今天主要講一講官網(wǎng)上沒有的東西,讓你更加深入的了解RT-thread是如何配置和使用串口進行數(shù)據(jù)收發(fā)的。

RT-thread官網(wǎng)上關于UART的資料:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/uart/uart_v1/uart

一、配置底層引腳

1、確定串口引腳

先從原理圖查看自己需要使用的串口號及對應的引腳。比如我要使用串口3,引腳是PB10和PB11(USART3除了這一組引腳還有PC10、PC11)

在這里插入圖片描述

2、配置底層引腳

1)配置串口

打開keil工程,使用STM32CubeMX配置底層接口(路徑一般在工程目錄下boardCubeMX_Config文件夾里面)

不懂的同學可以看下我之前的博客:RT-Thread零基礎快速入門第1講——新建工程

先打開對應的串口(Mode選擇Asynchronous即可),然后檢查GPIO是否和原理圖一致。

在這里插入圖片描述

如果不一致的話可以在右邊的芯片圖上面找到正確的引腳,然點擊引腳,修改該引腳為串口功能,最后再回到上一步,檢查一下串口是否已經(jīng)修改成正確的引腳了。

在這里插入圖片描述
在這里插入圖片描述

提示:使用STM32CubeMX配置串口只需要打開串口和配置引腳,其他的像波特率、NVIC這些都需要管,因為這些都是在RTT應用層初始化的時候配置的,即使在這里改了也是不起作用的。

2)生成新的工程

點擊右上角的GENERATE CODE,生成新工程即可。

注:如果生成工程時提示你是否需要下載新版本的固件庫,可以下載也可以繼續(xù)使用舊的,一般都是沒問題的。

在這里插入圖片描述

二、編寫應用層代碼

1、打開串口使能

用env打開工程,進入menuconfig配置頁面,打開串口使能。

提示:這里的使能和上面STM32CubeMX打開串口是不一樣的,env配置使能之后實際上是打開一個宏定義,打開之后才能調(diào)用RTT串口相關的庫函數(shù),而STM32CubeMX使能則是把HAL庫串口相關的函數(shù)加進來。

如果你不知道env怎么使用,可以在下面這個鏈接查看。

env使用方法:https://www.rt-thread.org/document/site/programming-manual/env/env/#bsp-menuconfig

在這里插入圖片描述

配置好之后,退出保存即可。

注意:如果menuconfig里面沒有你要使用的串口號怎么辦,這個問題請?zhí)胶竺娌榭?“常見問題解答”。

2、重新生成工程

在env輸入下面的命令,重新生成新的工程。

提示:會使用env的話應該都知道這個操作。

scons --target=mdk5

3、編寫串口收發(fā)代碼

串口收發(fā)的示例代碼可以在RT-thread官網(wǎng)查看,有中斷接收的示例,也有DMA接收的示例,都是寫的很詳細的了,拷貝過來改一下就可以用了。

你也可以在menuconfig里面打開串口接收的示例。

在這里插入圖片描述

打開示例之后要重新生成工程,也就是上面第2步的操作。

建議:如果只是測試串口功能的話可以直接添加示例文件,但是實際應用中還是建議新建一個文件,然后編寫串口的應用代碼,再把這個文件加入到keil工程里面。

參考:RT-Thread零基礎快速入門第2講——添加新文件到工程

不管用哪種方法,示例代碼添加進來之后還是要按照自己的需求修改配置,比如串口號,波特率,串口接收的數(shù)據(jù)處理等。

我這里簡單的舉個例子,具體怎么改還是要看你的功能需求。

以中斷接收的demo為例:

1)修改串口號

直接修改SAMPLE_UART_NAME這個宏即可,比如我這里用的是串口3,就改成"uart3"

#define SAMPLE_UART_NAME       "uart3"      /* 串口設備名稱 */

2)修改波特率

在查找串口(rt_device_find)之后,打開串口(rt_device_open)之前添加下面這段代碼即可。

/* 修改串口配置參數(shù) */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;  // 初始化配置參數(shù)
config.baud_rate = BAUD_RATE_9600;        //修改波特率為 9600
config.data_bits = DATA_BITS_8;           //數(shù)據(jù)位 8
config.stop_bits = STOP_BITS_1;           //停止位 1
config.bufsz     = 128;                   //修改緩沖區(qū) buff size 為 128
config.parity    = PARITY_NONE;           //無奇偶校驗位
/* 控制串口設備。通過控制接口傳入命令控制字,與控制參數(shù) */
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);

如下圖所示:

在這里插入圖片描述

3)串口數(shù)據(jù)接收處理

如果數(shù)據(jù)不多處理不復雜,可以直接在接收數(shù)據(jù)的線程進行數(shù)據(jù)處理,如下圖所示:

在這里插入圖片描述

如果數(shù)據(jù)比較多或者處理比較復雜需要消耗的時間比較長的情況下,就不太建議在接收的線程進行數(shù)據(jù)處理了,因為在這里處理數(shù)據(jù)會影響后續(xù)的數(shù)據(jù)接收。

推薦幾種常用的解決方法:

1:使用消息隊列把接收到的數(shù)據(jù)傳輸到其他線程,在其他的線程做統(tǒng)一的數(shù)據(jù)處理。

2:如果接收是以中斷的方式,可以考慮在接收的時候就做先做簡單的處理,比如用一個switch語句,每接收一個數(shù)據(jù)就處理一次,這樣就可以把每個字節(jié)接收的間隙時間利用起來。這個方法也可以用來判斷數(shù)據(jù)幀是否完整接收完成,是否有錯誤的數(shù)據(jù)幀。

數(shù)據(jù)處理的方法有很多,各有優(yōu)劣,具體用哪種方式則要看實際的情況,適合的方法才是最好的。

利用switch語句處理接收數(shù)據(jù)的示例代碼:

switch(count)
{
    case 0:{
        if(ch == 0xFC){                  // 幀頭
            uart_rx_buffer[i++] = ch;
            count ++;
        }
        else{
            i = 0;
            count = 0;
        }
        break;
    }
    case 1:{                             // 地址
        if(ch == 1 || ch == 2){
            uart_rx_buffer[i++] = ch;
            count ++;
        }
        else{
            i = 0;
            count = 0;
        }
        break; 
    } 
    case 2:{                             // 命令
            if(ch == 0xD4){
            uart_rx_buffer[i++] = ch;
            count ++;
        }
        else{
            i = 0;
            count = 0;
        }
        break;
    }
    case 3:{
            uart_rx_buffer[i++] = ch;     // 數(shù)據(jù)高位
            count ++;
        break;
    }
    case 4:{
            uart_rx_buffer[i++] = ch;     // 數(shù)據(jù)高位
            count ++;
        break;
    }
    case 5:{
            uart_rx_buffer[i++] = ch;     // 校驗
            i = 0;
            count = 0; 
            if(verify_check(uart_rx_buffer, 5) == uart_rx_buffer[5]) // 檢查校驗
            {
                rt_sem_release(rs485_timeout_sem);
                uart_485_data_handle(uart_rx_buffer);
            }
        break; 
    }
    default: 
        i = 0;
        count = 0;
        break;
}

三、進階學習

1、串口的硬件小知識

串口常用的電平有三種:TTL、RS232、RS485。

類型 說明
TTL 電壓范圍0V至+5V,高電平>2.4V,低電平<0.4V,一般MCU直接輸出的串口就是TTL電平
RS232 電壓范圍-15V至+15V,高電平為-3V至-15V,低電平為+3V至+15V
RS485 電壓范圍-7V至+12V,不同于TTL和RS232,RS485采用的差分信號負邏輯,高電平為兩線間的電壓差-2V至-6V,低電平為兩線間的電壓差+2V至+6V
USB 有單獨的協(xié)議,與TTL、RS232和RS485都不同

三種電平之間不能直接通信,需要通過轉(zhuǎn)換芯片轉(zhuǎn)換成相同的電平。除了這三種電平以外,我們常常還用到USB,USB有自己的協(xié)議(2.0、3.0、3.1等),USB和TTL、RS232和RS485這些電平之間也是不能直接通信的,也需要轉(zhuǎn)換。一般單片機或者其他MCU的串口電平都是TTL的,而PC端一般使用USB。

舉個例子:

如果MCU的串口需要連接到PC端,那么就需要實現(xiàn)TTL和USB直接的轉(zhuǎn)換,常用的方法如下:

1、通過一個USB轉(zhuǎn)TTL的芯片轉(zhuǎn)換,可以放在主板上,也可以用那種轉(zhuǎn)換小板,這個大家應該比較熟悉了,某寶上面隨處可見。
2、通過一個TTL轉(zhuǎn)232的芯片轉(zhuǎn)換,然后再接一根USB轉(zhuǎn)232的連接線,這個線常用DB9接口。
3、通過一個TTL轉(zhuǎn)485的芯片轉(zhuǎn)換,然后再接一根USB轉(zhuǎn)485的連接線。

TTL一般是板內(nèi)模塊間通訊用的比較多,因為串口線過長會有線損,影響通訊,因此,外接的傳感器和MCU的通訊大多使用RS232和RS485這兩種,像RS485,串口線即使長達一百米,也不影響正常通訊。

2、RS485的使用

上面簡單介紹了三種電平硬件上的區(qū)別,那么在編程上又有什么區(qū)別呢?

對于TTL和RS232來說,編程都是一樣的,只要配置好UART的收發(fā)即可,電平的轉(zhuǎn)換都是通過轉(zhuǎn)換芯片來完成的,與代碼無關。RS485也是類似的,電平的轉(zhuǎn)換也是通過轉(zhuǎn)換芯片來完成,但不同的是RS232是可以同時收發(fā)的,而RS485在同一時間只能發(fā)送或者接收,因此,RS485的轉(zhuǎn)換芯片多了一個使能引腳,這個使能腳是用來切換發(fā)送模式和接收模式的,一般是由MCU來控制。

在這里插入圖片描述

我們在寫代碼的時候只要把RS485這個使能腳的控制加進去就可以了。

1)先定義485的使能引腳,以及加入GPIO配置要用到的頭文件。

#include <rtdevice.h>
#include <board.h>
#define RS485_RE  GET_PIN(G, 8)

提示:引腳號用宏定義,這樣的話如果以后要修改引腳,就不需要把每個函數(shù)都改一遍。

2)在串口初始化的時候把485使能引腳的初始化也加進去,默認設置為接收模式。

rt_pin_mode(RS485_RE, PIN_MODE_OUTPUT);   // 配置RS485使能引腳為輸出
rt_pin_write(RS485_RE, PIN_LOW);          // 配置RS485為接收模式(一般低電平是接收模式,高電平是發(fā)送模式,當然,也有相反的,主要還是看485用什么芯片)

3)在串口發(fā)送數(shù)據(jù)前切換485為發(fā)送模式,發(fā)送完成后再切回接收模式。

rt_pin_write(RS485_RE, PIN_HIGH);         // 發(fā)送模式 
rt_device_write(serial, 0, &ch, 1);       // 發(fā)送數(shù)據(jù)
rt_pin_write(RS485_RE, PIN_LOW);          // 接收模式

四、常見問題解答

1、ENV配置里面沒有我要用的串口號

問題分析:這是因為你這個工程menuconfig頁面的配置文件并沒有把所有串口和配置都添加進來。

解決辦法:在工程目錄下board文件夾里面有一個Kconfig文件,這個就是menuconfig頁面的配置文件,在里面找到串口的配置,可以把原有的配置修改成你想要的串口號,也可以照貓畫虎的抄一遍原有的配置,然后再修改成你想要的串口號。修改完之后重新打開menuconfig即可,如果報錯打不開了,說明的改的有問題,有語法錯誤。

在這里插入圖片描述

還有一個辦法就是直接在工程文件里面的rtconfig.h添加串口使能的宏定義,實際上使用env配置修改的也是這個文件的宏,但是這樣做有一個問題就是每次你使用env配置好參數(shù)之后,你都要再手動添加一遍串口使能的宏,因為每次使用env配置參數(shù)的時候都會按照Kconfig文件覆蓋一遍,而Kconfig又沒有你手動添加的這個宏,所以,最好還是用上面的方法,在根本上解決問題。

在這里插入圖片描述

2、ENV配置的串口配置沒有DMA模式

問題分析:這個問題和上面那個問題其實是一樣的,修改Kconfig即可

3、ENV配置沒錯,硬件電路也是對的,但是串口就是收不到數(shù)據(jù)

問題分析:假如你ENV的配置是沒錯的,硬件電路也確認過是正常的,使用list_device也能查找到uart設備,但是就是收不到數(shù)據(jù),有可能是底層串口沒有配置好,比如底層的引腳號配置的不對或者串口根本就沒有打開,這種情況在修改了電路圖或者工程的時候很容易出現(xiàn),也很容易忽視,因為這個問題編譯的時候并不會報錯,你不仔細核對原理圖是發(fā)現(xiàn)不了的。

解決辦法:使用STM32CubeMX配置好串口的參數(shù),具體的操作上面已經(jīng)介紹過,就不多說了。

4、STM32CubeMX、ENV及串口初始化等軟件部分都確認是對的,但就是沒有數(shù)據(jù)

問題分析:這種情況就要結合硬件一起排查了,最快的排查方法就是直接上示波器或者邏輯分析儀,可以單獨寫一個測試線程,讓單片機定時發(fā)數(shù)據(jù)(發(fā)什么數(shù)據(jù)不重要),然后用示波器查看MCU串口的TX引腳的波形,正常的波形是很規(guī)律的,每一幀的數(shù)據(jù)間隔也會跟你定時的時間一致,并且數(shù)據(jù)幀的波形都是比較漂亮的方波。如果沒有波形,排除MCU損壞的情況的話,肯定還是軟件沒有配置好。接收的測試也是一樣的,可以通過PC端的串口助手定時發(fā)送數(shù)據(jù),然后測試MCU串口的RX引腳,看看波形是否正常,如果波形正常,但是單片機就是沒有收到數(shù)據(jù),那肯定還是軟件沒有配置好。

5、串口每次都只能通過輸入命令啟動嗎

命令行輸入只是為了方便我們測試,實際使用的話可以使用INIT_APP_EXPORT自動加載函數(shù),或者在其他函數(shù)、線程里面調(diào)用。
例如:

INIT_APP_EXPORT(uart_sample);

五、結束語

串口的使用其實非常簡單,但是實際使用的時候往往會因為一些小問題折騰了半天,這個時候一定要冷靜的分析問題,先檢查一遍硬件電路,再按流程檢查一遍配置和代碼,最后實在沒辦法了就上示波器吧。

好了,關于RT-thread串口的介紹就到這里,如果還有什么問題,歡迎在評論區(qū)留言。如果這篇文章能夠幫到你,就給我點個贊吧,如果想了解更多RT-thread和單片機的內(nèi)容,可以關注一下博主,后續(xù)我還會繼續(xù)分享更多的經(jīng)驗給大家。

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風險等級 參考價格 更多信息
MX573BBA156M250 1 Microchip Technology Inc CRYSTAL OSCILLATOR, CLOCK, LVPECL OUTPUT
暫無數(shù)據(jù) 查看
DC200D40 1 Crydom Inc Transistor Output SSR, 1-Channel, 2500V Isolation, ROHS COMPLIANT PACKAGE-4
$119.73 查看
KSZ8863RLLI 1 Microchip Technology Inc DATACOM, LAN SWITCHING CIRCUIT, PQFP48

ECAD模型

下載ECAD模型
$5.09 查看

相關推薦

電子產(chǎn)業(yè)圖譜