中心議題:
- SPI總線簡(jiǎn)介及主要特點(diǎn)
- SPI總線工作方式
- SPI總線常見(jiàn)錯(cuò)誤
- SPI總線控制器設(shè)計(jì)
1.SPI總線簡(jiǎn)介
SPI(serial peripheral interface,串行外圍設(shè)備接口)總線技術(shù)是Motorola公司推出的一種同步串行接口。它用于CPU與各種外圍器件進(jìn)行全雙工、同步串行通訊。它只需四條線就可以完成MCU與各種外圍器件的通訊,這四條線是:串行時(shí)鐘線(CSK)、主機(jī)輸入/從機(jī)輸出數(shù)據(jù)線(MISO)、主機(jī)輸出/從機(jī)輸入數(shù)據(jù)線(MOSI)、低電平有效從機(jī)選擇線CS。當(dāng)SPI工作時(shí),在移位寄存器中的數(shù)據(jù)逐位從輸出引腳(MOSI)輸出(高位在前),同時(shí)從輸入引腳(MISO)接收的數(shù)據(jù)逐位移到移位寄存器(高位在前)。發(fā)送一個(gè)字節(jié)后,從另一個(gè)外圍器件接收的字節(jié)數(shù)據(jù)進(jìn)入移位寄存器中。即完成一個(gè)字節(jié)數(shù)據(jù)傳輸?shù)膶?shí)質(zhì)是兩個(gè)器件寄存器內(nèi)容的交換。主SPI的時(shí)鐘信號(hào)(SCK)使傳輸同步。其典型系統(tǒng)框圖如下圖所示。
圖1 典型系統(tǒng)框圖
- 全雙工;
- 提供頻率可編程時(shí)鐘;
- 發(fā)送結(jié)束中斷標(biāo)志;
- 寫沖突保護(hù);
- 總線競(jìng)爭(zhēng)保護(hù)等。
3.SPI總線工作方式
SPI總線有四種工作方式,其中使用的最為廣泛的是SPI0和SPI3方式(實(shí)線表示):
圖2 SPI0和SPI3方式(實(shí)線表示)
四種工作方式時(shí)序分別為:
圖3 四種工作方式時(shí)序
[page]
時(shí)序詳解:
CPOL:時(shí)鐘極性選擇,為0時(shí)SPI總線空閑為低電平,為1時(shí)SPI總線空閑為高電平
CPHA:時(shí)鐘相位選擇,為0時(shí)在SCK第一個(gè)跳變沿采樣,為1時(shí)在SCK第二個(gè)跳變沿采樣
工作方式1:
當(dāng)CPHA=0、CPOL=0時(shí)SPI總線工作在方式1。MISO引腳上的數(shù)據(jù)在第一個(gè)SPSCK沿跳變之前已經(jīng)上線了,而為了保證正確傳輸,MOSI引腳的MSB位必須與SPSCK的第一個(gè)邊沿同步,在SPI傳輸過(guò)程中,首先將數(shù)據(jù)上線,然后在同步時(shí)鐘信號(hào)的上升沿時(shí),SPI的接收方捕捉位信號(hào),在時(shí)鐘信號(hào)的一個(gè)周期結(jié)束時(shí)(下降沿),下一位數(shù)據(jù)信號(hào)上線,再重復(fù)上述過(guò)程,直到一個(gè)字節(jié)的8位信號(hào)傳輸結(jié)束。
工作方式2:
當(dāng)CPHA=0、CPOL=1時(shí)SPI總線工作在方式2。與前者唯一不同之處只是在同步時(shí)鐘信號(hào)的下降沿時(shí)捕捉位信號(hào),上升沿時(shí)下一位數(shù)據(jù)上線。
工作方式3:
當(dāng)CPHA=1、CPOL=0時(shí)SPI總線工作在方式3。MISO引腳和MOSI引腳上的數(shù)據(jù)的MSB位必須與SPSCK的第一個(gè)邊沿同步,在SPI傳輸過(guò)程中,在同步時(shí)鐘信號(hào)周期開(kāi)始時(shí)(上升沿)數(shù)據(jù)上線,然后在同步時(shí)鐘信號(hào)的下降沿時(shí),SPI的接收方捕捉位信號(hào),在時(shí)鐘信號(hào)的一個(gè)周期結(jié)束時(shí)(上升沿),下一位數(shù)據(jù)信號(hào)上線,再重復(fù)上述過(guò)程,直到一個(gè)字節(jié)的8位信號(hào)傳輸結(jié)束。
工作方式4:
當(dāng)CPHA=1、CPOL=1時(shí)SPI總線工作在方式4。與前者唯一不同之處只是在同步時(shí)鐘信號(hào)的上升沿時(shí)捕捉位信號(hào),下降沿時(shí)下一位數(shù)據(jù)上線。
4.SPI總線常見(jiàn)錯(cuò)誤
4.1 SPR設(shè)定錯(cuò)誤
在從器件時(shí)鐘頻率小于主器件時(shí)鐘頻率時(shí),如果SCK的速率設(shè)得太快,將導(dǎo)致接收到的數(shù)據(jù)不正確(SPI接口本身難以判斷收到的數(shù)據(jù)是否正確,要在軟件中處理)。
整個(gè)系統(tǒng)的速度受三個(gè)因素影響:主器件時(shí)鐘CLK主、從器件時(shí)鐘CLK從和同步串行時(shí)鐘SCK,其中SCK是對(duì)CLK主的分頻,CLK從和CLK主是異步的。要使SCK無(wú)差錯(cuò)無(wú)遺漏地被從器件所檢測(cè)到,從器件的時(shí)鐘CLK從必須要足夠快。下面以SCK設(shè)置為CLK主的4分頻的波形為例,分析同步串行時(shí)鐘、主時(shí)鐘和從時(shí)鐘之間的關(guān)系。
圖4主從時(shí)鐘和SCK的關(guān)系
如圖4所示,當(dāng)T從 圖5中,當(dāng)T從≥TSCK/2=2T主時(shí),在clk_s的兩個(gè)上升沿都檢測(cè)不到SCK的低電平,這樣從器件就會(huì)漏掉一個(gè)SCK。在某些相位條件下,即使CLK從僥幸能檢測(cè)到SCK的低電平,也不能保證可以繼續(xù)檢測(cè)到下一個(gè)SCK。只要遺漏了一個(gè)SCK,就相當(dāng)于串行數(shù)據(jù)漏掉了一個(gè)位,后面繼續(xù)接收/發(fā)送的數(shù)據(jù)就都是錯(cuò)誤的了。
圖5主從時(shí)鐘和SCK的關(guān)系
根據(jù)以上的分析,SPR和主從時(shí)鐘比的關(guān)系如表1所列。
表1 SPR的設(shè)置和主從時(shí)鐘周期比值之間的關(guān)系
在發(fā)送數(shù)據(jù)之前按照表1對(duì)SPR進(jìn)行設(shè)置,SPR設(shè)定錯(cuò)誤可以完全避免。
[page]
4.2 模式錯(cuò)誤(MODF)
模式錯(cuò)誤表示的是主從模式選擇的設(shè)置和引腳SS的連接不一致。
器件工作在主模式的時(shí)候(MSTR=1),它的片選信號(hào)SS引腳必須接高電平。在發(fā)送數(shù)據(jù)的過(guò)程中,如果它的SS從高電平跳至低電平,在SS的下降沿,SPI模塊將檢測(cè)到模式錯(cuò)誤,對(duì)MODF位置1,強(qiáng)制器件從主模式轉(zhuǎn)入從模式(即令MSTR=0),清空內(nèi)部計(jì)數(shù)器counter,并結(jié)束正在進(jìn)行的數(shù)據(jù)傳輸,如圖6(a)所示。
對(duì)從模式(MSTR=0),在沒(méi)有數(shù)據(jù)傳送的時(shí)候,SS高電平表示從器件未被選中,從器件不工作,MISO輸出高阻;在數(shù)據(jù)傳輸過(guò)程中,片選信號(hào)SS必須接低電平,且SS不允許跳變。如果SS從低電平跳到高電平,在SS的上跳沿,SPI模塊也將檢測(cè)到模式錯(cuò)誤,清空內(nèi)部計(jì)數(shù)器counter,并結(jié)束正在進(jìn)行的數(shù)據(jù)傳輸。直到SS恢復(fù)為低電平,重新使SPEN=1時(shí),才重新開(kāi)始工作,如圖6(b)所示。
4.3 溢出錯(cuò)誤(OVR)
溢出錯(cuò)誤表示連續(xù)傳輸多個(gè)數(shù)據(jù)時(shí),后一個(gè)數(shù)據(jù)覆蓋了前一個(gè)數(shù)據(jù)而產(chǎn)生的錯(cuò)誤。
狀態(tài)標(biāo)志SPIF表示的是數(shù)據(jù)傳輸正在進(jìn)行中,它對(duì)數(shù)據(jù)的傳輸有較大的影響。主器件的SPIF有效由數(shù)據(jù)寄存器的空標(biāo)志SPTE=0產(chǎn)生,而從器件的SPIF有效則只能由收到的第一個(gè)SCK的跳變產(chǎn)生,且又由于從器件的SPIF和主器件發(fā)出的SCK是異步的,因此從器件的傳輸標(biāo)志SPIF從相對(duì)于主器件的傳輸標(biāo)志SPIF主有一定的滯后。如圖7所示,在主器件連續(xù)發(fā)送兩個(gè)數(shù)據(jù)的時(shí)候?qū)⒂锌赡軐?dǎo)致從器件的傳輸標(biāo)志和主器件下一個(gè)數(shù)據(jù)的傳輸標(biāo)志相重疊(圖7中虛線和陰影部分),第一個(gè)收到的數(shù)據(jù)必然被覆蓋,第二個(gè)數(shù)據(jù)的收/發(fā)也必然出錯(cuò),產(chǎn)生溢出錯(cuò)誤。
圖7溢出錯(cuò)誤
通過(guò)對(duì)從器件的波形分析發(fā)現(xiàn),counter=8后的第一個(gè)時(shí)鐘周期,數(shù)據(jù)最后一位的傳輸已經(jīng)完成。在數(shù)據(jù)已經(jīng)收/發(fā)完畢的情況下,counter=8狀態(tài)的長(zhǎng)短對(duì)數(shù)據(jù)的正確性沒(méi)有影響,因此可以縮短counter=8的狀態(tài),以避免前一個(gè)SPIF和后一個(gè)SPIF相重疊。這樣,從硬件上避免了這一階段的溢出錯(cuò)誤。
但是,如果從器件工作速度不夠快或者軟件正在處理其他事情,在SPI接口接收到的數(shù)據(jù)尚未被讀取的情況下,又接收到一個(gè)新的數(shù)據(jù),溢出錯(cuò)誤還是會(huì)發(fā)生的。此時(shí),SPI接口保護(hù)前一個(gè)數(shù)據(jù)不被覆蓋,舍棄新收到的數(shù)據(jù),置溢出標(biāo)志OVR=1;另外發(fā)出中斷信號(hào)(如果該中斷允許),通知從器件及時(shí)讀取數(shù)據(jù)。
[page]
4.4 偏移錯(cuò)誤(OFST)
SPI接口一般要求從器件先工作,然后主器件才開(kāi)始發(fā)送數(shù)據(jù)。有時(shí)在主器件往外發(fā)送數(shù)據(jù)的過(guò)程中,從器件才開(kāi)始工作,或者SCK受到外界干擾,從器件未能準(zhǔn)確地接收到8個(gè)SCK。如圖8所示,從器件接收到的8個(gè)SCK其實(shí)是屬于主器件發(fā)送相鄰的兩個(gè)數(shù)據(jù)的SCK主。這時(shí),主器件的SPIF和從器件的SPIF會(huì)發(fā)生重疊,數(shù)據(jù)發(fā)生了錯(cuò)位,從器件如果不對(duì)此進(jìn)行糾正的話,數(shù)據(jù)的接收/發(fā)送便一直地錯(cuò)下去。
圖8偏移錯(cuò)誤
在一個(gè)數(shù)據(jù)的傳輸過(guò)程中,SPR是不允許改變的,即SCK是均勻的,而從圖5可以看出,從器件接收到的8個(gè)SCK并不均勻,它們是分別屬于兩個(gè)數(shù)據(jù)的,因此可以計(jì)算SCK的占空時(shí)間來(lái)判斷是否發(fā)生了偏移錯(cuò)誤。經(jīng)分析,正常時(shí)候SCK=1時(shí)的時(shí)鐘周期數(shù)n的取值滿足如下關(guān)系:
但由于主從時(shí)鐘之間是異步的,并且經(jīng)過(guò)了取整,所以正常時(shí)候SCK=1時(shí)的時(shí)鐘周期計(jì)數(shù)值COUNT應(yīng)滿足:
比如在圖5中,COUNT的最大值COUNT(max)=2或者1,都可認(rèn)為是正常的。但當(dāng)出現(xiàn)COUNT(max)=8時(shí),可以判定出現(xiàn)了偏移錯(cuò)誤。在實(shí)際設(shè)計(jì)中,先記錄下第一個(gè)COUNT(max)的值,如果后面又出現(xiàn)與記錄值相差1以上的COUNT(max)出現(xiàn),可知有偏移錯(cuò)誤OFST發(fā)生。SPI接口在“不均勻”的地方令SPIF=1,然后準(zhǔn)備等待下一個(gè)數(shù)據(jù)的第一個(gè)SCK。其中COUNT的位數(shù)固定為8位,為了避免溢出時(shí)重新從00H開(kāi)始計(jì)數(shù),當(dāng)計(jì)數(shù)達(dá)到ffH時(shí)停止計(jì)數(shù)。
4.5 其他錯(cuò)誤
設(shè)定不當(dāng),或者受到外界干擾,數(shù)據(jù)傳輸難免會(huì)發(fā)生錯(cuò)誤,或者有時(shí)軟件對(duì)錯(cuò)誤的種類判斷不清,必須要有一種方法強(qiáng)制SPI接口從錯(cuò)誤狀態(tài)中恢復(fù)過(guò)來(lái)。在SPI不工作,即SPEN=0的時(shí)候,清除SPI模塊內(nèi)部幾乎所有的狀態(tài)(專用寄存器除外)。如果軟件在接收數(shù)據(jù)的時(shí)候,能夠發(fā)現(xiàn)數(shù)據(jù)有錯(cuò)誤,無(wú)論是什么錯(cuò)誤,都可以強(qiáng)制停止SPI的工作,重新進(jìn)行數(shù)據(jù)傳輸。例如,在偏移錯(cuò)誤(OFST)中,如果SPR2、SPR1和SPR0的設(shè)置適當(dāng),也可以使SCK顯得比較“均勻”。SPI接口硬件本身不可能檢測(cè)到有錯(cuò)誤,若用戶軟件能夠發(fā)現(xiàn)錯(cuò)誤,這時(shí)就可以強(qiáng)制停止SPI的傳輸工作,這樣就可以避免錯(cuò)誤一直持續(xù)下去。
在應(yīng)用中,如果對(duì)數(shù)據(jù)的正確性要求較高,除了要在軟件上滿足SPI接口的時(shí)序要求外,還需要在軟件上作適當(dāng)?shù)奶幚怼?br />
5.設(shè)計(jì)SPI總線控制器
目前的項(xiàng)目中使用了SPI總線接口的FLASH存儲(chǔ)器存儲(chǔ)圖像數(shù)據(jù)。FLASH的SPI總線頻率高達(dá)66M,但MCU的頻率較低,晶振頻率7.3728M,SPI最大頻率為主頻1/2。對(duì)于320*240*16的圖像讀取時(shí)間為333ms,而且還忽略了等待SPI傳輸完成、寫顯存、地址坐標(biāo)設(shè)定等時(shí)間。實(shí)際測(cè)試約為1s。成為GUI設(shè)計(jì)的極大瓶頸。由于TFT驅(qū)動(dòng)是自己FPGA設(shè)計(jì)的,資源尚有余量,決定把SPI控制器(主)及寫圖像部分邏輯放入FPGA中用硬件完成。
首先接觸到的是SPI的SCK時(shí)鐘頻率問(wèn)題。FPGA的頻率是48M,未使用PLL。能否以此頻率作為SCK頻率呢?要知道所有的MCU提供的SPI頻率最大為主頻的1/2!為什么呢?查過(guò)一些資料后發(fā)現(xiàn),SPI從機(jī)接收數(shù)據(jù)并不是以SCK為時(shí)鐘的,而是以主頻為時(shí)鐘對(duì)SCK和MISO進(jìn)行采樣,由采樣原理得知SCK不能大于1/2主頻,也就有了MCU提供最大master頻率是1/2主頻,最大slaver頻率是1/4主頻。FPGA在只作為主機(jī)時(shí)能否實(shí)現(xiàn)同主頻一樣頻率的SCK呢??答案貌似是肯定的!但我還是有點(diǎn)擔(dān)心,用組合邏輯控制SCK會(huì)不會(huì)出現(xiàn)較大毛刺影響系統(tǒng)穩(wěn)定性呢?