數(shù)據(jù)帶寬=(總線頻率×數(shù)據(jù)位寬)÷8
B表示帶寬,F表示存儲器時鐘頻率,D表示存儲器數(shù)據(jù)總線位數(shù),則帶寬為:
B(峰值帶寬)=F(時鐘頻率MHz)×D(總線位數(shù)bit)/8
例如,PC-100的SDRAM帶寬計算如下:
100MHz×64bit/8=800MB/S
由于SPI(serial peripheral interface)總線占用的接口線(4根)少,通信效率高.eg:外接M25P64型號的SPIFLASH時,SPI總線的最大傳輸速率為75MHz/8=9375KB/S,因為該SPIFLASH的頻率:75 MHz.普通IIC總線傳輸速率為10kbps--400kbps.并且SPI支持大部分處理器芯片,因而是一種理想的選擇.
SPI通信是串行發(fā)送或接收數(shù)據(jù)的,即一位一位的發(fā)送和接收(按位傳輸),且傳輸一般是高位MSB在前,低位LSB在后.
SPI模式可以允許同時同步發(fā)送和接收8位數(shù)據(jù),不同于IIC.IIC只有一條數(shù)據(jù)線,所以IIC每次只能發(fā)送數(shù)據(jù)或傳輸數(shù).SPI是利用4根信號線進行通信的串行同步接口協(xié)議,包括主/從兩種模式.4個接口信號為:串行數(shù)據(jù)輸入(MISO,主設備輸入、從設備輸出)、串行數(shù)據(jù)輸出(MOSI,主設備輸出、從設備輸入)、移位時鐘(SCK)、低電平有效的從設備使能信號(CS).SPI最大的特點是由主設備時鐘信號的出現(xiàn)與否來確定主/從設備間的通信(不想傳數(shù)據(jù)時可采用停止時鐘的方式).一旦檢測到主設備的時鐘信號,數(shù)據(jù)開始傳輸.
SPI在遠距離傳輸中很少用到,主要因為其抗干擾能力差,可靠傳輸距離只有1—3m.SPI
采用的是單端非平衡的傳輸方式,即傳輸?shù)臄?shù)據(jù)位的電壓電平是以公共地作為參考的.在這種傳輸方式中,對于已進入信號中的干擾是無法消除和減弱的.而信號在傳輸過程中總會受到干擾,而且距離越長干擾越嚴重,以致于信號傳輸產(chǎn)生錯誤.在這種條件下,信號傳輸就變得毫無意義了.另外,由于單端非平衡傳輸方式以公共地作為參考點,地線作為信號回流線,因此也存在信號電流.當傳輸線兩端的系統(tǒng)之間存在交流電位差時,這個電位差將直接竄到信號中,形成噪聲干擾.所以,為了解決抗干擾問題,通常采用平衡傳輸(balanced transmission)方式,這里采用比較常見的RS-422.
1. SPI器件的主從模式設置
SPI接口的器件,分為主設備(Master)和從設備(Slave).主設備產(chǎn)生時鐘信號,從設備使用主設備的產(chǎn)生的時鐘.主設備能主動發(fā)起數(shù)據(jù)傳輸.單片機的SPI控制寄存器SPCR中的MSTR位就是用來選擇單片機在傳輸中是作為主設備還是從設備的.MSTR設為1時為主設備,設為0的時候為從設備.對單片機來講管腳SS的電平也會影響SPI的工作模式,在主設備模式下,如果SS是輸入且為低電平那么MSTR會被清零,設備進入從模式.MISO信號由從機在主機的控制下產(chǎn)生.
下圖是由一個主機對接一個從機進行全雙工通信的系統(tǒng)構(gòu)成的方式.在該系統(tǒng)中,由于主機和從機的角色是固定不變的,并且只有一個從機,因此,可以將主機的SS端接高電平,將從機的SS端固定接地.
下圖是一個主機和多個從器件的通信系統(tǒng).各個從器件是單片機的外圍擴展芯片,它們的片選端SS分別獨占單片機的一條通用I/O引腳,由單片機分時選通它們建立通信.這樣省去了單片機在通信線路上發(fā)送地址碼的麻煩,但是占用了單片機的引腳資源.當外設器件只有一個時,可以不必選通而直接將SS端接地即可.
采用由三個單片機互相連接構(gòu)成多主機通信系統(tǒng)連接方法如下:
2. SPI器件的時鐘極性和相位設置
所有的SPI設備都采用相同的接口方式,可以通過調(diào)整處理器內(nèi)部寄存器改變時鐘的極性和相位.由于SPI器件并不一定遵循同一標準,比如EEPROM、DAC、ADC、實時時鐘及溫度傳感器等器件的SPI接口的時序都有所不同,為了能夠滿足不同的接口需要,采用時鐘的極性和相位可配就能夠調(diào)整SPI的通信時序.
SPI主機與之通信的從機的時鐘極性和相位應該一致.可以先看看另一篇博文,專門講解了時鐘極性和相位:http://www.cnblogs.com/jason-lu/articles/3713319.html
SPI數(shù)據(jù)傳輸?shù)哪J礁鶕?jù)時鐘的極性和相位有四種組合,這就是四種不同的傳輸模式.分別稱為模式0,模式1,模式2,模式3.有的SPI接口的器件只支持幾種模式,比如SPI接口的EEPROMAT25128可以工作于模式0和模式3.在實際使用中需要設置為和外圍器件兼容的模式.
設置舉例:
M25P64數(shù)據(jù)手冊上給出的時鐘的極性和相位和數(shù)據(jù)讀寫的對應的時序
如上圖所示:
時鐘極性和相位都是0時,上升沿為前沿,數(shù)據(jù)穩(wěn)定被采樣(鎖存),下降沿為后沿,被寫入SPI總線.
時鐘極性和相位都是1時,上升沿為后沿,數(shù)據(jù)穩(wěn)定被采樣(鎖存),下降沿為前沿,被寫入SPI總線.
和M25P64數(shù)據(jù)手冊上給出的時鐘的極性和相位和數(shù)據(jù)讀寫的對應的時序匹配的omapl138數(shù)據(jù)手冊上給出的時序
注:
從機對時序的響應和主機對時序的響應相同但要比主機反應遲鈍
圖30-9和圖30-10的區(qū)別:雖都表示時序上是下降沿寫上升沿讀,但30-10表示片選一拉低數(shù)據(jù)就被寫出,而30-9表示當片選拉低后還要等時鐘的下降沿來臨數(shù)據(jù)才被寫出.
數(shù)據(jù)在上升沿被鎖存
所以對應的程序:
//SPIFMT0寄存器 bit 8-15 是配置時鐘頻率,bit16是時鐘延時,bit17是時鐘極性(在高電平觸發(fā)還是低電平觸發(fā))
SPI1->SPIFMT0 = 0x00020608;//startware配置 //SPI1->SPIFMT0 = 0x00010208;(ok logicpd配置)
3. SPI的傳輸原理
SPI設備傳輸數(shù)據(jù)過程中總是先發(fā)送或接收高字節(jié)數(shù)據(jù),每個時鐘周期接收器或收發(fā)器左移
1位數(shù)據(jù)(SPI總線是按位傳輸?shù)?.對于小于16位的數(shù)據(jù)在發(fā)送之前必須左對齊,如果接收的數(shù)據(jù)小于16位則采用軟件將無效的數(shù)據(jù)位屏蔽,如圖1所示.對應的C代碼:
主機和從機都有一個串行移位寄存器,主機通過向它的SPI串行寄存器寫入一個字節(jié)來發(fā)起一次傳輸.主機的移位寄存器通過MOSI信號線將字節(jié)傳送給從機的移位寄存器,從機也將自己的移位寄存器中的內(nèi)容通過MISO信號線返回給主機的移位寄存器中(如下圖所示).這樣,兩個移位寄存器中的內(nèi)容就被交換.外設的寫操作和讀操作是同步完成的.
如果只進行寫操作,主機只需忽略接收到的字節(jié);當然,若主機要讀取從機的一個字節(jié),則應該發(fā)送一個空字節(jié)來引發(fā)從機的傳輸.
SPI的傳輸實際上相當于兩個八位移位寄存器首位相連.每個時鐘周期,數(shù)據(jù)從一個設備的移位寄存器移出,同時移入了另一個寄存器.八位數(shù)據(jù)全部移出時,兩個寄存器就實現(xiàn)了一次數(shù)據(jù)交換.因此,SPI的發(fā)送和接收是同時進行的,實際都是發(fā)送一個字節(jié)發(fā)起的,只不過需要接收的時候發(fā)送的是一個我們不關(guān)心的任意字節(jié).
4. SPI傳輸示例編程
當主機發(fā)送一個連續(xù)的數(shù)據(jù)流時,有些外設能夠進行多字節(jié)傳輸.多數(shù)具有SPI接口的存儲芯片就以這種方式工作.在這種傳輸方式下,從機的片選端必須在整個傳輸過程中保持低電平.此時,一次傳輸可能會涉及到成千上萬字節(jié)的信息,而不必在每個字節(jié)的數(shù)據(jù)發(fā)送的前后都去檢測其起始位和結(jié)束位(片選拉低開始,片選拉高結(jié)束),這正是同步傳輸方式優(yōu)于異步傳輸方式的原因所在.
針對外設是M25P64 外設的SPI的傳輸
方式:命令字(一個字節(jié))+FLASH的地址(三個字節(jié))+要發(fā)送或接收的數(shù)據(jù)(n個字節(jié))
/* Send read command to the flash (one byte) */
tx_data = 0x03; //SPI_FLASH_READ,這是單字節(jié)指令代碼 SpiTransfer(&tx_data, &rx_data, 1); /* Send the address to start reading from (3 bytes) ,共24位*/ addr[0] = (unsigned char)(flashAddr >> 16); addr[1] = (unsigned char)(flashAddr >> 8); addr[2] = (unsigned char)flashAddr; len = 0; while (len < sizeof(addr)) { SpiTransfer(&addr[len], &rx_data, 1); len++; } /* Read all the bytes */ len = 0; while(len < size) { SpiTransfer(&tx_data, destAddr, 1); destAddr++;//共20個字節(jié),一個字節(jié)一個字節(jié)放入 len++; } 命令字:
// numonyx spi flash commands. #define NUMONYX_CMD_WREN (0x06) #define NUMONYX_CMD_WRDI (0x04) #define NUMONYX_CMD_RDID (0x9F) #define NUMONYX_CMD_RDSR (0x05) #define NUMONYX_CMD_WRSR (0x01) #define NUMONYX_CMD_READ (0x03) #define NUMONYX_CMD_FAST_READ (0x0B) #define NUMONYX_CMD_PAGE_PROG (0x02) #define NUMONYX_CMD_SEC_ERASE (0xD8) #define NUMONYX_CMD_BULK_ERASE (0xC7) #define NUMONYX_CMD_RD_ELEC_SIG (0xAB)
評論