送MISO輸出0xFF的排查與解決)
Nucleo-H753ZI 上SPI 從機打開 DMA 準備發(fā)數(shù)據(jù)結(jié)果主機那邊一讀回來四個字節(jié)全是 0xFF 0xFF 0xFF 0xFF。這不是個例STM32 社區(qū)里隔三差五就有人貼出這個問題。別急著懷疑線接錯了先把 MISO 為什么會一直是高電平這件事想明白再往下查。先說結(jié)論SPI 從機的 MISO 在空閑狀態(tài)下就是高電平主機讀到 0xFF 意味著“這條線上沒有有效數(shù)據(jù)”。連續(xù) 0xFF 說明從機已經(jīng)被選中、SCK 時鐘也進來了但發(fā)送路徑上根本沒數(shù)據(jù)可移出去。問題基本鎖定在三個方向DMA 配置沒有真正生效、H7 平臺特有的傳輸長度設置沒做、或者發(fā)送緩沖區(qū)放到了 DMA 夠不到的內(nèi)存區(qū)域。這篇文章把原理、配置和排錯流程完整講一遍照著做基本一次能通。1. 先搞清楚 0xFF 是怎么來的1.1 從機 MISO 的空閑狀態(tài)SPI 是同步全雙工協(xié)議主機提供 SCK 時鐘從機在時鐘邊沿把數(shù)據(jù)一位一位移出到 MISO。站在主機側(cè)的視角MISO 上有兩種情況都會表現(xiàn)為高電平第一種是 NSS 為高、從機沒有被選中。此時從機的 MISO 引腳是高阻態(tài)主機側(cè)如果沒有下拉電阻線上被上拉或者空載讀數(shù)自然就是 1。第二種是從機被選中了SCK 也在跑但 TX 移位寄存器里沒有有效數(shù)據(jù)。此時 H7 的 SPI 外設會保持 MISO 的默認輸出電平主機讀到的還是 0xFF。所以看到 0xFF不要去懷疑“數(shù)據(jù)被干擾成 FF 了”它更可能是“從機壓根沒發(fā)數(shù)據(jù)”。1.2 TX 路徑上的數(shù)據(jù)是怎么流動的從機發(fā)送不是主動把數(shù)據(jù)推出去而是配合主機的時鐘往外供數(shù)據(jù)。主機來一個字節(jié)的時鐘從機把 TX FIFO 的頭一個字節(jié)搬進移位寄存器再從 MISO 一位一位移出去。這里有個關(guān)鍵點SPI 外設只有在 TX FIFO 里有數(shù)據(jù)時才會啟動內(nèi)部發(fā)送邏輯。如果你沒開 DMA、沒開 TXE 中斷、也沒手動往發(fā)送寄存器寫數(shù)據(jù)TX FIFO 就是空的。主機來的每個字節(jié)時鐘從機都只能輸出空數(shù)據(jù)。H7 的 SPI 在這種情況下會置起 UDRUnderrun欠載標志MISO 輸出默認電平也就是 0xFF。1.3 先把 DMA 摘掉用輪詢做定位遇到這個問題第一步不是去調(diào) DMA 參數(shù)而是把 DMA 整個摘掉用最笨的阻塞式發(fā)送驗證鏈路。uint8_t tx_buf[4] {0xA5, 0x5A, 0x01