SPI匯流排協議概述
一.概述
SPI(serial peripheral interface)是一種同步序列通訊協議,由一個主裝置和一個或多個從裝置組成,主裝置啟動與從裝置的同步通訊,從而完成資料的交換。SPI是一種高速全雙工同步通訊匯流排,標準的SPI僅僅使用4個引腳,主要應用在 EEPROM, Flash, 實時時鐘(RTC), 數模轉換器(ADC), 數字訊號處理器(DSP) 以及數字訊號解碼器之間。有跡象表明,SPI匯流排首次推出是在1979年,Motorola公司將SPI匯流排整合在他們第一支改自68000微處理器的微控制器晶片上。由於在晶片中只佔用四根管腳 (Pin) 用來控制以及資料傳輸, 節約了晶片的 pin 數目, 同時為 PCB 在佈局上節省了空間。 正是出於這種簡單易用的特性, 現在越來越多的晶片上都集成了 SPI技術。
二.特點
1. 採用主-從模式(Master-Slave) 的控制方式
SPI 規定了兩個 SPI 裝置之間通訊必須由主裝置 (Master) 來控制次裝置 (Slave). 一個 Master 裝置可以通過提供 Clock 以及對 Slave 裝置進行片選 (Slave Select) 來控制多個 Slave 裝置, SPI 協議還規定 Slave 裝置的 Clock 由 Master 裝置通過 SCK 管腳提供給 Slave 裝置, Slave 裝置本身不能產生或控制 Clock, 沒有 Clock 則 Slave 裝置不能正常工作.
2. 採用同步方式(Synchronous)傳輸資料
CPOL:clock polarity 時鐘的極性;表示 SPI 在空閒時, 時鐘訊號是高電平還是低電平. 若 CPOL 被設為 1, 那麼該裝置在空閒時 SCK 管腳下的時鐘訊號為高電平. 當 CPOL 被設為 0 時則正好相反.
CPHA:clock phase 時鐘的相位;表示 SPI 裝置是在 SCK 管腳上的時鐘訊號變為上升沿時觸發資料取樣, 還是在時鐘訊號變為下降沿時觸發資料取樣. 若 CPHA 被設定為 1, 則 SPI 裝置在時鐘訊號變為下降沿時觸發資料取樣, 在上升沿時傳送資料. 當 CPHA 被設為 0 時也正好相反.
Master 裝置會根據將要交換的資料來產生相應的時鐘脈衝(Clock Pulse), 時鐘脈衝組成了時鐘訊號(Clock Signal) , 時鐘訊號通過時鐘極性 (CPOL) 和 時鐘相位 (CPHA) 控制著兩個 SPI 裝置間何時資料交換以及何時對接收到的資料進行取樣, 來保證資料在兩個裝置之間是同步傳輸的.
3. 資料交換(Data Exchanges)
SPI 裝置間的資料傳輸之所以又被稱為資料交換, 是因為 SPI 協議規定一個 SPI 裝置不能在資料通訊過程中僅僅只充當一個 "傳送者(Transmitter)" 或者 "接收者(Receiver)". 在每個 Clock 週期內, SPI 裝置都會發送並接收一個 bit 大小的資料, 相當於該裝置有一個 bit 大小的資料被交換了.
一個 Slave 裝置要想能夠接收到 Master 發過來的控制訊號, 必須在此之前能夠被 Master 裝置進行訪問 (Access). 所以, Master 裝置必須首先通過 SS/CS pin 對 Slave 裝置進行片選, 把想要訪問的 Slave 裝置選上.
在資料傳輸的過程中, 每次接收到的資料必須在下一次資料傳輸之前被取樣. 如果之前接收到的資料沒有被讀取, 那麼這些已經接收完成的資料將有可能會被丟棄, 導致 SPI 物理模組最終失效. 因此, 在程式中一般都會在 SPI 傳輸完資料後, 去讀取 SPI 裝置裡的資料, 即使這些資料(Dummy Data)在我們的程式裡是無用的.
三.工作機制
1.概述
上圖只是對 SPI 裝置間通訊的一個簡單的描述, 下面就來解釋一下圖中所示的幾個元件(Module):
SSPBUF, Synchronous Serial Port Buffer, 泛指 SPI 裝置裡面的內部緩衝區, 一般在物理上是以 FIFO 的形式, 儲存傳輸過程中的臨時資料;
SSPSR, Synchronous Serial Port Register, 泛指 SPI 裝置裡面的移位暫存器(Shift Regitser), 它的作用是根據設定好的資料位寬(bit-width) 把資料移入或者移出 SSPBUF;
Controller, 泛指 SPI 裝置裡面的控制暫存器, 可以通過配置它們來設定 SPI 匯流排的傳輸模式.
通常情況下, 我們只需要對上圖所描述的四個管腳(pin) 進行程式設計即可控制整個 SPI 裝置之間的資料通訊:
SCK, Serial Clock, 主要的作用是 Master 裝置往 Slave 裝置傳輸時鐘訊號, 控制資料交換的時機以及速率;
SS/CS, Slave Select/Chip Select, 用於 Master 裝置片選 Slave 裝置, 使被選中的 Slave 裝置能夠被 Master 裝置所訪問;
SDO/MOSI, Serial Data Output/Master Out Slave In, 在 Master 上面也被稱為 Tx-Channel, 作為資料的出口, 主要用於 SPI 裝置傳送資料;
SDI/MISO, Serial Data Input/Master In Slave Out, 在 Master 上面也被稱為 Rx-Channel, 作為資料的入口, 主要用於SPI 裝置接收資料;
SPI 裝置在進行通訊的過程中, Master 裝置和 Slave 裝置之間會產生一個數據鏈路迴環(Data Loop), 就像上圖所畫的那樣, 通過 SDO 和 SDI 管腳, SSPSR 控制資料移入移出 SSPBUF, Controller 確定 SPI 匯流排的通訊模式, SCK 傳輸時鐘訊號。
2. Timing.
上圖通過 Master 裝置與 Slave 裝置之間交換1 Byte 資料來說明 SPI 協議的工作機制.
上圖裡的 "Mode 1, 1" 說明了本例所使用的 SPI 資料傳輸模式被設定成 CPOL = 1, CPHA = 1. 這樣, 在一個 Clock 週期內, 每個單獨的 SPI 裝置都能以全雙工(Full-Duplex) 的方式, 同時傳送和接收 1 bit 資料, 即相當於交換了 1 bit 大小的資料.對於主裝置,資料輸出在時鐘下降沿,資料讀入在時鐘上升沿; 如果 SPI 匯流排的 Channel-Width 被設定成 Byte, 表示 SPI 總線上每次資料傳輸的最小單位為 Byte, 那麼掛載在該 SPI 匯流排的裝置每次資料傳輸的過程至少需要 8 個 Clock 週期(忽略裝置的物理延遲). 因此, SPI 匯流排的頻率越快, Clock 週期越短, 則 SPI 裝置間資料交換的速率就越快.
3. SSPSR
SSPSR 是 SPI 裝置內部的移位暫存器(Shift Register). 它的主要作用是根據 SPI 時鐘訊號狀態, 往 SSPBUF 裡移入或者移出資料, 每次移動的資料大小由 Bus-Width 以及 Channel-Width 所決定.
Bus-Width 的作用是指定地址匯流排到 Master 裝置之間資料傳輸的單位.
例如, 我們想要往 Master 裝置裡面的 SSPBUF 寫入 16 Byte 大小的資料: 首先, 給 Master 裝置的配置暫存器設定 Bus-Width 為 Byte; 然後往 Master 裝置的 Tx-Data 移位暫存器在地址匯流排的入口寫入資料, 每次寫入 1 Byte 大小的資料(使用 writeb 函式); 寫完 1 Byte 資料之後, Master 裝置裡面的 Tx-Data 移位暫存器會自動把從地址匯流排傳來的1 Byte 資料移入 SSPBUF 裡; 上述動作一共需要重複執行 16 次.
Channel-Width 的作用是指定 Master 裝置與 Slave 裝置之間資料傳輸的單位. 與 Bus-Width 相似, Master 裝置內部的移位暫存器會依據 Channel-Width 自動地把資料從 Master-SSPBUF 裡通過 Master-SDO 管腳搬運到 Slave 裝置裡的 Slave-SDI 引腳, Slave-SSPSR 再把每次接收的資料移入 Slave-SSPBUF裡.
通常情況下, Bus-Width 總是會大於或等於 Channel-Width, 這樣能保證不會出現因 Master 與 Slave 之間資料交換的頻率比地址匯流排與 Master 之間的資料交換頻率要快, 導致 SSPBUF 裡面存放的資料為無效資料這樣的情況.
4. SSPBUF.
在每個時鐘週期內, Master 與 Slave 之間交換的資料其實都是 SPI 內部移位暫存器從 SSPBUF 裡面拷貝的. 我們可以通過往 SSPBUF 對應的暫存器 (Tx-Data / Rx-Data register) 裡讀寫資料, 間接地操控 SPI 裝置內部的 SSPBUF.
例如, 在傳送資料之前, 我們應該先往 Master 的 Tx-Data 暫存器寫入將要傳送出去的資料, 這些資料會被 Master-SSPSR 移位暫存器根據 Bus-Width 自動移入 Master-SSPBUF 裡, 然後這些資料又會被 Master-SSPSR 根據 Channel-Width 從 Master-SSPBUF 中移出, 通過 Master-SDO 管腳傳給 Slave-SDI 管腳, Slave-SSPSR 則把從 Slave-SDI 接收到的資料移入 Slave-SSPBUF 裡. 與此同時, Slave-SSPBUF 裡面的資料根據每次接收資料的大小(Channel-Width), 通過 Slave-SDO 發往 Master-SDI, Master-SSPSR 再把從 Master-SDI 接收的資料移入 Master-SSPBUF.在單次資料傳輸完成之後, 使用者程式可以通過從 Master 裝置的 Rx-Data 暫存器讀取 Master 裝置資料交換得到的資料.
5. Controller.
Master 裝置裡面的 Controller 主要通過時鐘訊號(Clock Signal)以及片選訊號(Slave Select Signal)來控制 Slave 裝置. Slave 裝置會一直等待, 直到接收到 Master 裝置發過來的片選訊號, 然後根據時鐘訊號來工作.
Master 裝置的片選操作必須由程式所實現. 例如: 由程式把 SS/CS 管腳的時鐘訊號拉低電平, 完成 SPI 裝置資料通訊的前期工作; 當程式想讓 SPI 裝置結束資料通訊時, 再把 SS/CS 管腳上的時鐘訊號拉高電平.
四.傳輸時序
SPI介面有四種不同的資料傳輸時序,取決於時鐘極性(CPOL)和時鐘相位(CPHA)的組合。時鐘相位設定讀取資料和傳送資料的時鐘沿。主機和從機發送資料是同時完成的,接收資料也是同時完成的。
時鐘極性CPOL:SPI在空閒時,時鐘訊號是高電平還是低電平,即SCLK傳送8 bit資料之前和之後的狀態。CPOL=0,空閒電平為低電平,CPOL=1,空閒電平為高電平。
時鐘相位CPHA:資料取樣(對於主機來說就是接收資料)在時鐘的第幾個邊沿。CPHA=0,在每個週期的第一個時鐘沿取樣,CPHA=1,在每個週期的第二個時鐘沿取樣。
Bit1為MSB,Bit8為LSB。假設CPOL=0,CPHA=0。在SCK的第一個時鐘週期,在時鐘的前沿取樣資料(上升沿),在時鐘的後沿輸出資料。先看主器件,主器件的輸出口(MOSI)輸出資料bit1,在時鐘的前沿被從器件取樣,那主器件是何時輸出bit1的呢?bit1的輸出時刻實際上在SCK訊號有效以前,比SCK的上升沿還要早半個時鐘週期,bit1的輸出時刻與SSEL訊號沒有關係。再來看從器件,主器件的輸入口MISO同樣是在時鐘的前沿取樣從器件輸出的bit1的,那從器件又是在何時輸出bit1的呢?從器件實在SSEL訊號有效後,立即輸出bit1,儘管此時SCK訊號還沒有生效。
參考連結:https://blog.csdn.net/ivy_reny/article/details/78189058