在51系列的MCU中,STC12C5410AD系列提供了一種高速串行通訊接口,其全雙工,高速,同步,兩種操作模式:主模式和從模式。主模式支持高達3Mbps的速率。
SPI接口寄存器如下:

SPI控制寄存器SPCTL

SSIG:引腳忽略控制位
SSIG=1;MSTR(第四位)確定硬件作為主機還是從機
SSIG=0;SS~用于確定其間作為主機還是從機。
SPEN;SPI使能位
SPEN=1;SPI使能,SPEN=0;
SPI禁止,此時可作為通用IO使用。
DORD:設定SPI數(shù)據(jù)發(fā)送和接收的位順序
DPRD=1;數(shù)據(jù)最低位LSB最先發(fā)送
DPRD=0;數(shù)據(jù)最高位MSB最先發(fā)送
MSTR;主從位選擇
CPOL;SPI時鐘極性
CPOL=1;SPICLK空閑時為高電平,SPICLK的前時鐘沿為下降沿而后沿為上升沿。
CPOL=0;SPICLK空閑時為低電平,SPICLK的前時鐘沿為上升沿而后沿為下降沿。
CPHA;SPI時鐘相位選擇
CPHA=1;數(shù)據(jù)在SPICLK的前時鐘沿驅動,并在后時鐘沿采樣。
CPHA=0;數(shù)據(jù)在(SS~)為低(SSIG=00)時被驅動,在SPICLK的后時鐘沿被改變,并在前時鐘沿被采樣。(SSIG為1時的動作未定義);
SPR1,SPR0;SPI時鐘速率選擇控制位,時鐘選擇如下:

其中,CPU_CLK為CPU的時鐘。
SPI狀態(tài)寄存器SPSTAT

SPIF;SPI傳輸完成標志
當一次傳輸完成,SPIF置位,此時,如果SPi中斷被打開(即ESPI(IE2.1)和EA(IE.7)都置位),則產(chǎn)生中斷。當SPI處于主模式且SSIG=0時,如果SSIG~為輸入并被驅動為低電平,SPIF也將置位,,表示模式改變,SPIF通過軟件向其寫入“1”,清零。
WCOL;SPI寫沖突標志
在數(shù)據(jù)傳輸?shù)倪^程中,如果對SPi數(shù)據(jù)寄存器SPDAT執(zhí)行寫操作,WCOL將置位,WCOL標志通過軟件向其寫入“1”清零。
SPI數(shù)據(jù)寄存器SPIDAT

SPDAT.7-SPDAT.0: 數(shù)據(jù)的傳輸位Bit7-Bit0
SPI的核心是一個8位的移位寄存器和數(shù)據(jù)緩沖器,數(shù)據(jù)可以同時接受或者發(fā)送,在SPI數(shù)據(jù)的傳輸過程中,發(fā)送和接受的數(shù)據(jù)都存儲在數(shù)據(jù)緩沖寄存器中
對于主模式,若想發(fā)送一字節(jié)數(shù)據(jù),只需將這個數(shù)據(jù)寫道SPIDAT寄存器中,
主模式下SS~不是必須的,
從模式下,必須在SS~信號變?yōu)橛行Р⒔邮艿胶线m的時鐘信號后,方可進行數(shù)據(jù)傳輸。此模式下,如果一個字節(jié)傳輸完成后,SS~信號變?yōu)楦唠娖,這個字節(jié)立即被硬件邏輯標志為接收完成,SPI接口準備接受下一個數(shù)據(jù)。
SPI接口的數(shù)據(jù)通信
SPI接口對應管腳SCLK/P1.7,MOSI/P1.5,MISO/P1.6mSS~/P1.4
MOSI(Master Out Sleavein--主出從入);多個從機共享一根MOSI信號線,在時鐘邊沿的前半周期,主機將數(shù)據(jù)放在MOSI信號線上,叢機在該邊界處獲取數(shù)據(jù)。
MISO(Master in Sleaver out--主入從出);一個主機可以連接多個從機,,因此MISO的信號線會連接到多個從機上,當主機與一個從機通訊時,其他從機應將其MISO引腳驅動置位高阻狀態(tài)。
SCLK(SPIClock);從主機到從機,用于同步不MOSI或者MISO的數(shù)據(jù)傳輸,當主器件啟動一次數(shù)據(jù)傳輸時,自動產(chǎn)生8個SCLK時鐘周期信號給從機,在SCLK的每個跳變處(上升沿或者下降沿)移出一位數(shù)據(jù),所以一次數(shù)據(jù)的傳輸可以穿出一個字節(jié)。
SS~(Sleave Select從機信號選擇);主從模式下的SS~使用不同。
主模式下,SPI接口只能有一個主機,不存在主機選擇問題,該模式下,SS~不是必須的,主模式下,通常將主機的SS~管腳通過10K電阻上啦至高電平。每一個從機的SS~接主機的IO口,由主機控制電平高低,以便主機選擇從機。
從模式下;不管發(fā)送還是接收,SS~信號必須有效,因此在一次數(shù)據(jù)開始傳輸之前,必須將SS~置為低電平。在典型配置中,SPI主機使用IO口選擇一個SPI器件作為當前的從機。
SPI從期間通過SS~管腳以確定是否被選擇,如果滿足下面的條件之一,SS~就被忽略:
如果SPI系統(tǒng)被禁止,即SPEN(SPCTL.6)=0。
如果SPI配置為主機,即MSTR(SPCTL.4)=1,并且P1.4配置為輸出(通過P1M0.4和P1M1.4)
如果SS~管腳被忽略,即SSIG1(SPCTL.7)=1;該腳配置用于IO口功能。
注意:及時SPI被配置為主機(MSTR=1),他仍然可以通過拉低SS~配置為從機(如果P1.4配置為輸入且SSIG=0),要是能改特性,應當置位SPIF(SPSTAT.7)。
SPI接口的數(shù)據(jù)通信方式
三種分別是:
單主機-----從機方式
雙器件方式(器件可互為主機和從機)
單主機----多主機方式
單主機----=單從機連接方式:

