本文轉(zhuǎn)自:https://www.cnblogs.com/aaronLinux/p/6219146.html
轉(zhuǎn)自:https://my.oschina.net/freeblues/blog/67400
1.SPI協(xié)議簡介
1.1.SPI協(xié)議概括
SPI,是英語Serial Peripheral interface的縮寫,顧名思義就是串行外圍設(shè)備接口。是Motorola首先在其MC68HCXX系列處理器上定義的失球。SPI接口主要應(yīng)用在 EEPROM君珠,F(xiàn)LASH基跑,實(shí)時(shí)時(shí)鐘橡淆,AD轉(zhuǎn)換器,還有數(shù)字信號(hào)處理器和數(shù)字信號(hào)解碼器之間立帖。SPI,是一種高速的悠砚,全雙工晓勇,同步的通信總線,并且在芯片的管腳上只占用四根線,節(jié)約了芯片的管腳绑咱,同時(shí)為PCB的布局上節(jié)省空間绰筛,提供方便,正是出于這種簡單易用的特性描融,現(xiàn)在越來越多的芯片集成了這種通信協(xié)議铝噩,比如AT91RM9200.
SPI的通信原理很簡單,它以主從方式工作稼稿,這種模式通常有一個(gè)主設(shè)備和一個(gè)或多個(gè)從設(shè)備薄榛,需要至少4根線,事實(shí)上3根也可以(單向傳輸時(shí))让歼。也是所有基于SPI的設(shè)備共有的敞恋,它們是SDI(數(shù)據(jù)輸入),SDO(數(shù)據(jù)輸出)谋右,SCK(時(shí)鐘)硬猫,CS(片選)。
SDO???? – 主設(shè)備數(shù)據(jù)輸出改执,從設(shè)備數(shù)據(jù)輸入
SDI????? – 主設(shè)備數(shù)據(jù)輸入啸蜜,從設(shè)備數(shù)據(jù)輸出
SCLK?? – 時(shí)鐘信號(hào),由主設(shè)備產(chǎn)生
CS??????? – 從設(shè)備使能信號(hào)辈挂,由主設(shè)備控制
CS: 其中CS是控制芯片是否被選中的衬横,也就是說只有片選信號(hào)為預(yù)先規(guī)定的使能信號(hào)時(shí)(高電位或低電位),對(duì)此芯片的操作才有效终蒂,這就允許在同一總線上連接多個(gè)SPI設(shè)備成為可能蜂林。
SDI/SDO/SCLK: 通訊是通過數(shù)據(jù)交換完成的,這里先要知道SPI是串行通訊協(xié)議拇泣,也就是說數(shù)據(jù)是一位一位的傳輸?shù)脑胄稹_@就是SCK時(shí)鐘線存在的原因,由SCK提供時(shí)鐘脈沖霉翔,SDI睁蕾,SDO則基于此脈沖完成數(shù)據(jù)傳輸。數(shù)據(jù)輸出通過 SDO線债朵,數(shù)據(jù)在時(shí)鐘上升沿或下降沿時(shí)改變子眶,在緊接著的下降沿或上升沿被讀取。完成一位數(shù)據(jù)傳輸葱弟,輸入也使用同樣原理壹店。這樣,在至少8次時(shí)鐘信號(hào)的改變(上沿和下沿為一次)芝加,就可以完成8位數(shù)據(jù)的傳輸硅卢。
要注意的是射窒,SCK信號(hào)線只由主設(shè)備控制,從設(shè)備不能控制信號(hào)線将塑。同樣脉顿,在一個(gè)基于SPI的設(shè)備中,至少有一個(gè)主控設(shè)備点寥。這樣傳輸?shù)奶攸c(diǎn):這樣的傳輸方式有一個(gè)優(yōu)點(diǎn)艾疟,與普通的串行通訊不同,普通的串行通訊一次連續(xù)傳送至少8位數(shù)據(jù)敢辩,而SPI允許數(shù)據(jù)一位一位的傳送蔽莱,甚至允許暫停,因?yàn)镾CK時(shí)鐘線由主控設(shè)備控制戚长,當(dāng)沒有時(shí)鐘跳變時(shí)盗冷,從設(shè)備不采集或傳送數(shù)據(jù),也就是說同廉,主設(shè)備通過對(duì)SCK時(shí)鐘線的控制可以完成對(duì)通訊的控制仪糖。SPI還是一個(gè)數(shù)據(jù)交換協(xié)議:因?yàn)镾PI的數(shù)據(jù)輸入和輸出線獨(dú)立,所以允許同時(shí)完成數(shù)據(jù)的輸入和輸出迫肖。不同的SPI設(shè)備的實(shí)現(xiàn)方式不盡相同锅劝,主要是數(shù)據(jù)改變和采集的時(shí)間不同,在時(shí)鐘信號(hào)上沿或下沿采集有不同定義蟆湖,具體請(qǐng)參考相關(guān)器件的文檔故爵。
在點(diǎn)對(duì)點(diǎn)的通信中,SPI接口不需要進(jìn)行尋址操作隅津,且為全雙工通信稠集,顯得簡單高效。在多個(gè)從設(shè)備的系統(tǒng)中饥瓷,每個(gè)從設(shè)備需要獨(dú)立的使能信號(hào),硬件上比I2C系統(tǒng)要稍微復(fù)雜一些痹籍。
最后呢铆,SPI接口的一個(gè)缺點(diǎn):沒有指定的流控制,沒有應(yīng)答機(jī)制確認(rèn)是否接收到數(shù)據(jù)蹲缠。
AT91RM9200的SPI接口主要由4個(gè)引腳構(gòu)成:SPICLK棺克、MOSI、MISO及 /SS线定,其中SPICLK是整個(gè)SPI總線的公用時(shí)鐘娜谊,MOSI、MISO作為主機(jī)斤讥,從機(jī)的輸入輸出的標(biāo)志纱皆,MOSI是主機(jī)的輸出,從機(jī)的輸入,MISO 是主機(jī)的輸入派草,從機(jī)的輸出搀缠。/SS是從機(jī)的標(biāo)志管腳,在互相通信的兩個(gè)SPI總線的器件近迁,/SS管腳的電平低的是從機(jī)艺普,相反/SS管腳的電平高的是主機(jī)。在一個(gè)SPI通信系統(tǒng)中鉴竭,必須有主機(jī)歧譬。SPI總線可以配置成單主單從,單主多從搏存,互為主從瑰步。
SPI的片選可以擴(kuò)充選擇16個(gè)外設(shè),這時(shí)PCS輸出=NPCS,說NPCS0~3接4-16譯碼器,這個(gè)譯碼器是需要外接4-16譯碼器,譯碼器的輸入為NPCS0~3祭埂,輸出用于16個(gè)外設(shè)的選擇面氓。
1.2.協(xié)議舉例
SPI是一個(gè)環(huán)形總線結(jié)構(gòu),由ss(cs)蛆橡、sck舌界、sdi、sdo構(gòu)成泰演,其時(shí)序其實(shí)很簡單呻拌,主要是在sck的控制下,兩個(gè)雙向移位寄存器進(jìn)行數(shù)據(jù)交換睦焕。
假設(shè)下面的8位寄存器裝的是待發(fā)送的數(shù)據(jù)10101010藐握,上升沿發(fā)送、下降沿接收垃喊、高位先發(fā)送猾普。
那么第一個(gè)上升沿來的時(shí)候 數(shù)據(jù)將會(huì)是sdo=1;寄存器=0101010x本谜。下降沿到來的時(shí)候初家,sdi上的電平將所存到寄存器中去,那么這時(shí)寄存器=0101010sdi乌助,這樣在?8個(gè)時(shí)鐘脈沖以后溜在,兩個(gè)寄存器的內(nèi)容互相交換一次。這樣就完成里一個(gè)spi時(shí)序他托。
舉例:
假設(shè)主機(jī)和從機(jī)初始化就緒:并且主機(jī)的sbuff=0xaa掖肋,從機(jī)的sbuff=0x55,下面將分步對(duì)spi的8個(gè)時(shí)鐘周期的數(shù)據(jù)情況演示一遍:假設(shè)上升沿發(fā)送數(shù)據(jù)
這樣就完成了兩個(gè)寄存器8位的交換赏参,上面的上表示上升沿志笼、下表示下降沿沿盅,sdi、sdo相對(duì)于主機(jī)而言的籽腕。其中ss引腳作為主機(jī)的時(shí)候嗡呼,從機(jī)可以把它拉底被動(dòng)選為從機(jī),作為從機(jī)的是時(shí)候皇耗,可以作為片選腳用南窗。根據(jù)以上分析,一個(gè)完整的傳送周期是16位郎楼,即兩個(gè)字節(jié)万伤,因?yàn)椋紫戎鳈C(jī)要發(fā)送命令過去呜袁,然后從機(jī)根據(jù)主機(jī)的命令準(zhǔn)備數(shù)據(jù)敌买,主機(jī)在下一個(gè)8位時(shí)鐘周期才把數(shù)據(jù)讀回來。
SPI?總線是Motorola公司推出的三線同步接口阶界,同步串行3線方式進(jìn)行通信:一條時(shí)鐘線SCK虹钮,一條數(shù)據(jù)輸入線MOSI,一條數(shù)據(jù)輸出線MISO;用于CPU與各種外圍器件進(jìn)行全雙工膘融、同步串行通訊芙粱。SPI主要特點(diǎn)有:可以同時(shí)發(fā)出和接收串行數(shù)據(jù);可以當(dāng)作主機(jī)或從機(jī)工作;提供頻率可編程時(shí)鐘;發(fā)送結(jié)束 中斷標(biāo)志;寫沖突保護(hù);總線競爭保護(hù)等。下圖示出SPI總線工作的四種方式氧映,其中使用的最為廣泛的是SPI0和SPI3方式?(實(shí)線表示):? ? ? ? ? ? ? ? ??
SPI總線四種工作方式
SPI?模塊為了和外設(shè)進(jìn)行數(shù)據(jù)交換春畔,根據(jù)外設(shè)工作要求,其輸出串行同步時(shí)鐘極性和相位可以進(jìn)行配置岛都,時(shí)鐘極性(CPOL)對(duì)傳輸協(xié)議沒有重大的影響律姨。
如果?CPOL=0,串行同步時(shí)鐘的空閑狀態(tài)為低電平臼疫;
如果CPOL=1择份,串行同步時(shí)鐘的空閑狀態(tài)為高電平。時(shí)鐘相位(CPHA)能夠配置用于選擇兩種不同的傳輸協(xié)議之一進(jìn)行數(shù)據(jù)傳輸烫堤。
如果CPHA=0缓淹,在串行同步時(shí)鐘的第一個(gè)跳變沿(上升或下降)數(shù)據(jù)被采樣;
如果CPHA=1塔逃,在串行同步時(shí)鐘的第二個(gè)跳變沿(上升或下降)數(shù)據(jù)被采樣。SPI主模塊和與之通信的外設(shè)備時(shí)鐘相位和極性應(yīng)該一致料仗。
補(bǔ)充:
上文中最后一句話:SPI主模塊和與之通信的外設(shè)備時(shí)鐘相位和極性應(yīng)該一致湾盗。個(gè)人理解這句話有2層意思:其一,主設(shè)備SPI時(shí)鐘和極性的配置應(yīng)該由外設(shè)來決定立轧;其二格粪,二者的配置應(yīng)該保持一致躏吊,即主設(shè)備的SDO同從設(shè)備的SDO配置一致,主設(shè)備的SDI同從設(shè)備的SDI配置一致帐萎。因?yàn)橹鲝脑O(shè)備是在SCLK的控制下比伏,同時(shí)發(fā)送和接收數(shù)據(jù),并通過2個(gè)雙向移位寄存器來交換數(shù)據(jù)疆导。工作原理演示如下圖:
上升沿主機(jī)SDO發(fā)送數(shù)據(jù)1赁项,同時(shí)從設(shè)備SDO發(fā)送數(shù)據(jù)0;緊接著在SCLK的下降沿的時(shí)候從設(shè)備的SDI接收到了主機(jī)發(fā)送過來的數(shù)據(jù)1澈段,同時(shí)主機(jī)也接收到了從設(shè)備發(fā)送過來的數(shù)據(jù)0.
1.3.協(xié)議心得
SPI接口時(shí)鐘配置心得:
在主設(shè)備這邊配置SPI接口時(shí)鐘的時(shí)候一定要弄清楚從設(shè)備的時(shí)鐘要求悠菜,因?yàn)橹髟O(shè)備這邊的時(shí)鐘極性和相位都是以從設(shè)備為基準(zhǔn)的。因此在時(shí)鐘極性的配置上一定要搞清楚從設(shè)備是在時(shí)鐘的上升沿還是下降沿接收數(shù)據(jù)败富,是在時(shí)鐘的下降沿還是上升沿輸出數(shù)據(jù)悔醋。但要注意的是,由于主設(shè)備的SDO連接從設(shè)備的SDI兽叮,從設(shè)備的SDO連接主設(shè)備的SDI芬骄,從設(shè)備SDI接收的數(shù)據(jù)是主設(shè)備的SDO發(fā)送過來的,主設(shè)備SDI接收的數(shù)據(jù)是從設(shè)備SDO發(fā)送過來的鹦聪,所以主設(shè)備這邊SPI時(shí)鐘極性的配置(即SDO的配置)跟從設(shè)備的SDI接收數(shù)據(jù)的極性是相反的账阻,跟從設(shè)備SDO發(fā)送數(shù)據(jù)的極性是相同的。下面這段話是Sychip Wlan8100 Module Spec上說的椎麦,充分說明了時(shí)鐘極性是如何配置的:
The 81xx module will always input data bits at the rising edge of the clock, and the host will always output data bits on the falling edge of the clock.
意思是:主設(shè)備在時(shí)鐘的下降沿發(fā)送數(shù)據(jù)宰僧,從設(shè)備在時(shí)鐘的上升沿接收數(shù)據(jù)。因此主設(shè)備這邊SPI時(shí)鐘極性應(yīng)該配置為下降沿有效观挎。
又如琴儿,下面這段話是摘自LCD Driver IC SSD1289:
SDI is shifted into 8-bit shift register on every rising edge of SCK in the order of data bit 7, data bit 6 …… data bit 0.
意思是:從設(shè)備SSD1289在時(shí)鐘的上升沿接收數(shù)據(jù),而且是按照從高位到地位的順序接收數(shù)據(jù)的嘁捷。因此主設(shè)備的SPI時(shí)鐘極性同樣應(yīng)該配置為下降沿有效造成。
時(shí)鐘極性和相位配置正確后,數(shù)據(jù)才能夠被準(zhǔn)確的發(fā)送和接收,因此應(yīng)該對(duì)照從設(shè)備的SPI接口時(shí)序或者Spec文檔說明來正確配置主設(shè)備的時(shí)鐘雄嚣。
2.SPI協(xié)議軟件模擬
2.1.單片機(jī)軟件模擬SPI接口—加深理解SPI總線協(xié)議
SPI(Serial Peripheral Interfacer 串行外設(shè)接口)是摩托羅拉公司推出的一種同步串行通訊接口晒屎,用于微處理器臌控制器和外圍擴(kuò)展芯片之間的串行連接,現(xiàn)已發(fā)展成為一種工業(yè)標(biāo)準(zhǔn)缓升,目前鼓鲁,各半導(dǎo)體公司推出了大量的帶有SPI接口的具有各種各樣功能的芯片,如RAM港谊,EEPROM骇吭,F(xiàn)lashROM,A/D轉(zhuǎn)換器歧寺、D/A轉(zhuǎn)換器燥狰、LED/LED顯示驅(qū)動(dòng)器棘脐、I/O接口芯片、實(shí)時(shí)時(shí)鐘龙致、UART收發(fā)器等等蛀缝,為用戶的外圍擴(kuò)展提供了極其靈活而價(jià)廉的選擇。由于SPI總線接口只占用微處理器四個(gè)I/O口線目代,采用SPI總線接口可以簡化電路沒計(jì)屈梁,節(jié)省很多常規(guī)電路中的接口器件和I/O口線,提高設(shè)計(jì)的可靠性像啼。
現(xiàn)以 AT89C205l單片機(jī)模擬SPI總線操作串行EEPROM 93CA6為例俘闯,如圖1所示,介紹利用單片機(jī)的I/O口通過軟件模擬SPI總線的實(shí)現(xiàn)方法忽冻。在這里真朗,僅介紹讀命令的時(shí)序和應(yīng)用子程序。
2.2.93C46存儲(chǔ)器SPI總線的工作原理
? ? ? ? ? 93CA6作為從設(shè)備僧诚,其SPI接口使用4條I/O口線:串行時(shí)鐘線(SK)遮婶、輸出數(shù)據(jù)線DO、輸入數(shù)據(jù)線DI和高電平有效的從機(jī)選擇線CS湖笨。其數(shù)據(jù)的傳輸格式是高位(MSB)在前旗扑,低位(LsB)在后。93C46的SPI總線接口讀命令時(shí)序如圖2所示慈省。?
2.3.軟件模擬SPI接口的實(shí)現(xiàn)方法?
對(duì)于不帶SPI串行總線接口的AT89C2051單片 機(jī)來說臀防,可以使用軟件來模擬SPI的操作,圖1所示 為AT89C2051單片機(jī)與串行EEPROM 93C46的硬件 連接圖边败,其中袱衷,P1.0模擬SPI主設(shè)備的數(shù)據(jù)輸出端 SDO,P1.2模擬SPI的時(shí)鐘輸出端SCK笑窜,P1.3模擬 SPI的從機(jī)選擇端SCS致燥,P1.1模擬SPI的數(shù)據(jù)輸入 SDI。
上電復(fù)位后首先先將P1.2(SCK)的初始狀態(tài)設(shè)置為0(空閑狀態(tài))排截。
讀操作:AT89C2051首先通過P1.0口發(fā)送1位起始位(1)嫌蚤,2位操作碼(10),6位被讀的數(shù)據(jù)地址(A5A4A3A2A1A0)断傲,然后通過P1.1口讀1位空位(0)脱吱,之后再讀l6位數(shù)據(jù)(高位在前)。
寫操作:AT89C2051首先通過P1.0口發(fā)送1位起始位(1)认罩,2位操作碼(01)箱蝠,6位被寫的數(shù)據(jù)地址(A5A4A3A2A1A0),之后通過P1.0口發(fā)送被寫的l6位數(shù)據(jù)(高位在前),寫操作之前要發(fā)送寫允許命令抡锈,寫之后要發(fā)送寫禁止命令。
寫允許操作(WEN)):寫操作首先發(fā)送1位起始位(1)乔外,2位操作碼(00)床三,6位數(shù)據(jù)(11XXXX)。
? ? ? ? ?寫禁止操作(WDS)):寫操作首先發(fā)送1位起始位(1)杨幼,2位操作碼(00)撇簿,6位數(shù)據(jù)(00XXXX)。
? ? ? ? 下面介紹用C51模擬SPI的子程序差购。
1//首先定義好I/O口 2sbit SDO=P1^0四瘫; 3sbit SDI=P1^1; 4sbit SCK=P1^2欲逃; 5sbit SCS=P1^3找蜜; 6sbit ACC_7= ACC^7; 7unsignedintSpiRead(unsignedchar add) 8{ 9unsignedchar i稳析;10unsignedint datal6洗做;11add&=0x3f;/*6位地址*/12add |=0x80彰居;/*讀操作碼l0*/13SDO=1诚纸;/*發(fā)送1為起始位*/14SCK=0;15SCK=1陈惰;16for(i=0畦徘;<8;i++)/*發(fā)送操作碼和地址*/17? ? {18if(add&0x80==1)19SDO=1抬闯;20else21SDO=0井辆;22SCK=0;/*從設(shè)備上升沿接收數(shù)據(jù)*/23SCK=1画髓;24add<<=1掘剪;25? ? }26SCK=1;/*從設(shè)備時(shí)鐘線下降沿后發(fā)送數(shù)據(jù)奈虾,空讀1位數(shù)據(jù)*/27SCK=0夺谁;28datal6<<=1;/*讀16位數(shù)據(jù)*/29for(i=0;<16肉微;i++)30? ? {31SCK=1匾鸥;32? ? ? ? _nop_();33if(SDI==1)34datal6|=0x01碉纳;35SCK =0勿负;36datal6< < =1;37? ? }38return datal6;39}
對(duì)于不同的串行接口外圍芯片奴愉,它們的時(shí)鐘時(shí)序是不同的琅摩。上述子程序是針對(duì)在SCK的上升沿輸入(接收)數(shù)據(jù)和在下降沿輸出(發(fā)送)數(shù)據(jù)的器件。這些子程序也適用于在串行時(shí)鐘)的上升沿輸入和下降沿輸出的其它各種串行外圍接口芯片锭硼,只要在程序中改變P1.2(SCK)的輸出電平順序進(jìn)行相應(yīng)調(diào)整即可房资。