嵌入式入門必知:SPI協(xié)議及工作原理分析
直接來源:21ic電子網(wǎng)
SPI 主要應(yīng)用在 EEPROM, Flash, 實時時鐘(RTC), 數(shù)模轉(zhuǎn)換器(ADC), 數(shù)字信號處理器(DSP) 以及數(shù)字信號解碼器之間. 它在芯片中只占用四根管腳 (Pin) 用來控制以及數(shù)據(jù)傳輸, 節(jié)約了芯片的 pin 數(shù)目, 同時為 PCB 在布局上節(jié)省了空間. 正是出于這種簡單易用的特性, 現(xiàn)在越來越多的芯片上都集成了 SPI技術(shù).
1. 采用主-從模式(Master-Slave) 的控制方式
SPI 規(guī)定了兩個 SPI 設(shè)備之間通信必須由主設(shè)備 (Master) 來控制次設(shè)備 (Slave). 一個 Master 設(shè)備可以通過提供 Clock 以及對 Slave 設(shè)備進行片選 (Slave Select) 來控制多個 Slave 設(shè)備, SPI 協(xié)議還規(guī)定 Slave 設(shè)備的 Clock 由 Master 設(shè)備通過 SCK 管腳提供給 Slave 設(shè)備, Slave 設(shè)備本身不能產(chǎn)生或控制 Clock, 沒有 Clock 則 Slave 設(shè)備不能正常工作.
2. 采用同步方式(Synchronous)傳輸數(shù)據(jù)
Master 設(shè)備會根據(jù)將要交換的數(shù)據(jù)來產(chǎn)生相應(yīng)的時鐘脈沖(Clock Pulse), 時鐘脈沖組成了時鐘信號(Clock Signal) , 時鐘信號通過時鐘極性 (CPOL) 和 時鐘相位 (CPHA) 控制著兩個 SPI 設(shè)備間何時數(shù)據(jù)交換以及何時對接收到的數(shù)據(jù)進行采樣, 來保證數(shù)據(jù)在兩個設(shè)備之間是同步傳輸?shù)?
3. 數(shù)據(jù)交換(Data Exchanges)
SPI 設(shè)備間的數(shù)據(jù)傳輸之所以又被稱為數(shù)據(jù)交換, 是因為 SPI 協(xié)議規(guī)定一個 SPI 設(shè)備不能在數(shù)據(jù)通信過程中僅僅只充當一個 "發(fā)送者(Transmitter)" 或者 "接收者(Receiver)". 在每個 Clock 周期內(nèi), SPI 設(shè)備都會發(fā)送并接收一個 bit 大小的數(shù)據(jù), 相當于該設(shè)備有一個 bit 大小的數(shù)據(jù)被交換了.
一個 Slave 設(shè)備要想能夠接收到 Master 發(fā)過來的控制信號, 必須在此之前能夠被 Master 設(shè)備進行訪問 (Access). 所以, Master 設(shè)備必須首先通過 SS/CS pin 對 Slave 設(shè)備進行片選, 把想要訪問的 Slave 設(shè)備選上.
在數(shù)據(jù)傳輸?shù)倪^程中,??每次接收到的數(shù)據(jù)必須在下一次數(shù)據(jù)傳輸之前被采樣. 如果之前接收到的數(shù)據(jù)沒有被讀取, 那么這些已經(jīng)接收完成的數(shù)據(jù)將有可能會被丟棄,??導(dǎo)致 SPI 物理模塊最終失效. 因此, 在程序中一般都會在 SPI 傳輸完數(shù)據(jù)后, 去讀取 SPI 設(shè)備里的數(shù)據(jù), 即使這些數(shù)據(jù)(Dummy Data)在我們的程序里是無用的.
1. 概述