雙器件方式(器件可互為主機和從機):

當沒有發(fā)聲SPI操作時,兩個期間度可以配置為主機(MSTR=1),將SSIG清零并將P1.4(SS~)配置為準雙向模式,當其中一個期間啟動傳輸時,它可將P1.4配置為輸出并驅動為低電平,這樣就強制另一個器件變?yōu)閺臋C。
雙方初始化時,將自己設置成忽略SS~腳的SPI從模式,當一方要主動發(fā)送數(shù)據(jù)時,先檢測SS~腳的電平,如果SS~是高電平,及將自己設置成忽略SS~的SPI主模式。
通訊雙方平時將SPi設置成沒有被選中的從模式,在該模式下,MISO,MOSI,SCLK均為輸入,當多個MCU的SPI接口以此模式并聯(lián)時,不會分發(fā)生總線沖突,這種特性在互為主/從,一主多從等應用中很有用。
注意:互為主從時,雙方的SPI速率必須相同,如果使用外部晶體振蕩器,雙方的晶體頻率也要相同。
單主機----多主機方式:

在上圖中,從機的SSIG(SPCTL.7)為0,從機通過對應的SS~信號被選中,SPI主機可使用任何端口(包括P1.4/SS~)來驅動SS~引腳。
SPI主從模式配置:

作為主機或者從機時的額外注意事項:
作為從機時,額外注意事項:
當CPHA=0時,SSIG必須為0(也就是i不能忽略SS~),SS~引腳必須置低并且在每個連續(xù)的串行字節(jié)發(fā)送完成后,需重新設置為高電平。如果SPDAT寄存器在SS~有效(低電平)時執(zhí)行寫操作,那么將導致一個寫沖突錯誤。
當CPHA=1時,SSIG可以置1(即可以忽略SS~引腳),入伏哦SSIG=0,SS~引腳可在連續(xù)傳輸之間保持低有效。這種方式有時適用于具有單固定主機和單從機驅動MISO的數(shù)據(jù)線的系統(tǒng)。
作為主機時的額外注意事項:
在SPI中,傳輸總是由主機啟動.如果SPI使能(SPEN=1)并選擇作為主機,主機對SPI數(shù)據(jù)寄存器的寫操作將啟動SPI時鐘發(fā)聲器和數(shù)據(jù)的傳輸,在數(shù)據(jù)寫入SPDAT之后的半個到一個SPI位時間后,數(shù)據(jù)將出現(xiàn)在MOSI腳。
需要注意的是:主機可以通過將對應器件SS~驅動為低電平與之通信,寫入主機SPDAT寄存器的數(shù)據(jù)從MOSI移出發(fā)送到從機的MOSI。同時主機SPDAT寄存器的數(shù)據(jù)從MISO移出發(fā)送到主機的MISO。
傳送玩一個字節(jié)后,SPI時鐘發(fā)聲器停止,傳輸完成標志SPIF置位,并產(chǎn)生一個中斷。主機和從機CPU的兩個移位寄存器可以看做是一個16位循環(huán)移位寄存器,當數(shù)據(jù)從主機移到從機時,數(shù)據(jù)也可以以相反的方向移入,這意味著一個移位周期中,主機和從機的數(shù)據(jù)相互交換。
通過SS~改變模式
如果SPEN=1,SSIG=0且MSTR=1,SPI使能位主機模式。SS~可配置為輸入或者準雙向模式。這種情況下,另外一個主機可將該腳驅動為低電平,從而將該器件選擇為SPI從機并向其發(fā)送數(shù)據(jù)。
為了避免爭奪總線,SPI系統(tǒng)執(zhí)行以下操作:
1.MSTR清零并且CPU變成從機。這樣SPi就變成從機。MOSI和SCLK強制變?yōu)檩斎肽J剑鳰ISO則變?yōu)檩敵瞿J?br />
2.SPATAT的SPIF的標志位置位,如果SPI中斷已被使能,則產(chǎn)生SPI中斷。
用戶軟件必須一直對MSTR位進行檢測,如果改為被一個從機選擇所清零而用戶想繼續(xù)講SPI作為主機,這是就必須重新職位MSTR,否則就進入從機模式。
寫沖突:
SPi在發(fā)送時為單緩沖,在接受時為雙緩沖,這樣在前一次發(fā)送行為完成之前,不能將新的數(shù)據(jù)寫入移位寄存器。當發(fā)送過程中,對數(shù)據(jù)寄存器進行寫操作時,WCOL(SPSTAT.6)將置位以指示數(shù)據(jù)沖突,在這種情況下,當前發(fā)送的數(shù)據(jù)繼續(xù)發(fā)送,而新寫入的數(shù)據(jù)則丟失。
當對主機或者從機進行寫沖突檢測時,主機發(fā)生寫沖突的情況是很罕見的,因為主機擁有數(shù)據(jù)傳輸?shù)耐耆刂茩啵珡臋C有可能發(fā)生寫沖突。因為當主機啟動傳輸時,從機無法盡心控制。
接收數(shù)據(jù)時,接收到的數(shù)據(jù)傳送到一個并行讀數(shù)據(jù)緩沖區(qū),這樣將釋放移位寄存器以繼續(xù)下一個數(shù)據(jù)的接收。但必須在下個字符完全移入之前,從數(shù)據(jù)寄存器中讀出接收到的數(shù)據(jù),否則前一個接收數(shù)據(jù)將丟失。
WCOl可通過軟件向其寫入“1”清零。
數(shù)據(jù)模式
時鐘相位位(CPHA)允許用戶設置采樣和改變數(shù)據(jù)的時鐘邊沿;時鐘極性位(CPOL)允許用戶攝者始終極性,
SPI從機傳輸格式(CPHA=0),如下:

