3.21. SPI 基礎

SPI(Serial Peripheral Interface,序列周邊介面)是一種同步序列匯流排,設計用於同一塊電路板上的一個控制器與一個或多個周邊裝置之間的短距離高速連結。它是 SD 卡、顯示器、快閃記憶體、ADC、DAC 以及各式各樣感測器的標準介面。

UART 沒有共用時脈,必須從資料線本身還原出時序;而 SPI 則在資料線旁邊另外拉一條時脈線。控制器可以用任意速率驅動時脈,匯流排上其他每個裝置都會與該時脈同步取樣資料。不需要猜測鮑率,也沒有訊框開銷——只有時脈邊緣與位元。

3.21.1. 四條線

全雙工的 SPI 匯流排有四條線:

  • SCK(序列時脈)。由控制器驅動。每個位元都在這個訊號的某個邊緣被時控移入或移出。

  • MOSI(控制器輸出、周邊輸入)。控制器的輸出線;周邊裝置從這條線上取樣位元。

  • MISO(控制器輸入、周邊輸出)。周邊裝置的輸出線;控制器從這條線上取樣位元。

  • CS(晶片選擇,chip select),有時稱為 SS(周邊選擇)。每個周邊裝置各有一條獨立的線。控制器將 CS 拉低以開始一次交易,再拉高以結束交易;任何 CS 未被致能(deasserted)的周邊裝置都會完全忽略匯流排,並停止驅動自己的 MISO 輸出。

Four signal traces stacked: CS at top, SCK below it, then MOSI and MISO. CS starts high (idle), drops low to begin the transaction, then SCK clocks out eight pulses while MOSI and MISO carry one byte of data each, then CS returns high.

一個 SPI 位元組:CS 變為低電位以選擇周邊裝置,SCK 時控八個位元,MOSI 與 MISO 各以相反方向傳送一個位元組。

每個時脈邊緣都會同時在兩個方向各移動一個位元。單一個 SCK 脈衝會同時在 MOSI 上送出一個位元,並在 MISO 上接收一個位元——SPI 在線路層級上是全雙工的。軟體不一定要同時使用兩個方向:只寫與只讀的交易都很常見,未使用的線路要嘛被忽略,要嘛維持高電位。

3.21.2. 時脈極性與相位

兩個設定位元決定了資料究竟在哪個時脈邊緣移動:

  • 時脈極性polarity,有時稱為 CPOL)——SCK 的閒置狀態。0 表示時脈閒置於低電位、脈衝為高電位;1 表示時脈閒置於高電位、脈衝為低電位。

  • 時脈相位phase,有時稱為 CPHA)——在哪個邊緣取樣資料。0 在每個時脈脈衝的第一個邊緣(前緣)取樣;1 在第二個邊緣(後緣)取樣。

這兩者合起來構成四種模式,慣例上稱為 Mode 0 到 Mode 3。Mode 0(polarity=0, phase=0)是最常見的一種,也是面對未知裝置時安全的預設值。

關鍵的規則是兩端必須對模式達成一致。即使時脈線與資料線都接線正確,模式不符仍會得到亂碼資料;如果某個裝置在第一次交易就回傳無意義的內容,模式是第一個該檢查的項目。

3.21.3. 多個周邊裝置

只要每個周邊裝置都有自己一條由控制器驅動的 CS 線,多個周邊裝置就可以共用同一組 SCK、MOSI 與 MISO 線:

  • 所有周邊裝置看到的都是相同的時脈與資料,但每個都各自監看自己的 CS。當 CS 未被致能(高電位)時,周邊裝置會完全忽略 SCK 與 MOSI,並讓 MISO 處於高阻抗狀態,因此不會與其他裝置爭搶這條線。

  • 控制器一次只致能一條 CS,執行交易,然後解除致能 CS 以釋放匯流排。

一個只有單一硬體 SPI 區塊的微控制器,能夠對話的周邊裝置數量,取決於它有多少空閒的 GPIO 接腳可挪用來當 CS 線——匯流排本身並沒有定址機制。

3.21.4. 優點與缺點

SPI 的優點與缺點都源自於它的設計:

  • 快速。 在短軌跡上搭配簡單的電位轉換,可達到數十 MHz。SD 卡讀卡機與 SPI 顯示器都運用了這一點。

  • 線路層級上簡單。 沒有定址、沒有確認、沒有特殊的起始/停止條件——只有與時脈同步的位元在線上傳輸。

  • 耗用接腳。 三條共用線,加上每個周邊裝置一條 CS。一塊有五個 SPI 裝置的電路板會用掉八支接腳(三加五)。

  • 短距離。 SPI 假設邊緣乾淨且快速,這意味著要在同一塊電路板上使用短軌跡。對於較長的連結,I2C 或某種具訊框的匯流排會是更合適的選擇。