1. SPI物理層
SPI通訊需要使用4條線:3條總線和1條片選 。
SPI遵循主從模式,3條總線分別是SCK、MOSI和MISO,片選線為nSS(低電平有效),SPI協議適用於一主多從的工作場景:
(1) nSS(Slave Select):片選信號線,用於選中SPI從設備。每個從設備獨立擁有這條nSS信號線,占據主機的一個引腳。設備的其他總線是並聯到SPI主機的,即無論多少個從設備,都共同使用這3條總線。當從設備上的nSS引腳被置拉低時表明該從設備被主機選中。
(2) SCK(Serial Clock):時鍾信號線,通訊數據同步用。時鍾信號由通訊主機產生,它決定了SPI的通訊速率。我們的主設備能夠控制時鍾,因為我們的SPI通信並不像UART或者IIC通信那樣有專門的通信周期,有專門的通信起始信號,有專門的通信結束信號;所以我們的SPI協議能夠通過控制時鍾信號線,當沒有數據交流的時候我們的時鍾線要么是保持高電平要么是保持低電平。
(3) MOSI(Master Ouput Slave Input):主機(數據)輸出/從設備(數據)輸入引腳,即這條信號線上傳輸從主機到從機的數據。
(4) MISO(Master Input Slave Ouput):主機(數據)輸入/從設備(數據)輸出引腳,即這條信號線上傳輸從機從到主機的數據主從機通過兩條信號線來傳輸數據,那么自然是全雙工通訊的了。之前的I2C通訊,數據只在一條SDA線上傳輸,主從機數據交互只能采用半雙工。
SPI是[單主設備( single-master )]通信協議,這意味着總線中的只有一支中心設備能發起通信。當SPI主設備想讀/寫[從設備]時,它首先拉低[從設備]對應的nSS線(nSS是低電平有效),接着開始發送工作脈沖到時鍾線上,在相應的脈沖時間上,[主設備]把信號發到MOSI實現"寫",同時可對MISO采樣而實現"讀"。
2. SPI協議層
如上為SPI通訊時序圖,nSS、SCK、MOSI信號均由主機產生,MISO信號由從機產生。在nSS為低電平的前提下,MOSI和MISO信號才有效,在每個時鍾周期MOSI和MISO傳輸一位數據。跟I2C通訊類似,SPI通訊也需要通訊的起始/結束信號,有效數據和同步時鍾。
2.1 通訊的起始/結束信號
圖中的nSS信號由高電平變為低電平即為SPI通訊的起始信號,反過來,nSS信號由低電平變為高電平即為SPI通訊的結束信號。這個可比I2C簡單得多吧。當從機檢測到自身的nSS引腳被拉低時就知道自己被主機選中,准備和主機進行通訊。
2.2 有效數據的采集
SPI通訊的數據采集是個相對復雜的環節,先不說其他,以上圖為例:
a、圖中紅色框框即為有效數據被采集的時間點,"CPOL = 0"所在的脈沖信號表示的是用於進行數據同步的SCK,MOSI和MISO線上的數據在每個SCK時鍾周期傳輸一位數據,注意,數據的輸入/輸出是可以同時進行的。
b、由圖可見,在SCK為奇數邊沿(在這里該邊沿為下降沿)時,數據得到有效采樣,也就是說,在這個時刻,MISO和MOSI的數據有效,高電平表示數據1,低電平表示數據0,在其它時刻數據並無效,可以理解為為下一次MISO和MOSI的數據傳輸做准備。
c、數據在傳輸中,高位在先還是低位在先,SPI協議並無明確規定,但是數據要在主從機中正確傳輸,自然雙方要先約定好,一般會采用高位在先(MSB)方式傳輸。
d、這里需要再提及的概念是時鍾極性(CPOL)和時鍾相位(CPHA)。
時鍾極性(CPOL)指通訊設備處於空閑狀態(SPI開始通訊前、nSS線無效)時,SCK的狀態。
CPOL = 0:SCK在空閑時為低電平
CPOL = 1:SCK在空閑時為高電平
時鍾相位(CPHA)指數據的采樣時刻位於SCK的偶數邊沿采樣還是奇數邊沿采樣。
CPHA = 0:在SCK的奇數邊沿采樣
CPHA = 1:在SCK的偶數邊沿采樣
那么這樣說來,SPI的采樣時刻並非由上升沿/下降沿決定的。注意的是,在數據采樣時刻,MOSI和MOSI的電平為有效電平,數據不能在這個時刻進行切換。在非采樣時刻MOSI和MISO上的信號才能切換。
完整的時序圖如下:
所以說,SPI有4中工作模式:
它們的區別是定義了在時鍾脈沖的哪條邊沿轉換(toggles)輸出信號,哪條邊沿采樣輸入信號,還有時鍾脈沖的穩定電平值(就是時鍾信號無效時是高還是低)。每種模式由一對參數刻畫,它們稱為時鍾極(clock polarity)CPOL與時鍾期(clock phase)CPHA。
[主從設備]必須使用相同的工作參數——SCLK、CPOL 和 CPHA,才能正常工作。如果有多個[從設備],並且它們使用了不同的工作參數,那么[主設備]必須在讀寫不同[從設備]間重新配置這些參數。但要注意的是,由於主設備的SDO連接從設備的SDI,從設備的SDO連接主設備的SDI,從設備SDI接收的數據是主設備的SDO發送過來的,主設備SDI接收的數據是從設備SDO發送過來的,所以主設備這邊SPI時鍾極性的配置(即SDO的配置)跟從設備的SDI接收數據的極性是相反的,跟從設備SDO發送數據的極性是相同的。
下面這段話是Sychip Wlan8100 Module Spec上說的,充分說明了時鍾極性是如何配置的:
The 81xx module will always input data bits at the rising edge of the clock, and the host will always output data bits on the falling edge of the clock.
意思是:主設備在時鍾的下降沿發送數據,從設備在時鍾的上升沿接收數據。因此主設備這邊SPI時鍾極性應該配置為下降沿有效。
又如,下面這段話是摘自LCD Driver IC SSD1289:
SDI is shifted into 8-bit shift register on every rising edge of SCK in the order of data bit 7, data bit 6 …… data bit 0.
意思是:從設備SSD1289在時鍾的上升沿接收數據,而且是按照從高位到地位的順序接收數據的。因此主設備的SPI時鍾極性同樣應該配置為下降沿有效。
時鍾極性和相位配置正確后,數據才能夠被准確的發送和接收, 因此應該對照從設備的SPI接口時序或者Spec文檔說明來正確配置主設備的時鍾。
SPI不規定最大傳輸速率,沒有地址方案;SPI也沒規定通信應答機制,沒有規定流控制規則。事實上,SPI[主設備]甚至並不知道指定的[從設備]是否存在。這些通信控制都得通過SPI協議以外自行實現。