嵌入式系統(tǒng)低速接口-SPI 繼續(xù)說(shuō)SPI,SPI來(lái)說(shuō)就是沒(méi)有IIC那么固定。它就是設(shè)計(jì)了一種二進(jìn)制流的交互方式,所以這也是為什么它那么靈活的原因。它可以在任何兩個(gè)嵌入式的設(shè)備之間交換消息。
但是話又說(shuō)回來(lái)了,SPI和UART都是串行的,那有啥區(qū)別呢? SPI的優(yōu)點(diǎn): 速度快,可達(dá)數(shù)十Mbps 接口簡(jiǎn)單,只需要三根線(SCLK、MOSI、MISO) 多設(shè)備支持簡(jiǎn)單,通過(guò)CS線選擇從機(jī) 更好的實(shí)時(shí)控制能力 支持全雙工通信 推挽驅(qū)動(dòng)(跟漏極開(kāi)路正相反)提供了比較好的信號(hào)完整性和較高的速度 比I2C或SMBus吞吐率更高 協(xié)議非常靈活支持“位”傳輸 異常簡(jiǎn)單的硬件接口: 一般來(lái)講比I2C或SMBus需要的功耗更低,因?yàn)樾枰俚碾娐?包括上拉電阻) 沒(méi)有仲裁機(jī)制或相關(guān)的失效模式 “從設(shè)備”采用的是“主設(shè)備”的時(shí)鐘,不需要精確的晶振 “從設(shè)備”不需要一個(gè)單獨(dú)的地址 — 這點(diǎn)不像I2C或GPIB或SCSI 不需要收/發(fā)器
在一個(gè)IC上只用了4個(gè)管腳, 板上走線和布局連接都比并行接口簡(jiǎn)單很多 每個(gè)設(shè)備最多只有一個(gè)單獨(dú)的總線信號(hào)(片選);其它的都是共享的 信號(hào)都是單方向的,非常容易進(jìn)行電流隔離 對(duì)于時(shí)鐘的速度沒(méi)有上限,有進(jìn)一步提高速度的潛力
SPI的缺點(diǎn): 通信距離短,不適合長(zhǎng)距離通信 通常需要額外的片選信號(hào)增加從機(jī)數(shù)量 全雙工通信復(fù)雜度較高 相比于I2C總線需要更多的管腳, 即便是只用到3根線的情況下 沒(méi)有尋址機(jī)制,在共享的總線連接時(shí)需要通過(guò)片選信號(hào)支持多個(gè)設(shè)備的訪問(wèn) 在從設(shè)備側(cè)沒(méi)有硬件流控機(jī)制(主設(shè)備一側(cè)可以通過(guò)延遲到下一個(gè)時(shí)鐘沿以降低傳輸?shù)乃俾? 從設(shè)備無(wú)法進(jìn)行硬件“應(yīng)答”(主設(shè)備傳送的信息無(wú)法確定傳遞到哪里,是否傳遞成功) 一般只支持一個(gè)主設(shè)備(取決于設(shè)備的硬件構(gòu)成) 沒(méi)有查錯(cuò)機(jī)制 沒(méi)有一個(gè)正式的標(biāo)準(zhǔn)規(guī)范,無(wú)法驗(yàn)證一致性 相對(duì)于RS-232, RS-485, 或CAN-總線,只能近距離傳輸 存在很多的變種,很難能夠找到開(kāi)發(fā)工具(例如主適配卡)支持這所有的變種 SPI不支持熱交換(動(dòng)態(tài)地增加一個(gè)節(jié)點(diǎn)). 如果想使用“中斷”,只有通過(guò)SPI信號(hào)以外的其它信號(hào)線,或者采用類似USB1.1或2.0中的周期性查詢的欺騙方式 有一些變種比如多路I/O SPI和下面定義的三線串行總線都是半雙工的
UART的優(yōu)點(diǎn): UART的缺點(diǎn): 速率較慢,通常在Mbps量級(jí) 單主機(jī)與單從機(jī)通信,擴(kuò)展難度大 對(duì)時(shí)序信號(hào)敏感,容易出現(xiàn)誤碼 不具備同步通信能力
總體來(lái)說(shuō),SPI更適合需要高速的數(shù)據(jù)交互和實(shí)時(shí)控制的場(chǎng)景;而UART更適合簡(jiǎn)單的遠(yuǎn)距離串行通信。 SPI偏向大數(shù)據(jù)流,UART可以長(zhǎng)距離的控制。 假如是自己的封裝的一個(gè)SPI的收發(fā)協(xié)議呢?
用結(jié)構(gòu)體封裝一個(gè)這樣的東西,別問(wèn)是啥?就這樣
發(fā)送 接收 所以大概要實(shí)現(xiàn)的功能 在應(yīng)用層的時(shí)候,這樣使用
以上這些函數(shù)就可以實(shí)現(xiàn),兩個(gè)MCU之間的自定義協(xié)議的通訊。
在數(shù)據(jù)在處理上面,還有一個(gè)小細(xì)節(jié),就是SPI和IIC的傳感器,有時(shí)候里面的data要使用二進(jìn)制的補(bǔ)碼。 就像這樣 使用二進(jìn)制補(bǔ)碼表示數(shù)據(jù)的好處主要有:二進(jìn)制補(bǔ)碼可以直接表示傳感器采集的有符號(hào)數(shù)據(jù)(負(fù)數(shù)),無(wú)需額外處理。比如溫度值可以直接用二進(jìn)制補(bǔ)碼形式表示正負(fù)溫度。如果使用純二進(jìn)制表示無(wú)符號(hào)數(shù)據(jù),CPU進(jìn)行有符號(hào)數(shù)的運(yùn)算和比較需要額外處理。使用補(bǔ)碼可以直接進(jìn)行算術(shù)運(yùn)算,提高效率。如果使用ASCII等編碼,數(shù)據(jù)存儲(chǔ)和傳輸會(huì)膨脹很多。二進(jìn)制補(bǔ)碼表示可以高效利用每一位。補(bǔ)碼形式的數(shù)據(jù)可以直接作為int16、int32等有符號(hào)類型解析,無(wú)需復(fù)雜解碼。ASCII編碼需要進(jìn)行 num-to-ascii 和 ascii-to-num 的轉(zhuǎn)換,容易引入錯(cuò)誤。二進(jìn)制補(bǔ)碼可以避免這類問(wèn)題。統(tǒng)一不同設(shè)備的數(shù)據(jù)表示采用標(biāo)準(zhǔn)補(bǔ)碼表示,使不同廠家的設(shè)備的數(shù)據(jù)可以統(tǒng)一被處理。但需要注意,二進(jìn)制補(bǔ)碼需要處理符號(hào)位擴(kuò)展問(wèn)題,左移時(shí)需要適當(dāng)維護(hù)符號(hào)位。并且 debug 和顯示需做轉(zhuǎn)換。使用二進(jìn)制補(bǔ)碼可以提高傳感器數(shù)據(jù)處理的效率與質(zhì)量。那說(shuō)了這么多,自己模擬一個(gè)協(xié)議可能是最好的,這里就用51單片機(jī)來(lái)搞這個(gè)。使用的引腳
遍歷需要發(fā)送的數(shù)據(jù)字節(jié)數(shù)組,一位一位寫(xiě)入MOSI口。同時(shí)通過(guò)設(shè)置SCK為1和0來(lái)模擬SPI時(shí)鐘的上升沿和下降沿。
在一個(gè)8位循環(huán)內(nèi),讀取MOSI的每一位數(shù)據(jù),在SCK上升沿時(shí)采樣,并寫(xiě)入data變量。SCK下降沿準(zhǔn)備采樣下一位。傳感器具有能在SCK輸入信號(hào)為有效高電平或低電平時(shí)工作的能力。當(dāng) CE 信號(hào)變成高電平時(shí),檢測(cè)到 SCK 的 無(wú)效狀態(tài),而時(shí)鐘輸入 (CP)的極性決定數(shù)據(jù)是在系統(tǒng)時(shí)鐘的上升沿或下降沿移入或移出,看眼引腳
這個(gè)圖給出了用于傳送數(shù)據(jù)到寄存器和從寄存器移出數(shù)據(jù)的相應(yīng)時(shí)鐘邊沿。每個(gè)時(shí)鐘脈沖傳送一位數(shù)據(jù),數(shù)據(jù)位以 8 位為一組傳送。A是地址,D是數(shù)據(jù)。先發(fā)送地址字節(jié),隨后為數(shù)據(jù)。數(shù)據(jù)可以采用單字節(jié)或多字節(jié)包的方式進(jìn)行傳送,在 3 字節(jié)包中,數(shù)據(jù)序列包括溫度數(shù)據(jù)的 MSb、溫度數(shù)據(jù)的 LSb 和緊接著的控制寄存器數(shù)據(jù)。通過(guò)向寄存器寫(xiě)入所需數(shù)據(jù)包的最高地址來(lái)啟動(dòng)多字節(jié)讀功能。串行輸出: SCLK : SCK, CLK. 主輸出 –> 從輸入: MOSI : SIMO, SDI(對(duì)于“從”設(shè)備), DI, DIN, SI, MTST. 主輸入 ←- 從輸出: –> MISO : SOMI, SDO (對(duì)于“從”設(shè)備), DO, DOUT, SO, MRSR. 從選擇: SS : nCS, CS, CSB, CSN, EN, nSS, STE, SYNC. 多數(shù)從設(shè)備的輸出是三態(tài)的,當(dāng)該從設(shè)備沒(méi)有被選中的時(shí)候它們的MISO信號(hào)就為高阻(邏輯上斷開(kāi)連接)。不具有三態(tài)輸出的器件是不能同其它器件共享SPI總線部分的,只能是一個(gè)從設(shè)備跟主設(shè)備相連。單片機(jī)GPIO引腳的三態(tài)(Tri-state)是指該引腳可以處于三種狀態(tài):1.推挽輸出: 引腳被配置為輸出,可以被置高電平(1)或者低電平(0)。2.開(kāi)漏輸出: 引腳被配置為開(kāi)漏輸出,可以被置低電平(0),或處于高阻抗?fàn)顟B(tài)(Z)。3.高阻輸入: 引腳被配置為輸入,此時(shí)處于高阻抗?fàn)顟B(tài)(Z),可以檢測(cè)外部信號(hào)的高低電平。這里以最常見(jiàn)的SPI3模式說(shuō)下時(shí)序圖怎么看。
當(dāng)數(shù)據(jù)未發(fā)送時(shí)以及發(fā)送完畢后,SCK都是高電平,因此CPOL=1。看最前面。 在SCK第一個(gè)沿(下降沿)的時(shí)候,MOSI和MISO會(huì)發(fā)生變化。同時(shí)SCK第二個(gè)沿(上升沿)的時(shí)候,數(shù)據(jù)是穩(wěn)定的,此刻采樣數(shù)據(jù)是合適的,也就是上升沿即一個(gè)時(shí)鐘周期的后沿鎖存讀取數(shù)據(jù),即CPHA=1。 當(dāng)CPHA=0、CPOL=0時(shí)SPI總線工作在方式0,如下圖。簡(jiǎn)化起見(jiàn)把MOSI和MISO合在一起了。當(dāng)CPHA=0、CPOL=1時(shí)SPI總線工作在SPI1當(dāng)CPHA=1、CPOL=0時(shí)SPI總線工作在SPI2。要點(diǎn),看發(fā)送前的時(shí)鐘,然后看兩個(gè)邊沿對(duì)應(yīng)的數(shù)據(jù)線,判斷什么時(shí)候是保持邊沿的。適合采樣的。讓我小小的臭美一下
|