SPI匯流排的特點、工作方式及常見錯誤解答
1.SPI匯流排簡介
SPI(serial peripheral interface,序列外圍裝置介面)匯流排技術是Motorola公司推出的一種同步序列介面。它用於CPU與各種外圍器件進行全雙工、同步序列通訊。它只需四條線就可以完成MCU與各種外圍器件的通訊,這四條線是:序列時鐘線(CSK)、主機輸入/從機輸出資料線(MISO)、主機輸出/從機輸入資料線(MOSI)、低電平有效從機選擇線CS。當SPI工作時,在移位暫存器中的資料逐位從輸出引腳(MOSI)輸出(高位在前),同時從輸入引腳(MISO)接收的資料逐位移到移位暫存器(高位在前)。傳送一個位元組後,從另一個外圍器件接收的位元組資料進入移位暫存器中。即完成一個位元組資料傳輸的實質是兩個器件暫存器內容的交換。主SPI的時鐘訊號(SCK)使傳輸同步。其典型系統框圖如下圖所示。
圖1 典型系統框圖
2.SPI匯流排的主要特點
· 全雙工;
· 可以當作主機或從機工作;
· 提供頻率可程式設計時鐘;
· 傳送結束中斷標誌;
· 寫衝突保護;
.匯流排競爭保護等。
3.SPI匯流排工作方式
SPI匯流排有四種工作方式,其中使用的最為廣泛的是SPI0和SPI3方式(實線表示):
圖2 SPI0和SPI3方式(實線表示)
四種工作方式時序分別為:
圖3 四種工作方式時序
時序詳解:
CPOL:時鐘極性選擇,為0時SPI匯流排空閒為低電平,為1時SPI匯流排空閒為高電平
CPHA:時鐘相位選擇,為0時在SCK第一個跳變沿取樣,為1時在SCK第二個跳變沿取樣
工作方式1:
當CPHA=0、CPOL=0時SPI匯流排工作在方式1。MISO引腳上的資料在第一個SPSCK沿跳變之前已經上線了,而為了保證正確傳輸,MOSI引腳的MSB位必須與SPSCK的第一個邊沿同步,在SPI傳輸過程中,首先將資料上線,然後在同步時鐘訊號的上升沿時,SPI的接收方捕捉位訊號,在時鐘訊號的一個週期結束時(下降沿),下一位資料訊號上線,再重複上述過程,直到一個位元組的8位訊號傳輸結束。
工作方式2:
當CPHA=0、CPOL=1時SPI匯流排工作在方式2。與前者唯一不同之處只是在同步時鐘訊號的下降沿時捕捉位訊號,上升沿時下一位資料上線。
工作方式3:
當CPHA=1、CPOL=0時SPI匯流排工作在方式3。MISO引腳和MOSI引腳上的資料的MSB位必須與SPSCK的第一個邊沿同步,在SPI傳輸過程中,在同步時鐘訊號週期開始時(上升沿)資料上線,然後在同步時鐘訊號的下降沿時,SPI的接收方捕捉位訊號,在時鐘訊號的一個週期結束時(上升沿),下一位資料訊號上線,再重複上述過程,直到一個位元組的8位訊號傳輸結束。
工作方式4:
當CPHA=1、CPOL=1時SPI匯流排工作在方式4。與前者唯一不同之處只是在同步時鐘訊號的上升沿時捕捉位訊號,下降沿時下一位資料上線。
4.SPI匯流排常見錯誤
4.1 SPR設定錯誤
在從器件時鐘頻率小於主器件時鐘頻率時,如果SCK的速率設得太快,將導致接收到的資料不正確(SPI介面本身難以判斷收到的資料是否正確,要在軟體中處理)。
整個系統的速度受三個因素影響:主器件時鐘CLK主、從器件時鐘CLK從和同步序列時鐘SCK,其中SCK是對CLK主的分頻,CLK從和CLK主是非同步的。要使SCK無差錯無遺漏地被從器件所檢測到,從器件的時鐘CLK從必須要足夠快。下面以SCK設定為CLK主的4分頻的波形為例,分析同步序列時鐘、主時鐘和從時鐘之間的關係。
圖4主從時鐘和SCK的關係
如圖4所示,當T<tsck 2,即t從<2t主時,無論主時鐘和從時鐘之間的相位關係如何,在從器件clk從的上升沿必然能夠檢測到sck的低電平,即sck=0的範圍內至少包含一個clk從的上升沿。<="" p="">從<Tsck/2,即T從<2T主時,無論主時鐘和從時鐘之間的相位關係如何,在從器件CLK從的上升沿必然能夠檢測到SCK的低電平,即SCK=0的範圍內至少包含一個CLK從的上升沿。
圖5中,當T從≥TSCK/2=2T主時,在clk_s的兩個上升沿都檢測不到SCK的低電平,這樣從器件就會漏掉一個SCK。在某些相位條件下,即使CLK從僥倖能檢測到SCK的低電平,也不能保證可以繼續檢測到下一個SCK。只要遺漏了一個SCK,就相當於序列資料漏掉了一個位,後面繼續接收/傳送的資料就都是錯誤的了。
圖5主從時鐘和SCK的關係
根據以上的分析,SPR和主從時鐘比的關係如表1所列。
表1 SPR的設定和主從時鐘週期比值之間的關係
在傳送資料之前按照表1對SPR進行設定,SPR設定錯誤可以完全避免。
4.2 模式錯誤(MODF)
模式錯誤表示的是主從模式選擇的設定和引腳SS的連線不一致。
器件工作在主模式的時候(MSTR=1),它的片選訊號SS引腳必須接高電平。在傳送資料的過程中,如果它的SS從高電平跳至低電平,在SS的下降沿,SPI模組將檢測到模式錯誤,對MODF位置1,強制器件從主模式轉入從模式(即令MSTR=0),清空內部計數器counter,並結束正在進行的資料傳輸,如圖6(a)所示。
對從模式(MSTR=0),在沒有資料傳送的時候,SS高電平表示從器件未被選中,從器件不工作,MISO輸出高阻;在資料傳輸過程中,片選訊號SS必須接低電平,且SS不允許跳變。如果SS從低電平跳到高電平,在SS的上跳沿,SPI模組也將檢測到模式錯誤,清空內部計數器counter,並結束正在進行的資料傳輸。直到SS恢復為低電平,重新使SPEN=1時,才重新開始工作,如圖6(b)所示。
圖6模式錯誤的檢測
4.3 溢位錯誤(OVR)
溢位錯誤表示連續傳輸多個數據時,後一個數據覆蓋了前一個數據而產生的錯誤。
狀態標誌SPIF表示的是資料傳輸正在進行中,它對資料的傳輸有較大的影響。主器件的SPIF有效由資料暫存器的空標誌SPTE=0產生,而從器件的SPIF有效則只能由收到的第一個SCK的跳變產生,且又由於從器件的SPIF和主器件發出的SCK是非同步的,因此從器件的傳輸標誌SPIF從相對於主器件的傳輸標誌SPIF主有一定的滯後。如圖7所示,在主器件連續傳送兩個資料的時候將有可能導致從器件的傳輸標誌和主器件下一個資料的傳輸標誌相重疊(圖7中虛線和陰影部分),第一個收到的資料必然被覆蓋,第二個資料的收/發也必然出錯,產生溢位錯誤。
圖7溢位錯誤
通過對從器件的波形分析發現,counter=8後的第一個時鐘週期,資料最後一位的傳輸已經完成。在資料已經收/發完畢的情況下,counter=8狀態的長短對資料的正確性沒有影響,因此可以縮短counter=8的狀態,以避免前一個SPIF和後一個SPIF相重疊。這樣,從硬體上避免了這一階段的溢位錯誤。
但是,如果從器件工作速度不夠快或者軟體正在處理其他事情,在SPI介面接收到的資料尚未被讀取的情況下,又接收到一個新的資料,溢位錯誤還是會發生的。此時,SPI介面保護前一個數據不被覆蓋,捨棄新收到的資料,置溢位標誌OVR=1;另外發出中斷訊號(如果該中斷允許),通知從器件及時讀取資料。
4.4 偏移錯誤(OFST)
SPI介面一般要求從器件先工作,然後主器件才開始傳送資料。有時在主器件往外發送資料的過程中,從器件才開始工作,或者SCK受到外界干擾,從器件未能準確地接收到8個SCK。如圖8所示,從器件接收到的8個SCK其實是屬於主器件傳送相鄰的兩個資料的SCK主。這時,主器件的SPIF和從器件的SPIF會發生重疊,資料發生了錯位,從器件如果不對此進行糾正的話,資料的接收/傳送便一直地錯下去。
圖8偏移錯誤
在一個數據的傳輸過程中,SPR是不允許改變的,即SCK是均勻的,而從圖5可以看出,從器件接收到的8個SCK並不均勻,它們是分別屬於兩個資料的,因此可以計算SCK的佔空時間來判斷是否發生了偏移錯誤。經分析,正常時候SCK=1時的時鐘週期數n的取值滿足如下關係:
但由於主從時鐘之間是非同步的,並且經過了取整,所以正常時候SCK=1時的時鐘週期計數值COUNT應滿足:
比如在圖5中,COUNT的最大值COUNT(max)=2或者1,都可認為是正常的。但當出現COUNT(max)=8時,可以判定出現了偏移錯誤。在實際設計中,先記錄下第一個COUNT(max)的值,如果後面又出現與記錄值相差1以上的COUNT(max)出現,可知有偏移錯誤OFST發生。SPI介面在“不均勻”的地方令SPIF=1,然後準備等待下一個資料的第一個SCK。其中COUNT的位數固定為8位,為了避免溢位時重新從00H開始計數,當計數達到ffH時停止計數。
4.5 其他錯誤
設定不當,或者受到外界干擾,資料傳輸難免會發生錯誤,或者有時軟體對錯誤的種類判斷不清,必須要有一種方法強制SPI介面從錯誤狀態中恢復過來。在SPI不工作,即SPEN=0的時候,清除SPI模組內部幾乎所有的狀態(專用暫存器除外)。如果軟體在接收資料的時候,能夠發現數據有錯誤,無論是什麼錯誤,都可以強制停止SPI的工作,重新進行資料傳輸。例如,在偏移錯誤(OFST)中,如果SPR2、SPR1和SPR0的設定適當,也可以使SCK顯得比較“均勻”。SPI介面硬體本身不可能檢測到有錯誤,若使用者軟體能夠發現錯誤,這時就可以強制停止SPI的傳輸工作,這樣就可以避免錯誤一直持續下去。
在應用中,如果對資料的正確性要求較高,除了要在軟體上滿足SPI介面的時序要求外,還需要在軟體上作適當的處理。
5.設計SPI匯流排控制器
目前的專案中使用了SPI匯流排介面的FLASH儲存器儲存影象資料。FLASH的SPI匯流排頻率高達66M,但MCU的頻率較低,晶振頻率7.3728M,SPI最大頻率為主頻1/2。對於320*240*16的影象讀取時間為333ms,而且還忽略了等待SPI傳輸完成、寫視訊記憶體、地址座標設定等時間。實際測試約為1s。成為GUI設計的極大瓶頸。由於TFT驅動是自己FPGA設計的,資源尚有餘量,決定把SPI控制器(主)及寫影象部分邏輯放入FPGA中用硬體完成。
首先接觸到的是SPI的SCK時鐘頻率問題。FPGA的頻率是48M,未使用PLL。能否以此頻率作為SCK頻率呢?要知道所有的MCU提供的SPI頻率最大為主頻的1/2!為什麼呢?查過一些資料後發現,SPI從機接收資料並不是以SCK為時鐘的,而是以主頻為時鐘對SCK和MISO進行取樣,由取樣原理得知SCK不能大於1/2主頻,也就有了MCU提供最大master頻率是1/2主頻,最大slaver頻率是1/4主頻。FPGA在只作為主機時能否實現同主頻一樣頻率的SCK呢??答案貌似是肯定的!但我還是有點擔心,用組合邏輯控制SCK會不會出現較大毛刺影響系統穩定性呢?