SPI從機傳輸格式(CPHA=1),如下:

SPI主機傳輸格式(CPHA=0),如下:

SPI主機傳輸格式(CPHA=1),如下:

SPI的相關縮寫:
SPI的極性Polarity和相位Phase,最常見的寫法是CPOL和CPHA,
CKPOL (Clock Polarity) = CPOL = POL = Polarity = (時鐘)極性
CKPHA (Clock Phase) = CPHA =PHA = Phase = (時鐘)相位
SCK=SCLK=SPI的時鐘
Edge=邊沿,即時鐘電平變化的時刻,即上升沿(rising edge)或者下降沿(falling edge)
在一個周期內(nèi),關于邊沿的問題:
Leadingedge=前一個邊沿=第一個邊沿,對于開始電壓是1,那么就是1變成0的時候,對于開始電壓是0,那么就是0變成1的時候;
Trailingedge=后一個邊沿=第二個邊沿,對于開始電壓是1,那么就是0變成1的時候(即在第一次1變成0之后,才可能有后面的0變成1),對于開始電壓是0,那么就是1變成0的時候
關于極性和相位的解釋:

CPOL極性:
先說什么是SCLK時鐘的空閑時刻,其就是當SCLK在數(shù)發(fā)送8個bit比特數(shù)據(jù)之前和之后的狀態(tài),
于此對應的,SCLK在發(fā)送數(shù)據(jù)的時候,就是正常的工作的時候,有效active的時刻了。
先說英文,其精簡解釋為:Clock Polarity = IDLE state of SCK。
再用中文詳解:
SPI的CPOL,表示當SCLK空閑idle的時候,其電平的值是低電平0還是高電平1:
CPOL=0,時鐘空閑idle時候的電平是低電平,所以當SCLK有效的時候,就是高電平,就是所謂的active-high;
CPOL=1,時鐘空閑idle時候的電平是高電平,所以當SCLK有效的時候,就是低電平,就是所謂的active-low;
CPHA相位:
首先說明一點,capture strobe = latch = read =sample,都是表示數(shù)據(jù)采樣,數(shù)據(jù)有效的時刻。
相位,對應著數(shù)據(jù)采樣是在第幾個邊沿(edge),是第一個邊沿還是第二個邊沿,0對應著第一個邊沿,1對應著第二個邊沿。
對于:
CPHA=0,表示第一個邊沿:
對于CPOL=0,idle時候的是低電平,第一個邊沿就是從低變到高,所以是上升沿;
對于CPOL=1,idle時候的是高電平,第一個邊沿就是從高變到低,所以是下降沿;
CPHA=1,表示第二個邊沿:
對于CPOL=0,idle時候的是低電平,第二個邊沿就是從高變到低,所以是下降沿;
對于CPOL=1,idle時候的是高電平,第一個邊沿就是從低變到高,所以是上升沿;
或者圖文可以解釋的更加的清晰:

判斷SPI的CPOL和CPHA的方法:
CPOL是用來決定SCK時鐘信號空閑時的電平,CPOL=0,空閑電平為低電平,CPOL=1時,空閑電平為高電平。
CPHA是用來決定采樣時刻的,CPHA=0,在每個周期的第一個時鐘沿采樣,CPHA=1,在每個周期的第二個時鐘沿采樣
圖形可能會來得更加的直觀:

|