據(jù)交互實(shí)戰(zhàn))
串口通信避坑指南樹莓派與STM32 的數(shù)據(jù)交互實(shí)戰(zhàn)近些日子有個(gè)智能小車方面的項(xiàng)目, 這里需要將樹莓派跟那種STM32利用串口展開交流。原本以為這不過(guò)是輕松搞定的連線, 以及簡(jiǎn)簡(jiǎn)單單書寫好幾行代碼的事兒, 然而實(shí)際遭遇的麻煩遠(yuǎn)比設(shè)想的多好多。先是樹莓派的串口怎么都沒辦法開啟, 接著又是STM32接收數(shù)據(jù)出現(xiàn)亂碼的狀況, 而后還有兩邊通信協(xié)議相互不匹配的問(wèn)題, 差不多把所有可能碰到的陷阱問(wèn)題整個(gè)體驗(yàn)一番了。這篇章體內(nèi)容就是專注去梳理整合這些遭遇麻煩的經(jīng)歷以及對(duì)應(yīng)的解決辦法, 期望能夠給予那些正忙于嘗試樹莓派跟嵌入式設(shè)備進(jìn)行通信事宜的友人們提供一定程度的助力幫助。串口通信看上去好像很古老, 然而在嵌入式跟單板計(jì)算機(jī)共同協(xié)作工作的情景當(dāng)中, 它依舊是最為直接、最為可靠的通信方式當(dāng)中的一種。不存在繁雜的網(wǎng)絡(luò)協(xié)議棧, 不存在驅(qū)動(dòng)兼容性方面的問(wèn)題, 僅僅將幾根線連接在一起數(shù)據(jù)便能夠開始流動(dòng)起來(lái)??墒? 這種所謂的“簡(jiǎn)單”背后隱藏著相當(dāng)多的細(xì)節(jié), 像電平匹配、波特率校準(zhǔn)、數(shù)據(jù)幀解析、流控制等, 只要任何一個(gè)環(huán)節(jié)出現(xiàn)問(wèn)題, 通信就會(huì)遭遇失敗。尤其是在你將具備完整Linux系統(tǒng)運(yùn)行環(huán)境的樹莓派與資源存在限制情形的STM32單片機(jī)放置到一起的時(shí)候, 這兩者之間的編程模型乃是不同的, 其系統(tǒng)時(shí)序情形亦不一樣, 再者調(diào)試手段方面的差異著實(shí)巨大, 如此一來(lái)便更加要求有一套清晰的實(shí)踐予以實(shí)施辦法來(lái)能夠規(guī)避風(fēng)險(xiǎn)了。本文會(huì)從實(shí)際項(xiàng)目著手, 不但會(huì)告知你怎樣使樹莓派與STM32成功實(shí)現(xiàn)通信, 甚至還會(huì)深入探究那些易被忽視的細(xì)節(jié): 一、樹莓派的/dev/為何有時(shí)會(huì)“不見”? 二、STM32中斷接收數(shù)據(jù)為何會(huì)出現(xiàn)丟包情況? 三、怎樣設(shè)計(jì)一個(gè)既簡(jiǎn)單又穩(wěn)健的通信協(xié)議去處理粘包及錯(cuò)誤? 我們會(huì)把作為樹莓派端的主要工具, 聯(lián)合具體的代碼示例以及調(diào)試技巧, 使你在動(dòng)手進(jìn)行實(shí)踐時(shí)避開那些令我熬夜調(diào)試的“大坑”。1. 環(huán)境準(zhǔn)備與硬件連接從混亂到有序在著手寫代碼起始之時(shí), 準(zhǔn)確無(wú)誤的硬件連接以及軟件環(huán)境乃是成功得以實(shí)現(xiàn)的根基所在。要是在這一極為關(guān)鍵緊要的步驟當(dāng)中有所疏忽大意, 那么后續(xù)開展的所有調(diào)試工作極有可能是在錯(cuò)誤的導(dǎo)向路徑之上無(wú)謂地?fù)p耗時(shí)間, 白費(fèi)精力, 徒勞無(wú)功。1.1 硬件連線不僅僅是TX接RX在樹莓派以4B作為示例的GPIO各個(gè)引腳當(dāng)中 的 GPIO的 以4B為例 物理引腳8/TXD以及 還有物理這個(gè)引腳10/RXD便是 是默認(rèn)的 屬于那種硬件串口比如說(shuō)UART的引腳。到了STM32開發(fā)板以常見的逐飛科技核心板當(dāng)作例子這里 其串口引腳就得 需要去查看原理圖 一般來(lái)說(shuō)通常都是 某一個(gè)USART里面的TX和RX引腳 就像比如說(shuō)和 這樣。注意, 最基礎(chǔ)的連接原則乃是交叉連接, 即樹莓派的TXD要去接STM32的RXD, 樹莓派的RXD則須接STM32的TXD。除此之外, 一定要連接兩者的GND, 也就是地線, 以此為信號(hào)提供共同的參考電平, 而這可是很多初學(xué)者容易忽略進(jìn)而導(dǎo)致通信不穩(wěn)定的關(guān)鍵所在。然而, 僅僅把這三根線連接起來(lái), 也就是TXD, RXD, GND, 這或許還不行。要是你的通信距離在較長(zhǎng)的范圍, 也就是超過(guò)1米, 或者所處環(huán)境干擾比較大這樣的情況下, 那就得考慮去添加電平轉(zhuǎn)換了。樹莓派的GPIO是3.3V電平, 而好多STM32開發(fā)板盡管同樣是3.3V, 可是有些模塊或者轉(zhuǎn)換芯片有可能是5V。直接將3.3V和5V設(shè)備連接起來(lái), 就有可能會(huì)損壞樹莓派。穩(wěn)妥的舉措是用到一個(gè)3.3V/5V雙向電平轉(zhuǎn)換模塊, 比如等等, 或者去確認(rèn)你的STM32板載IO電平同樣是3.3V。一個(gè)清晰的連接對(duì)照表能幫你快速排查硬件問(wèn)題設(shè)備端信號(hào)線連接目標(biāo)引腳說(shuō)明電壓樹莓派 4BTXD ()STM32 RXD物理引腳 83.3V樹莓派 4BRXD ()STM32 TXD物理引腳 103.3V樹莓派 4BGNDSTM32 GND物理引腳 6 (或其他GND)0VSTM32TXD (如 PA9)樹莓派 RXD3.3VSTM32RXD (如 PA10)樹莓派 TXD3.3V1.2 樹莓派串口配置解開系統(tǒng)“占用鎖”樹莓派原本默認(rèn)的那個(gè)硬件串口, 也就是/dev/的那個(gè), 被分配給了藍(lán)牙模塊, 與此同時(shí), 另一個(gè)迷你串口, 即/dev/ttyS0, 被分配給了GPIO引腳。為了能夠獲得穩(wěn)定的、高性能的通信, 我們需要進(jìn)行交換。把它們交換一下, 并且將硬件串口釋放出來(lái)。起先, 借助SSH要么直接連接終端至樹莓派, 運(yùn)用raspi-工具予以配置。sudo raspi-config在界面中依次選擇當(dāng)被問(wèn)到“Would you like a login shell to be over?”的時(shí)候, 要選擇No, 這一點(diǎn)是很重要的哦, 不然的話串口就會(huì)被登錄終端給占用啦。當(dāng)被問(wèn)到“Would you like the port to be?”的時(shí)候, 要選擇Yes。接下來(lái)需要編輯引導(dǎo)配置文件確保硬件UART被正確啟用sudo nano /boot/config.txt在文件末尾添加或修改以下兩行enable_uart1 dtoverlaydisable-bt讓第一行去強(qiáng)制性地啟用UART, 將第二行用于禁用藍(lán)牙從而去釋放硬件串口, 進(jìn)行保存并且退出CtrlX, 接著是Y, 隨后回車, 重新啟動(dòng)一下樹莓派來(lái)令更改產(chǎn)生效果。將其重新啟動(dòng)之后, 對(duì)串口設(shè)備展開驗(yàn)證。去執(zhí)行 ls -l /dev/* 這個(gè)操作, 你理應(yīng)能夠看到類似于以下這般的輸出結(jié)果:/dev/serial0 - ttyAMA0 /dev/serial1 - ttyS0這意味著, /dev/區(qū)域也即我們這些GPIO引腳所對(duì)應(yīng)的串口, 此刻已然指向了硬件串口, 你能夠借助這個(gè)終端工具來(lái)開展快速測(cè)試。sudo apt-get install minicom -y sudo minicom -b 115200 -o -D /dev/ttyAMA0要是呈現(xiàn)出界面并且不存在錯(cuò)誤, 那就表明串口設(shè)備已然就緒。按下CtrlA, 接著按下X從而退出。1.3 環(huán)境與庫(kù)安裝樹莓派通常預(yù)裝了。我們使用pip來(lái)安裝功能強(qiáng)大的庫(kù)sudo pip3 install pyserial在完成安裝之后, 能夠去撰寫一個(gè)最為簡(jiǎn)單的測(cè)試腳本.py, 以此來(lái)檢驗(yàn)庫(kù)是否工作處于正常狀態(tài):import serial try: # 嘗試打開串口不進(jìn)行實(shí)際通信 ser serial.Serial(/dev/ttyAMA0, 115200, timeout1) print(f串口 {ser.port} 打開成功配置為{ser}) ser.close() print(串口已關(guān)閉。) except serial.SerialException as e: print(f打開串口失敗{e})執(zhí)行.py, 要是瞅見成功開啟的訊息, 那就表明串口環(huán)境已準(zhǔn)備妥當(dāng)。2. 樹莓派端串口編程核心技巧掌握了基礎(chǔ)環(huán)境我們來(lái)深入的庫(kù)。它雖然接口簡(jiǎn)單但