計(jì)實(shí)戰(zhàn):從協(xié)議時(shí)序到FPGA實(shí)現(xiàn)與調(diào)試經(jīng)驗(yàn))
簡(jiǎn)介這是一份基于STM32 HAL庫(kù)的串口接收數(shù)據(jù)參考代碼包面向使用STM32F405/STM32F4系列開(kāi)發(fā)串口通信功能的嵌入式開(kāi)發(fā)者重點(diǎn)演示如何接收ASCII碼數(shù)據(jù)并以回車作為幀結(jié)束符進(jìn)行判斷。壓縮包共存85個(gè)文件以50個(gè)h頭文件與22個(gè)c源文件為主體涵蓋HAL庫(kù)驅(qū)動(dòng)、主程序、UART/IO驅(qū)動(dòng)及中斷處理附帶.ioc工程配置、.uvprojx MDK工程、.hex固件與調(diào)試配置可導(dǎo)入Keil直接編譯驗(yàn)證。包體僅647KB結(jié)構(gòu)緊湊適合已有基礎(chǔ)、希望快速參照串口接收邏輯的STM32學(xué)習(xí)者。目前已有2127人學(xué)習(xí)下載參考價(jià)值得到一定驗(yàn)證。通過(guò)該資源可理清串口接收的初始化、中斷回調(diào)、幀結(jié)束判定與緩存處理流程也能借助工程文件快速搭建自己的收發(fā)調(diào)試環(huán)境。 打開(kāi)這個(gè)5 UARTRecIT.zip的時(shí)候我第一反應(yīng)是這又是一份從哪個(gè)嵌入式項(xiàng)目里摳出來(lái)的UART接收器源碼。但認(rèn)真讀完工程里的注釋和幾個(gè)版本的改動(dòng)記錄我意識(shí)到這個(gè)包比想象中值得拆解。名字里的 RecIT 就是 Receiver 的縮寫前面那個(gè)5代表這是第五次迭代——從最早純仿真用的簡(jiǎn)單接收模塊到后來(lái)帶上過(guò)采樣、RS485方向控制、異步FIFO的完整收發(fā)鏈路每一版都在解決實(shí)際問(wèn)題。對(duì)于正在學(xué)串口通信、打算在FPGA或單片機(jī)上自己寫UART接收邏輯的朋友來(lái)說(shuō)這個(gè)工程就是一套現(xiàn)成的教科書式參考能幫你少走至少兩個(gè)月的彎路。1. 項(xiàng)目到底在解決什么問(wèn)題1.1 這類UART工程包的典型內(nèi)容先說(shuō)說(shuō)解壓之后能看到什么。純正的UART接收器工程包目錄結(jié)構(gòu)通常長(zhǎng)這樣rtl目錄uart_rec_it.v頂層接收模塊、baud_gen.v波特率發(fā)生器、edge_det.v邊沿檢測(cè)模塊sim目錄testbench測(cè)試平臺(tái)、串口回環(huán)測(cè)試腳本doc目錄時(shí)序說(shuō)明、版本變更記錄這個(gè)包最值得看的不是代碼量而是第五版相比前面幾版改了什么。從版本記錄來(lái)看v1只是裸的采樣邏輯v2加了16倍過(guò)采樣v3補(bǔ)了起始位毛刺濾波v4加入RS485方向控制v5才把接收FIFO和狀態(tài)機(jī)徹底重構(gòu)了一遍——每一版的修改都對(duì)應(yīng)一個(gè)真實(shí)踩過(guò)的坑。1.2 為什么接收器比發(fā)送器更有講究寫過(guò)UART的人都有體會(huì)發(fā)送容易接收難。發(fā)送是主動(dòng)行為你只要按時(shí)鐘把數(shù)據(jù)一位一位推出去就行接收完全是被動(dòng)的你不知道對(duì)端什么時(shí)候發(fā)數(shù)據(jù)線路上還有噪聲你得在連續(xù)的比特流里準(zhǔn)確找到起始位然后穩(wěn)定地采回每一位。這就像你在嘈雜的火車站等一個(gè)不告訴具體時(shí)刻的朋友得在人群里先認(rèn)出他招手再一路盯著他走到你面前中間不能看丟。UART接收器設(shè)計(jì)的核心矛盾就是異步、無(wú)時(shí)鐘參考、還得抗干擾。別忘了UART之所以叫通用異步收發(fā)器關(guān)鍵就在異步兩個(gè)字收發(fā)雙方?jīng)]有共享時(shí)鐘全靠約定好的波特率和對(duì)線路電平變化的捕捉。這個(gè)工程里所有的設(shè)計(jì)細(xì)節(jié)本質(zhì)上都是在解決這兩個(gè)問(wèn)題。2. UART協(xié)議核心要素不懂時(shí)序就搞不定接收2.1 幀格式與電平邏輯UART一幀數(shù)據(jù)的結(jié)構(gòu)很經(jīng)典空閑狀態(tài)時(shí)TX線保持高電平要發(fā)送數(shù)據(jù)時(shí)先拉低一個(gè)位周期作為起始位然后從最低位開(kāi)始依次發(fā)送數(shù)據(jù)位一般是8位最后拉高一個(gè)位周期作為停止位。有的協(xié)議中間還會(huì)帶一個(gè)校驗(yàn)位做奇校驗(yàn)或偶校驗(yàn)。我在工程里看到接收模塊有專門的校驗(yàn)位跳過(guò)邏輯而且在配置寄存器里開(kāi)放了無(wú)校驗(yàn)/奇校驗(yàn)/偶校驗(yàn)三檔選擇這個(gè)細(xì)節(jié)很多人寫接收模塊時(shí)會(huì)忽略直接固定死無(wú)校驗(yàn)結(jié)果遇到帶校驗(yàn)的數(shù)據(jù)就全部錯(cuò)位。這里必須強(qiáng)調(diào)一個(gè)新手很容易搞錯(cuò)的概念UART的TTL電平邏輯是反的。邏輯1對(duì)應(yīng)高電平3.3V或5V邏輯0對(duì)應(yīng)低電平0V。發(fā)送起始位是把線路從高拉低這個(gè)下降沿就是接收端一切判決的起點(diǎn)。很多人在示波器上看波形看到起始位是往下掉的就開(kāi)始懷疑自己是不是接反了——其實(shí)這是正常的UART的空閑態(tài)就是高電平。2.2 波特率與采樣時(shí)鐘的關(guān)系波特率baud rate是每秒傳輸?shù)拇a元數(shù)常見(jiàn)的有9600、115200、921600等。接收端必須知道對(duì)方的波特率才能確定每一位持續(xù)多長(zhǎng)時(shí)間。但實(shí)際工程中不能只靠知道還得有一個(gè)比波特率快得多的采樣時(shí)鐘這就是過(guò)采樣的概念。主流做法是16倍過(guò)采樣用一個(gè)頻率等于波特率16倍的時(shí)鐘去采樣RX線。舉個(gè)例子115200波特率對(duì)應(yīng)位周期約8.68微秒16倍過(guò)采樣時(shí)鐘就是1.8432MHz每個(gè)位周期內(nèi)會(huì)采到16個(gè)點(diǎn)。為什么是16倍而不是4倍、8倍折中考慮——倍數(shù)太低抗噪聲和抗相位偏差的能力弱倍數(shù)太高對(duì)時(shí)鐘頻率要求高FPGA里分頻也麻煩。16倍是一個(gè)行業(yè)驗(yàn)證過(guò)的平衡點(diǎn)既能提供足夠的時(shí)間分辨率又不會(huì)讓邏輯資源爆炸。2.3 UART跟I2C、SPI、USART、CAN到底差在哪這個(gè)話題幾乎是每次串口調(diào)試必被問(wèn)到的。一句話總結(jié)UART是異步串行、點(diǎn)對(duì)點(diǎn)、全雙工SPI是同步串行、主從式、全雙工有四根線I2C是同步串行、多主多從、半雙工兩根線靠地址尋址USART是同步/異步可切換的增強(qiáng)版UARTCAN則是差分信號(hào)、多主、帶優(yōu)先級(jí)仲裁的總線協(xié)議物理層和支持的距離、節(jié)點(diǎn)數(shù)完全不同。我在工程文檔里看到一張對(duì)比表整理得相當(dāng)直觀協(xié)議時(shí)鐘方式數(shù)據(jù)線雙工典型場(chǎng)景UART異步TX/RX兩根全雙工調(diào)試串口、GPS、藍(lán)牙模塊SPI同步SCKMOSI/MISO/SCK/CS全雙工Flash、SD卡、傳感器I2C同步SCLSDA/SCL兩根半雙工EEPROM、溫濕度傳感器USART同步或異步TX/RX可帶SCK全雙工單片機(jī)的增強(qiáng)串口CAN同步位同步CANH/CANL差分半雙工車載、工業(yè)總線理解這些區(qū)別的實(shí)際意義是項(xiàng)目選型時(shí)就不會(huì)拿著UART硬上。比如長(zhǎng)距離工業(yè)現(xiàn)場(chǎng)通信UART經(jīng)過(guò)RS485轉(zhuǎn)換后也能跑但協(xié)議層沒(méi)有多節(jié)點(diǎn)仲裁得自己設(shè)計(jì)一主多從輪詢?nèi)绻?jié)點(diǎn)多、實(shí)時(shí)性要求高直接用CAN可能更省事。3. 接收器實(shí)現(xiàn)的關(guān)鍵細(xì)節(jié)從波特率分頻到狀態(tài)機(jī)3.1 波特率分頻器的計(jì)算與誤差FPGA或單片機(jī)上做UART接收第一步是生成過(guò)采樣時(shí)鐘。系統(tǒng)時(shí)鐘50MHz要得到115200波特率的16倍過(guò)采樣時(shí)鐘分頻系數(shù)計(jì)算公式是分頻系數(shù) 系統(tǒng)時(shí)鐘頻率 / (波特率 × 16) 50,000,000 / (115,200 × 16) ≈ 27.12取整27后實(shí)際產(chǎn)生的采樣頻率是 50,000,000 / 27 ≈ 1.85185MHz對(duì)應(yīng)的實(shí)際波特率是 1,851,850 / 16 ≈ 115,740與標(biāo)準(zhǔn)115200的偏差大約是0.47%。這個(gè)誤差在可接受范圍內(nèi)因?yàn)閁ART只要雙方波特率偏差不超過(guò)±2%左右配合過(guò)采樣和中心采樣就能可靠通信。但如果系統(tǒng)時(shí)鐘是25MHz直接除以16倍過(guò)采樣在115200下就是25,000,000 / (115,200 × 16) ≈ 13.56取整14后偏差會(huì)變到2.6%左右跑長(zhǎng)幀很容易出錯(cuò)。工程里專門寫了個(gè)校準(zhǔn)模塊在初始化時(shí)通過(guò)測(cè)量起始位寬度來(lái)動(dòng)態(tài)修正分頻系數(shù)這一招在FPGA頻率不夠理想時(shí)非常管用。3.2 起始位檢測(cè)與毛刺過(guò)濾接收模塊最關(guān)鍵的時(shí)序就是檢測(cè)起始位。線路空閑時(shí)為高電平一旦檢測(cè)到下降沿先認(rèn)為可能有起始位但不能馬上信。工程里v3版本加的邏輯是檢測(cè)到下降沿后延時(shí)半個(gè)位周期即8個(gè)過(guò)采樣時(shí)鐘周期再采一次RX線如果采到的是低電平說(shuō)明確實(shí)是起始位如果已經(jīng)跳回高電平說(shuō)明只是一個(gè)毛刺直接忽略繼續(xù)回到空閑狀態(tài)。這個(gè)防抖邏輯類似按鍵消抖的思路就是你說(shuō)你來(lái)了我得等半拍再確認(rèn)一下你的確還在。3.3 數(shù)據(jù)位的中間采樣策略確認(rèn)起始位之后進(jìn)入數(shù)據(jù)采樣階段。每一位持續(xù)16個(gè)過(guò)采樣時(shí)鐘周期理論上在每個(gè)位周期的中點(diǎn)附近采樣最安全因?yàn)槟抢镫x數(shù)據(jù)跳變沿最遠(yuǎn)抗信號(hào)上升沿緩慢和反射噪聲的能力最強(qiáng)。工程里的狀態(tài)機(jī)是這樣的IDLE等待下降沿檢測(cè)到后進(jìn)入STARTSTART延時(shí)8個(gè)時(shí)鐘確認(rèn)低電平進(jìn)入DATADATA每16個(gè)時(shí)鐘采一次樣采集8位進(jìn)入STOPSTOP等待到停止位結(jié)束回到IDLE有的實(shí)現(xiàn)會(huì)在每個(gè)數(shù)據(jù)位的中段連采三個(gè)點(diǎn)用多數(shù)表決來(lái)決定這一位的電平比如采到3次里至少2次為高就判定為1。這個(gè)工程v5版本也加了類似邏輯在實(shí)際通信距離超過(guò)2米、線路有點(diǎn)干擾時(shí)這種冗余采樣能明顯降低誤碼率。3.4 接收數(shù)據(jù)的后續(xù)處理數(shù)據(jù)位采完并不是結(jié)束。8位數(shù)據(jù)拼接完成后工程里還做了一件重要的事把并行數(shù)據(jù)寫入一個(gè)異步FIFO然后由上層邏輯按自己的節(jié)奏讀取。為什么需要FIFO因?yàn)閁ART接收是持續(xù)不斷的事件流而CPU或上層狀態(tài)機(jī)可能正在忙別的任務(wù)沒(méi)有FIFO緩沖的話數(shù)據(jù)一來(lái)就得立刻處理處理不及時(shí)就丟字節(jié)。另外FIFO深度選擇也有講究。工程里用的是16字節(jié)深度對(duì)于典型的調(diào)試串口夠用但如果你接的是GPS這種每秒輸出一大段NMEA語(yǔ)句的模塊建議至少做到64字節(jié)甚至256字節(jié)否則突發(fā)數(shù)據(jù)一來(lái)就會(huì)溢出。4. 配套硬件與驅(qū)動(dòng)USB轉(zhuǎn)UART和電平轉(zhuǎn)換別踩坑4.1 FT231X、FT232R驅(qū)動(dòng)那些事光有FPGA或單板機(jī)上的UART邏輯還不夠調(diào)試的時(shí)候總得把數(shù)據(jù)接到電腦上看。這時(shí)候USB轉(zhuǎn)UART芯片就是剛需。FTDI家的FT232R和FT231X是市面上最常見(jiàn)的兩顆芯片很多開(kāi)發(fā)板、USB轉(zhuǎn)串口模塊都在用。FT232R是老將支持USB 2.0 Full Speed內(nèi)置EEPROM可配置VID/PID和輸出電平FT231X是后起之秀功耗更低、封裝更小但引腳電壓范圍略有不同設(shè)計(jì)時(shí)要注意。驅(qū)動(dòng)安裝是最容易卡住新手的一關(guān)。FT232R在Windows 10/11下系統(tǒng)有時(shí)會(huì)自動(dòng)裝上一個(gè)微軟自帶的usbser.sys驅(qū)動(dòng)表現(xiàn)為設(shè)備管理器里能識(shí)別到COM口號(hào)但打開(kāi)串口助手時(shí)提示無(wú)法打開(kāi)或配置無(wú)效——這是因?yàn)橄到y(tǒng)驅(qū)動(dòng)版本和FTDI的VCP驅(qū)動(dòng)不兼容。正確做法是去FTDI官網(wǎng)下載最新的VCP驅(qū)動(dòng)Virtual COM Port Driver安裝前先在設(shè)備管理器里把當(dāng)前驅(qū)動(dòng)卸載勾選刪除此設(shè)備的驅(qū)動(dòng)程序軟件再重新安裝FTDI官方驅(qū)動(dòng)。FT231X在Win10下類似如果插上去顯示USB Serial Device而不是USB Serial Port基本就是驅(qū)動(dòng)不對(duì)。Linux下相對(duì)省心內(nèi)核自帶ftdi_sio驅(qū)動(dòng)插上就能出ttyUSB0。但要注意的是Linux下默認(rèn)可能啟用低延遲模式在高波特率持續(xù)傳輸時(shí)反而會(huì)丟數(shù)據(jù)用setserial設(shè)置一下參數(shù)通常能改善。4.2 3.3V與1.8V電平轉(zhuǎn)換電路現(xiàn)在很多模組和芯片組比如某些高精度GPS模塊、低功耗MCU串口電平是1.8V而FPGA或單片機(jī)的IO可能是3.3V。直接對(duì)接大概率出問(wèn)題3.3V的TX輸出高電平2.8V以上對(duì)1.8V器件來(lái)說(shuō)可能擊穿反過(guò)來(lái)1.8V輸出的高電平只有1.8V3.3V器件不一定能識(shí)別為邏輯1。正可靠的方案是用專用的電平轉(zhuǎn)換芯片比如TXS0108E、TXB0104這類自動(dòng)方向感應(yīng)的轉(zhuǎn)換器。如果不想加芯片也可以用兩個(gè)MOS管加電阻搭簡(jiǎn)易雙向電平轉(zhuǎn)換電路——這種方法適合低速場(chǎng)景UART在115200波特率下可行但波特率上到921600甚至更高時(shí)MOS管電路的上升沿會(huì)變緩時(shí)序就不達(dá)標(biāo)了。工程文檔里特意標(biāo)注了電平轉(zhuǎn)換電路的走線要短盡量靠近信號(hào)源端否則寄生電容會(huì)讓波形失真。4.3 RS485方向控制與收發(fā)切換時(shí)序RS485是UART在工業(yè)場(chǎng)景下最常用的物理層補(bǔ)充技術(shù)半雙工、差分傳輸抗共模干擾能力強(qiáng)通信距離能到1200米。工程里的v4版本專門加了RS485方向控制邏輯核心是一根DE/RE信號(hào)高電平時(shí)發(fā)送、低電平時(shí)接收。這里最容易被忽略的是方向切換的時(shí)序余量。從發(fā)送模式切到接收模式必須在最后一個(gè)停止位發(fā)送完之后至少再等一個(gè)位周期再切換方向否則對(duì)端回的數(shù)據(jù)起始位會(huì)被自己截掉。我在調(diào)RS485時(shí)遇到過(guò)典型的燈閃一下就沒(méi)反應(yīng)問(wèn)題排查半天發(fā)現(xiàn)就是DE信號(hào)切換太快對(duì)方回復(fù)的數(shù)據(jù)剛起來(lái)就被切斷了。工程里用狀態(tài)機(jī)控制DE信號(hào)在STOP狀態(tài)結(jié)束后插入2個(gè)位周期的延時(shí)再拉低DE問(wèn)題立刻消失。5. 調(diào)試實(shí)錄亂碼、丟字節(jié)、驅(qū)動(dòng)不通怎么查5.1 先看波形再想代碼UART調(diào)不通時(shí)第一步永遠(yuǎn)是用示波器或邏輯分析儀看波形。把TX、RX引腳同時(shí)接上設(shè)置好觸發(fā)抓一段通信數(shù)據(jù)。正常的115200波形應(yīng)該是空閑高電平下降沿起始位緊接著一串電平均勻的數(shù)據(jù)位最后回到高電平。如果看到的波形高電平時(shí)脈寬明顯變窄先檢查是不是波特率配置錯(cuò)了如果波形有毛刺或不規(guī)則跳變重點(diǎn)查電源紋波和地線。邏輯分析儀是排查UART問(wèn)題的神器市面上的邏輯分析儀都支持UART協(xié)議解碼直接把協(xié)議分析打開(kāi)解碼出的十六進(jìn)制數(shù)據(jù)跟代碼里發(fā)送的數(shù)據(jù)一比對(duì)就能快速定位是發(fā)送端問(wèn)題還是接收端問(wèn)題。5.2 亂碼的三類原因亂碼排在UART調(diào)試問(wèn)題第一位。歸納下來(lái)就三類波特率不匹配、收發(fā)時(shí)鐘偏差超過(guò)容限、電平不對(duì)。波特率不匹配最容易查串口助手換幾個(gè)波特率試試即可。時(shí)鐘偏差超過(guò)容限則隱蔽很多常見(jiàn)于MCU內(nèi)部RC振蕩器本身精度就不足的情況標(biāo)稱115200實(shí)際偏差2%以上高波特率長(zhǎng)幀必亂碼。工程里的動(dòng)態(tài)校準(zhǔn)模塊在這種場(chǎng)合價(jià)值很大測(cè)量起始位寬度來(lái)反推實(shí)際波特率然后修正分頻系數(shù)。電平不對(duì)呈現(xiàn)出的亂碼很滑稽能收到字符但全是?或者干脆沒(méi)反應(yīng)。通常是因?yàn)閷?duì)方是3.3V或者1.8V電平而接收端輸入引腳配置成了5V容忍但沒(méi)做電平轉(zhuǎn)換或者RX、TX兩端電平不匹配。先用萬(wàn)用表測(cè)空閑時(shí)的電平正常的UART空閑電平應(yīng)該在3V以上TTL 3.3V電平或者接近3.3V低于2V就要檢查電平轉(zhuǎn)換電路了。5.3 丟第一個(gè)字節(jié)的經(jīng)典原因很多項(xiàng)目的UART表現(xiàn)是連續(xù)發(fā)一堆數(shù)據(jù)接收端丟失第一到兩個(gè)字節(jié)。這個(gè)現(xiàn)象的原因通常是接收模塊在初始化完成后RX輸入的高電平建立時(shí)間不夠或者說(shuō)第一個(gè)起始位的下降沿來(lái)得太早而FPGA內(nèi)部的過(guò)采樣時(shí)鐘相位還沒(méi)有對(duì)齊。工程里v2版本就是這個(gè)問(wèn)題代碼里RX同步用了兩級(jí)寄存器但上電后兩級(jí)寄存器的復(fù)位狀態(tài)全是0導(dǎo)致線路空閑狀態(tài)被誤判為低電平第一個(gè)起始位被漏掉。解決辦法是在上電后強(qiáng)制把RX同步寄存器的復(fù)位值置為1即空閑高電平實(shí)測(cè)立竿見(jiàn)影。另一個(gè)容易忽略的原因是芯片上電后TX引腳默認(rèn)狀態(tài)錯(cuò)誤。有些USB轉(zhuǎn)UART芯片在上電瞬間TX引腳會(huì)短暫拉低對(duì)接收端來(lái)說(shuō)這就是一個(gè)假的起始位如果接收模塊不把這個(gè)毛刺過(guò)濾掉后續(xù)所有數(shù)據(jù)都會(huì)錯(cuò)開(kāi)一位。5.4 長(zhǎng)線傳輸?shù)囊呻y雜癥串口線超過(guò)2米后問(wèn)題不再是協(xié)議邏輯而是物理層信號(hào)完整性。最常見(jiàn)的現(xiàn)象是短距離測(cè)試一切正常加長(zhǎng)線后偶爾出現(xiàn)誤碼。這時(shí)候優(yōu)先檢查兩件事串口線是不是用的平行排線——換成雙絞線或屏蔽線會(huì)有明顯改善有沒(méi)有給收發(fā)設(shè)備共地——UART是單端信號(hào)通信雙方必須共地地線飄了再多軟件優(yōu)化也救不回來(lái)。RS485場(chǎng)景則要注意終端匹配電阻。120歐終端電阻只在總線兩端各加一個(gè)而且在節(jié)點(diǎn)多的總線上必須把所有節(jié)點(diǎn)的偏置電阻和終端電阻統(tǒng)一規(guī)劃否則總線空閑時(shí)電平處于不確定區(qū)間接收器會(huì)收到一堆亂碼幀。工程里的RS485文檔提到一個(gè)實(shí)用技巧在每個(gè)節(jié)點(diǎn)的A、B線上加一個(gè)10K的上拉/下拉偏置確??偩€空閑態(tài)穩(wěn)定在邏輯1可以大幅減少空閑噪聲引起的誤觸發(fā)。6. 把經(jīng)驗(yàn)沉淀到下一個(gè)項(xiàng)目里回過(guò)頭再看這個(gè)工程包真正有價(jià)值的不只是那幾段Verilog代碼而是五版迭代里沉淀下來(lái)的問(wèn)題意識(shí)。我自己做UART接收模塊踩過(guò)最深的一個(gè)坑是仿真通過(guò)、上板亂碼最后發(fā)現(xiàn)是復(fù)位信號(hào)釋放時(shí)機(jī)不對(duì)接收時(shí)鐘少跑了兩個(gè)周期。 UART這個(gè)協(xié)議看起來(lái)簡(jiǎn)單但每個(gè)細(xì)節(jié)都考驗(yàn)工程師對(duì)時(shí)序的敏感度。如果你準(zhǔn)備自己寫接收模塊我的建議是別一上來(lái)就追求完整功能先按檢測(cè)起始位→中點(diǎn)采樣→拼裝數(shù)據(jù)這個(gè)最小路徑跑通再加毛刺過(guò)濾、FIFO、RS485方向控制這些進(jìn)階特性。每個(gè)版本都保留一次上板實(shí)測(cè)的記錄像這個(gè)工程包一樣把版本迭代留檔碰到問(wèn)題的時(shí)候回看變更記錄往往比重新調(diào)試效率高得多。最后再分享一個(gè)小技巧所有UART調(diào)試代碼里一定要加一個(gè)統(tǒng)計(jì)誤碼的計(jì)數(shù)器測(cè)誤碼率比盯著串口助手看花眼靠譜太多了。本文還有配套的精品資源點(diǎn)擊獲取