簡單快速的匯流排協議——SPI

這是IC君的第24篇原創文章 (同步於微信公眾號 icstudy )

連續幾日大雪,IC君可以在家好好寫文章了。但是想想項目分配的活還是要準時高質量的完成,真是頭大啊。

之前有一篇文章介紹了簡單優雅的匯流排協議——I2C,這篇文章來聊一聊SPI協議。標準SPI協議比I2C協議就多了2根線,但它的協議生涯就起了翻天覆地的變化。

在網上搜了一下SPI的協議,基本上都是這樣寫的

SPI是串列外設介面(Serial Peripheral Interface)的縮寫。是 Motorola 公司推出的一 種同步串列介面技術,是一種高速的,全雙工,同步的通信匯流排。

高速和同步可以理解,全雙工是什麼鬼?

全雙工是指host(主設備)與外圍從設備之間的發送線和接受線各自獨立,發送數據的同時也能夠接收數據,兩者同步進行。

SPI協議主要用於短距離的通信系統中,特別是嵌入式系統,比如以下晶元:

存儲器:RAM,EEPROM,Flash等

數模轉換:A/D,D/A轉換器等

驅動介面:LED顯示驅動器、I/O介面晶元、UART收發器等。

2017年哪類晶元最缺貨啊?存儲器相關的啊!好吧,就選它了:SPI Flash。SPI Flash的本質就是使用SPI的協議去對Flash 存儲器進行各種讀寫操作。結合Flash有助於我們更好的理解SPI協議。

首先我們從國內最大的SPI NOR Flash公司兆易創新網站上下載一份datasheet(公司看到可以給我打廣告費了):

gigadevice.com/product/

datasheet對應的是一顆存儲容量為512M-bit SPI NOR Flash。

從datasheet第4頁的特徵介紹可以看出這顆產品支持標準單埠(1IO)、Dual SPI(2IO)、Quad SPI(4IO)模式的SPI協議。

從datasheet第5頁的封裝方式可以看到,晶元包含以下輸入輸出埠:SCLK, CS#, SI, SO, WP#, HOLD#

從datasheet第6頁的封裝方式可以看到對輸入輸出pin功能的描述:

其中CS#是一個晶元選擇信號,#表示這個pin輸入low的時候才會選中當前晶元,其它pin的輸入才可能有效;如果為high,則不選中該晶元,其它pin的輸入是完全無效的。

SCLK是一個輸入時鐘,是由外部的主器件輸入的;

SI是輸入信號,也是有外部的主器件輸入的;

SO是輸出信號,是由從器件輸出到主器件的;

通常標準SPI協議(1IO)只包含上面4個信號。對於這顆晶元中的Dual SPI (2IO)/Quad SPI(4IO) 模式還會用到另外2個pin:WP#和HOLD#。這裡我們可以簡單的認為WP#和HOLD#就是跟SI/SO地位平等的2個信號。

接著我們來看看這幾個輸入輸出信號之間的時序關係,如下圖所示:

晶元選擇信號CS#和時鐘信號SCLK有相對關係,用來確定輸入SCLK有效和無效。

tSLCH :定義了CS# go low 到第一個CLK go high的時間,只有主器件給的時間大於這個時間,輸入的CLK信號才算有效。這個參數在datasheet上要求最小是5n。如果主器件給的時間小於5n,則輸入的第一個CLK有可能無效,整個傳輸過程就有可能發生錯誤。

tDVCH和tSLCH:定義了輸入數據SI和輸入時鐘CLK之間的setup/hold 時間,這個跟我們數字電路裡面的DFF觸發器的setup/hold概念是相同的。這2個參數在datasheet上定義的最小值分別是2n/2n。

SPI協議的整個工作過程如下:

當CS# go low之後,輸入到從器件的CLK開始有效,全雙工的傳輸過程開始。主器件在信號線SI上輸入數據並被從器件讀取,從器件輸出數據到SO信號線並被主器件讀取。當CS# go high之後,從器件不再被選中,結束整個傳輸過程。

在傳輸的時候,不管是輸入輸出,通常都是以一個byte的最高有效位(MSB)開始傳輸:

比如主器件輸入bit7->6->5->4->3->2->1>0,從器件接受每個bit之後再向右shift,最終一個byte傳完之後,從器件看到的順序是bit[0:7]。從器件的輸出方式類似。

在datasheet的第9頁有這樣一句話:

SPI匯流排支持mode 0和3。這裡的mode 0和3是指時鐘模式,SPI協議通常有4種模式,可以通過CPOL(時鐘極性 Clock Polarity)和CPHA(時鐘相位 Clock Phase)來定義:

Mode0:CPOL=0,CPHA=0

Mode1:CPOL=0,CPHA=1

Mode2:CPOL=1,CPHA=0

Mode3:CPOL=1,CPHA=1

CPOL表示SPI匯流排空閑的時候時鐘的default狀態,對於SPI NOR Flash而言就是CS# go high之後 SCLK的值。

如果是Mode0, SCLK 為0;

如果是Mode3 ,SCLK 為1;

CPHA表示用第幾個邊沿去採樣數據,0表示第一個,1表示第二個:

對於Mode0而言,SCLK go high的時候去採樣數據,就像一個正沿的dffp;

對於Mode3 而言,因為SCLK初始值為1,而採樣沿為第二個,所以SCLK必須有1->0, 0->1的過程,同樣也是在SCLK上升沿採樣輸入的數據;

對於Mode1和Mode2,大家可以自行推斷匯流排空閑時CLK的初始值和採樣數據的時鐘沿。

不得不說SPI Flash的協議支持時鐘的模式是精心挑選的,都是CLK的上升沿採樣數據,沒有坑設計人員。如果所有的時鐘模式都支持,設計和驗證的工作量可能會大大增加。有時候datasheet上面的隨便一句話,對於我們設計人員可能要付出很大的面積和大量的驗證時間的代價,更悲劇的是這個功能95%的時間都用不到。

既然上升沿用來採樣輸出數據,那輸出數據只能是下降沿了:

對於SPI Flash而言,有一個參數tCLQV 用來定義在一定的負載電容下 Clock Low 到 Output Valid 的時間,實際應用中你必須大於這個時間來採樣數據。如果系統的時鐘頻率(Host 和SPI Flash都是用的這個頻率)比較慢,那你在下一個clk的上升沿就可以採集上一筆數據;如果系統的時鐘頻率比較快(百Mhz量級),只能在下一個時鐘的下降沿去採集數據。

一般SPI的協議比較快的時鐘頻率可能能到幾百Mhz,再快的IC君沒見過。相對於I2C的幾Mhz速度快了很多,速度越快要求驅動負載loading越輕。

這顆SPI Flash的時鐘最快頻率是104MHz,在最差的工藝角下模擬結果也要達到這個頻率。

舉一個讀的例子來解釋SPI協議在Flash中的應用,CS# go low, 利用SPI的協議輸入8 bit的讀command code 03H,再輸入想讀的地址(門牌號),Flash開始輸出內容(房間裡面有什麼東西),輸出一段時間後,主器件不再需要數據了, CS# go high 退出這個command。

SPI協議可以操作在主器件對單個或者多個從器件的條件下:

這個時候晶元選擇信號有多個,但同一個時間只能有一個SS# (CS#)有效,選中一個從器件,從器件的輸出信號MISO(SO)埠都是三態驅動的:

輸出高電平 "1";

輸出低電平 "0";

如果SS# (CS# 為high,不選中該從器件 )則輸出高阻態;

被選中的從器件驅動MISO埠輸出到主器件的時候,其它從器件的輸出都是高阻態。

下面是一種CMOS三態驅動門的電路:

可以看到,EN=0的時候輸出沒有驅動能力,處於高阻狀態。

最後總結一下,SPI協議的優缺點:

優點

  1. 協議簡單利於硬體設計與實現,比如不需要像I2C協議中每個從器件都需要一個地址;只用到4根線,封裝也很容易做
  2. 全雙工的協議,既能發送數據也能接受數據
  3. 三態輸出的驅動能力強,相對I2C的開漏輸出,抗干擾能力強,傳輸穩定;
  4. 相對於I2C協議,時鐘速度快,沒有最大限制
  5. 輸入輸出的bit數也沒什麼限制,不局限於一個byte

缺點

  1. 信號線4根,比I2C多,晶元選擇線會隨著從器件的個數的增加而增加
  2. 傳輸的過程沒有確認信號,擼起柚子加油傳,不管從器件收不收到;在SPI Flash中會有read status 這個命令確認從器件的狀態,是否處於busy狀態
  3. 沒有校驗機制,I2C也沒有,難兄難弟啊

推薦閱讀:

TAG:芯片设计 | 数字IC设计 | 存储设备电子 |