上圖只是對 SPI 設(shè)備間通信的一個簡單的描述, 下面就來解釋一下圖中所示的幾個組件(Module):
SSPBUF, Synchronous Serial Port Buffer, 泛指 SPI 設(shè)備里面的內(nèi)部緩沖區(qū), 一般在物理上是以 FIFO 的形式, 保存?zhèn)鬏斶^程中的臨時數(shù)據(jù);
SSPSR, Synchronous Serial Port Register, 泛指 SPI 設(shè)備里面的移位寄存器(Shift Regitser), 它的作用是根據(jù)設(shè)置好的數(shù)據(jù)位寬(bit-width) 把數(shù)據(jù)移入或者移出 SSPBUF;
Controller, 泛指 SPI 設(shè)備里面的控制寄存器, 可以通過配置它們來設(shè)置 SPI 總線的傳輸模式.
通常情況下, 我們只需要對上圖所描述的四個管腳(pin) 進行編程即可控制整個 SPI 設(shè)備之間的數(shù)據(jù)通信:
SCK, Serial Clock, 主要的作用是 Master 設(shè)備往 Slave 設(shè)備傳輸時鐘信號, 控制數(shù)據(jù)交換的時機以及速率;
SS/CS, Slave Select/Chip Select, 用于 Master 設(shè)備片選 Slave 設(shè)備, 使被選中的 Slave 設(shè)備能夠被 Master 設(shè)備所訪問;
SDO/MOSI, Serial Data Output/Master Out Slave In, 在 Master 上面也被稱為 Tx-Channel, 作為數(shù)據(jù)的出口, 主要用于 SPI 設(shè)備發(fā)送數(shù)據(jù);
SDI/MISO, Serial Data Input/Master In Slave Out, 在 Master 上面也被稱為 Rx-Channel, 作為數(shù)據(jù)的入口, 主要用于SPI 設(shè)備接收數(shù)據(jù);
SPI 設(shè)備在進行通信的過程中, Master 設(shè)備和 Slave 設(shè)備之間會產(chǎn)生一個數(shù)據(jù)鏈路回環(huán)(Data Loop), 就像上圖所畫的那樣, 通過 SDO 和 SDI 管腳, SSPSR 控制數(shù)據(jù)移入移出 SSPBUF, Controller 確定 SPI 總線的通信模式, SCK 傳輸時鐘信號.
2. Timing.

CPOL:?時鐘極性, 表示 SPI 在空閑時, 時鐘信號是高電平還是低電平. 若 CPOL 被設(shè)為 1, 那么該設(shè)備在空閑時 SCK 管腳下的時鐘信號為高電平. 當 CPOL 被設(shè)為 0 時則正好相反.
CPHA:?時鐘相位, 表示 SPI 設(shè)備是在 SCK 管腳上的時鐘信號變?yōu)樯仙貢r觸發(fā)數(shù)據(jù)采樣, 還是在時鐘信號變?yōu)橄陆笛貢r觸發(fā)數(shù)據(jù)采樣. 若 CPHA 被設(shè)置為 1, 則 SPI 設(shè)備在時鐘信號變?yōu)橄陆笛貢r觸發(fā)數(shù)據(jù)采樣, 在上升沿時發(fā)送數(shù)據(jù). 當 CPHA 被設(shè)為 0 時也正好相反.
??
上圖里的 "Mode 1, 1" 說明了本例所使用的 SPI 數(shù)據(jù)傳輸模式被設(shè)置成 CPOL = 1, CPHA = 1. 這樣, 在一個 Clock 周期內(nèi), 每個單獨的 SPI 設(shè)備都能以全雙工(Full-Duplex) 的方式, 同時發(fā)送和接收 1 bit 數(shù)據(jù), 即相當于交換了 1 bit 大小的數(shù)據(jù). 如果 SPI 總線的 Channel-Width 被設(shè)置成 Byte, 表示 SPI 總線上每次數(shù)據(jù)傳輸?shù)淖钚挝粸?Byte, 那么掛載在該 SPI 總線的設(shè)備每次數(shù)據(jù)傳輸?shù)倪^程至少需要 8 個 Clock 周期(忽略設(shè)備的物理延遲). 因此, SPI 總線的頻率越快, Clock 周期越短, 則 SPI 設(shè)備間數(shù)據(jù)交換的速率就越快.
3. SSPSR.

