SPI協議詳解
摘要
SPI(Serial Peripheral Interface)是一種同步序列通訊協議,用於微控制器(MCU)和它們的外圍裝置(外設IC)之間或兩個微控制器(MCU)之間的通訊。
SPI通訊是全雙工的,意味著它可以同時傳送和接收資料。,以其全雙工、高速率和簡單硬體結構優於UART。
SPI通訊通常需要四根線:SCLK(時鐘線)、CS/SS(片選線)、MOSI(主裝置資料輸出線)、MISO(主裝置資料輸入線),透過時鐘極性和相位配置實現不同模式的通訊。
SPI支援多從機模式,如多NSS或菊花鏈連線,但缺乏硬體級別的錯誤檢查協議,並且通常僅支援一個主裝置。在STM32等微控制器中,透過HAL庫可以方便地實現SPI程式設計。
串列埠
UART是通用序列非同步通訊協議。
因為UART沒有時鐘訊號,無法控制何時傳送資料,也無法保證雙發按照完全相同的速度接收資料。因此,雙方以不同的速度進行資料接收和傳送,就會出現問題。
如果要解決這個問題,UART為每個位元組新增額外的起始位和停止位,以幫助接收器在資料到達時進行同步;
雙方還必須事先就傳輸速度達成共識(設定相同的波特率,例如每秒9600位)。
傳輸速率如果有微小差異不是問題,因為接收器會在每個位元組的開頭重新同步。相應的協議如下圖所示;
如果您注意到上圖中的 11801010
不等於0x53
,這是一個細節。
串列埠協議通常會首先傳送最低有效位,因此最小位在最左邊 LSB
。低四位位元組實際上是0011=0x3
,高四位位元組是0101=0x5
。
非同步序列工作得很好,但是在每個位元組傳送的時候都需要額外的起始位和停止位以及在傳送和接收資料所需的複雜硬體方面都有很多開銷。
不難發現,如果接收端和傳送端設定的速度都不一致,那麼接收到的資料將是垃圾(亂碼)。
下面開始講一下SPI協議,會有哪些優點。
SPI通訊協議
於是我們想有沒有更好一點的序列通訊方式:相比較於 UART
,SPI
的工作方式略有不同。
SPI
是一個同步的資料匯流排,也就是說它是用單獨的資料線和一個單獨的時鐘訊號來保證傳送端和接收端的完美同步。
時鐘是一個振盪訊號,它告訴接收端在確切的時機對資料線上的訊號進行取樣。
產生時鐘的一側稱為主機,另一側稱為從機。總是隻有一個主機(一般來說可以是微控制器/MCU),但是可以有多個從機(後面詳細介紹);
資料的採集時機可能是時鐘訊號的上升沿(從低到高)或下降沿(從高到低),具體要看對SPI的配置;
整體的傳輸大概可以分為以下幾個過程:
-
主機先將
NSS
訊號拉低,這樣保證開始接收資料; -
當接收端檢測到時鐘的邊沿訊號時,它將立即讀取資料線上的訊號,這樣就得到了一位資料(1 bit);
由於時鐘是隨資料一起傳送的,因此指定資料的傳輸速度並不重要,儘管裝置將具有可以執行的最高速度(稍後我們將討論選擇合適的時鐘邊沿和速度)。 -
主機傳送到從機時:主機產生相應的時鐘訊號,然後資料一位一位地將從
MOSI
訊號線上進行傳送到從機; -
主機接收從機資料:如果從機需要將資料傳送回主機,則主機將繼續生成預定數量的時鐘訊號,並且從機會將資料透過 MIS0 訊號線傳送;
具體如下圖所示;
注意,SPI是“全雙工”(具有單獨的傳送和接收線路),因此可以在同一時間傳送和接收資料,另外SPI的接收硬體可以是一個簡單的移位暫存器。這比非同步序列通訊所需的完整UART要簡單得多,並且更加便宜;
資料在傳輸中,高位在先還是低位在先,SPI協議並無明確規定,但是資料要在主從機中正確傳輸,自然雙方要先約定好,一般會採用高位在先(MSB)方式傳輸。
圖中可能會產生歧義,關於0x53,這裡要表達的意思是右邊到左邊是位元組高位到低位。
SPI特性
SPI匯流排包括4條邏輯線,定義如下:
-
MISO:
Master input slave output
主機輸入,從機輸出(資料來自從機); -
MOSl:
Master output slave input
主機輸出,從機輸入(資料來自主機); -
SCLK:
Seria1 clock
序列時鐘訊號,由主機產生髮送給從機; -
SS:
Slave select
片選訊號,由主機傳送,以控制與哪個從機通訊,通常是低電平有效。
其他製造商可能會遵循其他命名規則,但是最終他們指的相同的含義。以下是一些常用術語:
-
MISO也可以是
SIMO
,DOUT
,DO
,SDO
或SO
(在主機端); -
MOSI也可以是
SOMI
,DIN
,DI
,SDI
或SI
(在主機端); -
NSS也可以是
CE
,CS
或SSEL
; -
SCLK也可以是
SCK
;
本文將按照以下命名進行講解 [MISO,MOSI,SCK,NSS
]
下圖顯示了單個主機和單個從機,之間的典型SPI連線。
時脈頻率
SPI匯流排上的主機必須在通訊開始時候配置並生成相應的時鐘訊號。在每個SPI時鐘週期內,都會發生全雙工資料傳輸。
主機在 MOSI
線上傳送一位資料,從機讀取它,而從機在 MIS0
線上傳送一位資料,主機讀取它。
就算只進行單向的資料傳輸,也要保持這樣的順序。這就意味著無論接收任何資料,必須實際傳送一些東西!在這種情況下,我們稱其為虛擬資料;
從理論上講,只要實際可行,時鐘速率就可以是您想要的任何速率,當然這個速率受限於每個系統能提供多大的系統時脈頻率,以及最大的SPI傳輸速率。
時鐘極性 CKP/Clock Polarity
除了配置序列時鐘速率(頻率)外,SPI主裝置還需要配置時鐘極性。
根據硬體製造商的命名規則不同,時鐘極性通常寫為CKP或CPOL。時鐘極性和相位共同決定讀取資料的方式,比如訊號上升沿讀取資料還是訊號下降沿讀取資料;
CKP可以配置為1或0。這意味著您可以根據需要將時鐘的預設狀態(IDLE)設定為高或低。極性反轉可以透過簡單的邏輯逆變器實現。您必須參考裝置的資料手冊才能正確設定CKP和CKE。
-
CKP = 0
:時鐘空閒IDLE
為低電平0
; -
CKP = 1
:時鐘空閒IDLE
為高電平1
;
時鐘相位 CKE /Clock Phase(Edge)
除配置序列時鐘速率和極性外,SPI主裝置還應配置時鐘相位(或邊沿)。根據硬體製造商的不同,時鐘相位通常寫為CKE或CPHA;
顧名思義,時鐘相位/邊沿,也就是採集資料時是在時鐘訊號的具體相位或者邊沿;
-
CKE = 0
:在時鐘訊號SCK
的第一個跳變沿取樣; -
CKE = 1
:在時鐘訊號SCK
的第二個跳變沿取樣;
時鐘配置總結
綜上幾種情況,下圖總結了所有時鐘配置組合,並突出顯示了實際取樣資料的時刻;
其中黑色線為取樣資料的時刻;
藍色線為SCK時鐘訊號;
具體如下圖所示;
模式編號
SPI的時鐘極性和相位的配置通常稱為 SPI模式,所有可能的模式都遵循以下約定;具體如下表所示;
除此之外,我們還應該仔細檢查微控制器資料手冊中包含的模式表,以確保一切正常。
多從機模式
前面說到SPI匯流排必須有一個主機,可以有多個從機,那麼具體連線到SPI匯流排的方法有以下兩種:
第一種方法:多NSS
1.通常,每個從機都需要一條單獨的SS線。
2.如果要和特定的從機進行通訊,可以將相應的 NSS
訊號線拉低,並保持其他 NSS
訊號線的狀態為高電平;如果同時將兩個 NSS
訊號線拉低,則可能會出現亂碼,因為從機可能都試圖在同一條 MISO
線上傳輸資料,最終導致接收資料亂碼。
具體連線方式如下圖所示;
第二種方法:菊花鏈
在數字通訊世界中,在裝置訊號(匯流排訊號或中斷訊號)以序列的方式從一個裝置依次傳到下一個裝置,不斷迴圈直到資料到達目標裝置的方式被稱為菊花鏈。
1.菊花鏈的最大缺點是因為是訊號序列傳輸,所以一旦資料鏈路中的某裝置發生故障的時候,它下面優先順序較低的裝置就不可能得到服務了;
2.另一方面,距離主機越遠的從機,獲得服務的優先順序越低,所以需要安排好從機的優先順序,並且設定匯流排檢測器,如果某個從機超時,則對該從機進行短路,防止單個從機損壞造成整個鏈路崩潰的情況;
具體的連線如下圖所示;
其中紅線加粗為資料的流向;
所以最終的資料流向圖可以表示為:
SCK為時鐘訊號,8clks表示8個邊沿訊號;
其中D為資料,X為無效資料;
所以不難發現,菊花鏈模式充分使用了SPI其移位暫存器的功能,整個鏈充當通訊移位暫存器,每個從機在下一個時鐘週期將輸入資料複製到輸出。
SPI通訊的優缺點
SPI通訊的優勢
使SPI作為序列通訊介面脫穎而出的原因很多;
-
全雙工序列通訊;
-
高速資料傳輸速率;
-
簡單的軟體配置;
-
極其靈活的資料傳輸,不限於8位,它可以是任意大小的字;
-
非常簡單的硬體結構。從站不需要唯一地址(與12C不同)。從機使用主機時鐘,不需要精密時鐘振盪器/晶振(與UART不同)。不需要收發器(與CAN不同)。
SPI的缺點
沒有硬體從機應答訊號(主機可能在不知情的情況下無處傳送);
通常僅支援一個主裝置;
需要更多的引腳(與12C不同);
沒有定義硬體級別的錯誤檢查協議;
與RS-232和CAN匯流排相比,只能支援非常短的距離;
程式設計實現
下面是透過STM32的cubemx自動生成的HAL庫程式碼,比較簡單,擷取了其中一部分,具體如下;
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER; //主機模式
hspi1.Init.Direction = SPI_DIRECTION_2LINES; //全雙工
hspi1.Init.DataSize = SPI_DATASIZE_8BIT; //資料位為8位
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; //CPOL=0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; //CPHA為資料線的第一個變化沿
hspi1.Init.NSS = SPI_NSS_SOFT; //軟體控制NSS
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;//2分頻,32M/2=16MHz
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; //最高位先傳送
hspi1.Init.TIMode = SPI_TIMODE_DISABLE; //TIMODE模式關閉
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;//CRC關閉
hspi1.Init.CRCPolynomial = 10; //預設值,無效
if (HAL_SPI_Init(&hspi1) != HAL_OK) //初始化
{
_Error_Handler(__FILE__, __LINE__);
}
}
//傳送資料
HAL_StatusTypeDef
HAL_SPI_Transmit(SPI_HandleTypeDef *hspi,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
//接收資料
HAL_StatusTypeDef
HAL_SPI_Receive(SPI_HandleTypeDef *hspi,
uint8_t *pData,
uint16_t Size,
uint32_t Timeout);
SPI通訊的相關特點
SPI通訊的主要特點
- 全雙工通訊:可以同時傳送和接收資料。
- 高速資料傳輸:比I2C等其他序列通訊協議快。
- 主從模式:有一個主裝置(Master)和多個從裝置(Slave)。
- 同步通訊:使用時鐘訊號(SCLK)來同步資料傳輸。
- 資料幀格式:通常為8位或16位,可以配置為MSB(高位在前)或LSB(低位在前)。
- 連線簡單:只需要4根線:SCLK、MOSI(主裝置資料輸出,從裝置資料輸入線)、MISO(主裝置資料輸入,從裝置資料輸出線)、CS(片選訊號線)。
SPI的通訊特性
- 裝置選擇:SPI是單主裝置通訊協議,主裝置透過拉低CS/SS訊號來選擇從裝置進行通訊。
- 裝置時鐘:SPI的時鐘訊號由主裝置產生,資料傳輸速率取決於時脈頻率,且具有可程式設計性。
- 四種模式:SPI有四種工作模式,由CPOL(時鐘極性)和CPHA(時鐘相位)定義,這決定了資料取樣和傳送的時鐘邊沿。
SPI的資料傳輸方式特點
- 無起始位和停止位,資料位連續傳輸,提高了傳輸效率。
- 支援更高的資料傳輸速率,通常能達到甚至超過10M/bps。
- 靈活的資料傳輸寬度,不限於8位,可以是任意大小的字。
- 簡單的硬體結構,易於實現。
然而,SPI也有一些侷限性:
- 需要更多的訊號線,相比I2C和UART使用四根訊號線。
- 沒有像I2C那樣的從裝置定址系統,也沒有硬體從機應答訊號。
- 無法確認資料是否已成功接收,沒有錯誤檢查機制如UART中的奇偶校驗位。
SPI的測試標準
SPI通訊的測試通常遵循一些通用的電氣和協議標準,以確保通訊的可靠性和相容性。雖然沒有一個統一的“SPI測試標準”,但是一些通用的測試準則包括:
- 時脈頻率測試:驗證SPI通訊在不同時脈頻率下的效能。
- 資料完整性測試:確保資料在傳輸過程中沒有錯誤。
- 通訊距離測試:測試SPI匯流排在不同長度下的訊號完整性。
- 負載測試:測試SPI匯流排在連線多個從裝置時的效能。
- 噪聲和抗干擾測試:評估SPI匯流排對電磁干擾的抵抗能力。
- 電源穩定性測試:確保SPI匯流排在不同電源條件下的穩定性。
SPI的板級測試
SPI的板級測試步驟
板級測試通常包括以下步驟:
- 硬體連線:確保SPI匯流排上的所有裝置正確連線。
- 訊號完整性測試:使用示波器等工具測試SCLK、MOSI、MISO線上的訊號質量。
- 通訊測試:透過軟體傳送資料並接收,驗證資料的正確性。
- 時序測試:確保資料傳輸的時序符合SPI協議要求。
- 故障模擬:模擬一些故障情況,如斷線、短路等,測試系統的容錯能力。
SPI的板級測試標準
SPI匯流排的測試標準主要圍繞訊號質量和訊號完整性展開,以確保通訊的可靠性和穩定性。以下是一些關鍵的測試原則和標準:
- 訊號幅度測試:確保SPI匯流排上訊號的幅度在規定的範圍內,滿足裝置的要求。這包括訊號的最大電平、最小電平、幅度以及高低電平的平均值等。
- 時序測試:測試訊號的時序是否滿足規定的時脈頻率和資料傳輸速率要求,保證訊號的傳輸速度和時鐘同步。時序測試包括SCLK頻率、資料的建立時間和保持時間等。
- 噪聲測試:檢查SPI匯流排上是否存在干擾訊號或電磁噪聲,確保訊號的清晰度和穩定性。
- 電平測試:測試包括幅值、過沖和下衝等。規格書一般會在首頁列出SPI通訊協議的電平範圍,結合邏輯低電平的最大值和高電平的最小值等標準,判斷所測資料是否滿足要求。
- 訊號完整性測試:包括訊號線的高低電平脈寬、頻率、建立時間和保持時間。測量時序時取訊號中間點,以避免引入不必要的誤差。
- 硬體和軟體配置:在硬體層面,SPI介面的配置包括時鐘極性(CPOL)、時鐘相位(CPHA)、主從模式、資料線的配置等 。軟體層面,需要編寫相應的驅動程式來控制SPI通訊,包括初始化配置和資料交換函式。
- 實際波形測試:使用示波器等裝置捕獲SPI通訊的實際波形,分析訊號的穩定性和時序準確性,確保與資料手冊中定義的標準一致。
在進行SPI通訊測試時,應嚴格參照產品資料手冊中的規格要求,包括訊號幅度、時序要求等,以確保SPI匯流排通訊的準確性和穩定性。
SPI協議的升級版,如Dual SPI、Quad SPI和QPI,透過增加資料線位數來提高資料傳輸效率,已經被許多Flash廠家支援。此外,SPI介面也支援多從機模式,可以透過多片選或菊花鏈方式連線多個從裝置,但需要注意訊號的優先順序和鏈路的穩定性。
總的來說,SPI是一種靈活、高效的通訊協議,適用於多種應用場景,但設計者需要根據具體的應用需求和裝置特性來選擇合適的SPI模式和配置。