SPI總線通訊電路設計

數據帶寬=(總線頻率×數據位寬)÷8html

B表示帶寬,F表示存儲器時鐘頻率,D表示存儲器數據總線位數,則帶寬爲:
B(峯值帶寬)=F(時鐘頻率MHz)×D(總線位數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通訊是串行發送或接收數據的,即一位一位的發送和接收(按位傳輸),且傳輸通常是高位MSB在前,低位LSB在後.spa

SPI模式能夠容許同時同步發送和接收8位數據,不一樣於IIC.IIC只有一條數據線,因此IIC每次只能發送數據或傳輸數.SPI是利用4根信號線進行通訊的串行同步接口協議,包括主/從兩種模式.4個接口信號爲:串行數據輸入(MISO,主設備輸入、從設備輸出)、串行數據輸出(MOSI,主設備輸出、從設備輸入)、移位時鐘(SCK)、低電平有效的從設備使能信號(CS).SPI最大的特色是由主設備時鐘信號的出現與否來肯定主/從設備間的通訊(不想傳數據時可採用中止時鐘的方式).一旦檢測到主設備的時鐘信號,數據開始傳輸.code

SPI在遠距離傳輸中不多用到,主要由於其抗干擾能力差,可靠傳輸距離只有1—3m.SPIhtm

採用的是單端非平衡的傳輸方式,即傳輸的數據位的電壓電平是以公共地做爲參考的.在這種傳輸方式中,對於已進入信號中的干擾是沒法消除和減弱的.而信號在傳輸過程當中總會受到干擾,並且距離越長干擾越嚴重,以至於信號傳輸產生錯誤.在這種條件下,信號傳輸就變得毫無心義了.另外,因爲單端非平衡傳輸方式以公共地做爲參考點,地線做爲信號迴流線,所以也存在信號電流.當傳輸線兩端的系統之間存在交流電位差時,這個電位差將直接竄到信號中,造成噪聲干擾.因此,爲了解決抗干擾問題,一般採用平衡傳輸(balanced transmission)方式,這裏採用比較常見的RS-422.blog

1. SPI器件的主從模式設置

SPI接口的器件,分爲主設備(Master)和從設備(Slave).主設備產生時鐘信號,從設備使用主設備的產生的時鐘.主設備能主動發起數據傳輸.單片機的SPI控制寄存器SPCR中的MSTR位就是用來選擇單片機在傳輸中是做爲主設備仍是從設備的.MSTR設爲1時爲主設備,設爲0的時候爲從設備.對單片機來說管腳SS的電平也會影響SPI的工做模式,在主設備模式下,若是SS是輸入且爲低電平那麼MSTR會被清零,設備進入從模式.MISO信號由從機在主機的控制下產生.接口

下圖是由一個主機對接一個從機進行全雙工通訊的系統構成的方式.在該系統中,因爲主機和從機的角色是固定不變的,而且只有一個從機,所以,能夠將主機的SS端接高電平,將從機的SS端固定接地.ip

下圖是一個主機和多個從器件的通訊系統.各個從器件是單片機的外圍擴展芯片,它們的片選端SS分別獨佔單片機的一條通用I/O引腳,由單片機分時選通它們創建通訊.這樣省去了單片機在通訊線路上發送地址碼的麻煩,可是佔用了單片機的引腳資源.當外設器件只有一個時,能夠沒必要選通而直接將SS端接地便可.資源

採用由三個單片機互相鏈接構成多主機通訊系統鏈接方法以下:

2. SPI器件的時鐘極性和相位設置

全部的SPI設備都採用相同的接口方式,能夠經過調整處理器內部寄存器改變時鐘的極性和相位.因爲SPI器件並不必定遵循同一標準,好比EEPROM、DAC、ADC、實時時鐘及溫度傳感器等器件的SPI接口的時序都有所不一樣,爲了可以知足不一樣的接口須要,採用時鐘的極性和相位可配就可以調整SPI的通訊時序.

SPI主機與之通訊的從機的時鐘極性和相位應該一致.能夠先看看另外一篇博文,專門講解了時鐘極性和相位:http://www.cnblogs.com/jason-lu/articles/3713319.html

SPI數據傳輸的模式根據時鐘的極性和相位有四種組合,這就是四種不一樣的傳輸模式.分別稱爲模式0,模式1,模式2,模式3.有的SPI接口的器件只支持幾種模式,好比SPI接口的EEPROMAT25128能夠工做於模式0和模式3.在實際使用中須要設置爲和外圍器件兼容的模式.

設置舉例:

M25P64數據手冊上給出的時鐘的極性和相位和數據讀寫的對應的時序

如上圖所示:

時鐘極性和相位都是0時,上升沿爲前沿,數據穩定被採樣(鎖存),降低沿爲後沿,被寫入SPI總線.

時鐘極性和相位都是1時,上升沿爲後沿,數據穩定被採樣(鎖存),降低沿爲前沿,被寫入SPI總線.

和M25P64數據手冊上給出的時鐘的極性和相位和數據讀寫的對應的時序匹配的omapl138數據手冊上給出的時序

注:

  • 從機對時序的響應和主機對時序的響應相同但要比主機反應遲鈍
  • 圖30-9和圖30-10的區別:雖都表示時序上是降低沿寫上升沿讀,但30-10表示片選一拉低數據就被寫出,而30-9表示當片選拉低後還要等時鐘的降低沿來臨數據才被寫出.
  • 數據在上升沿被鎖存

因此對應的程序:

//SPIFMT0寄存器 bit 8-15 是配置時鐘頻率,bit16是時鐘延時,bit17是時鐘極性(在高電平觸發仍是低電平觸發)
SPI1->SPIFMT0 = 0x00020608;//startware配置
//SPI1->SPIFMT0 = 0x00010208;(ok logicpd配置)

3. SPI的傳輸原理

SPI設備傳輸數據過程當中老是先發送或接收高字節數據,每一個時鐘週期接收器或收發器左移

1位數據(SPI總線是按位傳輸的).對於小於16位的數據在發送以前必須左對齊,若是接收的數據小於16位則採用軟件將無效的數據位屏蔽,如圖1所示.對應的C代碼:

主機和從機都有一個串行移位寄存器,主機經過向它的SPI串行寄存器寫入一個字節來發起一次傳輸.主機的移位寄存器經過MOSI信號線將字節傳送給從機的移位寄存器,從機也將本身的移位寄存器中的內容經過MISO信號線返回給主機的移位寄存器中(以下圖所示).這樣,兩個移位寄存器中的內容就被交換.外設的寫操做和讀操做是同步完成的.

若是隻進行寫操做,主機只需忽略接收到的字節;固然,若主機要讀取從機的一個字節,則應該發送一個空字節來引起從機的傳輸.

SPI的傳輸實際上至關於兩個八位移位寄存器首位相連.每一個時鐘週期,數據從一個設備的移位寄存器移出,同時移入了另外一個寄存器.八位數據所有移出時,兩個寄存器就實現了一次數據交換.所以,SPI的發送和接收是同時進行的,實際都是發送一個字節發起的,只不過須要接收的時候發送的是一個咱們不關心的任意字節.

4. SPI傳輸示例編程

當主機發送一個連續的數據流時,有些外設可以進行多字節傳輸.多數具備SPI接口的存儲芯片就以這種方式工做.在這種傳輸方式下,從機的片選端必須在整個傳輸過程當中保持低電平.此時,一次傳輸可能會涉及到成千上萬字節的信息,而沒必要在每一個字節的數據發送的先後都去檢測其起始位和結束位(片選拉低開始,片選拉高結束),這正是同步傳輸方式優於異步傳輸方式的緣由所在.

針對外設是M25P64 外設的SPI的傳輸

方式:命令字(一個字節)+FLASH的地址(三個字節)+要發送或接收的數據(n個字節)

/* Send read command to the flash (one byte) */
tx_data =  0x03; //SPI_FLASH_READ,這是單字節指令代碼
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個字節,一個字節一個字節放入
    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)

本文爲網友熱心整理,本人純屬拿來主義.

相關文章
相關標籤/搜索