SSPSR 是 SPI 設(shè)備內(nèi)部的移位寄存器(Shift Register). 它的主要作用是根據(jù) SPI 時鐘信號狀態(tài), 往 SSPBUF 里移入或者移出數(shù)據(jù), 每次移動的數(shù)據(jù)大小由 Bus-Width 以及 Channel-Width 所決定.
Bus-Width 的作用是指定地址總線到 Master 設(shè)備之間數(shù)據(jù)傳輸?shù)膯挝?
例如, 我們想要往 Master 設(shè)備里面的 SSPBUF 寫入 16 Byte 大小的數(shù)據(jù): 首先, 給 Master 設(shè)備的配置寄存器設(shè)置 Bus-Width 為 Byte; 然后往 Master 設(shè)備的 Tx-Data 移位寄存器在地址總線的入口寫入數(shù)據(jù), 每次寫入 1 Byte 大小的數(shù)據(jù)(使用 writeb 函數(shù)); 寫完 1 Byte 數(shù)據(jù)之后, Master 設(shè)備里面的 Tx-Data 移位寄存器會自動把從地址總線傳來的1 Byte 數(shù)據(jù)移入 SSPBUF 里; 上述動作一共需要重復(fù)執(zhí)行 16 次.
Channel-Width 的作用是指定 Master 設(shè)備與 Slave 設(shè)備之間數(shù)據(jù)傳輸?shù)膯挝? 與 Bus-Width 相似,??Master 設(shè)備內(nèi)部的移位寄存器會依據(jù) Channel-Width 自動地把數(shù)據(jù)從 Master-SSPBUF 里通過 Master-SDO 管腳搬運到 Slave 設(shè)備里的 Slave-SDI 引腳, Slave-SSPSR 再把每次接收的數(shù)據(jù)移入 Slave-SSPBUF里.
通常情況下, Bus-Width 總是會大于或等于 Channel-Width, 這樣能保證不會出現(xiàn)因 Master 與 Slave 之間數(shù)據(jù)交換的頻率比地址總線與 Master 之間的數(shù)據(jù)交換頻率要快, 導(dǎo)致 SSPBUF 里面存放的數(shù)據(jù)為無效數(shù)據(jù)這樣的情況.
4. SSPBUF.

我們知道, 在每個時鐘周期內(nèi), Master 與 Slave 之間交換的數(shù)據(jù)其實都是 SPI 內(nèi)部移位寄存器從 SSPBUF 里面拷貝的. 我們可以通過往 SSPBUF 對應(yīng)的寄存器 (Tx-Data / Rx-Data register) 里讀寫數(shù)據(jù), 間接地操控 SPI 設(shè)備內(nèi)部的 SSPBUF.
例如, 在發(fā)送數(shù)據(jù)之前, 我們應(yīng)該先往 Master 的 Tx-Data 寄存器寫入將要發(fā)送出去的數(shù)據(jù), 這些數(shù)據(jù)會被 Master-SSPSR 移位寄存器根據(jù) Bus-Width 自動移入 Master-SSPBUF 里, 然后這些數(shù)據(jù)又會被 Master-SSPSR 根據(jù) Channel-Width 從 Master-SSPBUF 中移出, 通過 Master-SDO??管腳傳給 Slave-SDI 管腳,??Slave-SSPSR 則把從??Slave-SDI 接收到的數(shù)據(jù)移入 Slave-SSPBUF 里.??與此同時, Slave-SSPBUF 里面的數(shù)據(jù)根據(jù)每次接收數(shù)據(jù)的大小(Channel-Width), 通過 Slave-SDO 發(fā)往 Master-SDI, Master-SSPSR 再把從 Master-SDI 接收的數(shù)據(jù)移入 Master-SSPBUF.在單次數(shù)據(jù)傳輸完成之后, 用戶程序可以通過從 Master 設(shè)備的 Rx-Data 寄存器讀取 Master 設(shè)備數(shù)據(jù)交換得到的數(shù)據(jù).
5. Controller.

Master 設(shè)備里面的 Controller 主要通過時鐘信號(Clock Signal)以及片選信號(Slave Select Signal)來控制 Slave 設(shè)備. Slave 設(shè)備會一直等待, 直到接收到 Master 設(shè)備發(fā)過來的片選信號, 然后根據(jù)時鐘信號來工作.
Master 設(shè)備的片選操作必須由程序所實現(xiàn). 例如: 由程序把 SS/CS 管腳的時鐘信號拉低電平, 完成 SPI 設(shè)備數(shù)據(jù)通信的前期工作; 當程序想讓 SPI 設(shè)備結(jié)束數(shù)據(jù)通信時, 再把 SS/CS 管腳上的時鐘信號拉高電平.
版權(quán)歸原作者所有,如有侵權(quán),請聯(lián)系刪除。
???????????????? ?END ?????????????????
關(guān)注我的微信公眾號,回復(fù)“加群”按規(guī)則加入技術(shù)交流群。
關(guān)注程序員編程基地,回復(fù)“pdf”獲取程序員必讀經(jīng)典書單,一起編程一起進階。
點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。
