隨著科技的演進, 在單晶片微控制器及 SoC 的領域中, SPI 及 I2C 這二種串列 (序列) 介面變得十分常見. 這二者與主機間通訊用的非同步串列通訊埠 RS-232 (UART) 非常不一樣
- 二個都是同步傳輸介面, 主要是用於 CPU 和週邊晶片之間.
- SPI 及 I2C 二者設計的主要目的在於減少 CPU 和週邊晶片之間的接腳數.
- SPI 一般需要 4 條接線 (至少三條), 而 I2C 則只要二條線, 這和早期常用的並列匯流排動輒十數條接線有著明顯的差異.
- SPI 的硬體結構簡單而且傳輸速度快, 一般是 5M/10M/20Mbps 或是更快 (可以到 200Mbps), I2C 的傳輸速度則只有 100Kbps/400Kbps/1Mbps(/3.4Mbps/單向5Mbps).
- SPI 是全雙工, I2C 則是半雙工.
- SPI 使用硬體線路來指定 slave 晶片, I2C 則在傳送的第一個位元組上指定 (7bit位址).
- SPI 不提供交握機制, 無法確認 slave 晶片是否有跟上. I2C 則有雙向的確認機制.
本篇介紹的是 SPI 介面
SPI 簡介
SPI 是 Serial Peripheral Interface 的縮寫, 中文意思是串列週邊介面, 該介面是由 Motorola 公司設計發展的高速同步串列介面, 原先是應用在其 68xx 系列的 8 位元處理器上 (1985 年首次出現在 M68HC11 處理器上, 並提供了完整之說明文件), 用以連接 ADC, DAC, EEPROM, 通訊傳輸 IC...等週邊晶片. 由於具備有低接腳數, 結構單純, 傳輸速度快, 簡單易用...等特性, 目前已經成為業界慣用標準: 不只是單晶片微控制器上有, 許多新的 SoC 晶片直接就支援多組 SPI 介面, 甚至普及到連模組化的產品 (如: 手機用的 LCD 模組 (SDI 介面), 相機模組) 及 3C 產品 (如: 數位相機用的記憶卡) 也都是使用 SPI 介面.
備註: 早期數位相機用的 MMC (Multi Media Card) 記憶卡是直接使用 SPI 相容的介面, 新式的 SD 卡為了加快傳輸速度雖然擴充了接腳定義, 但也還保留了舊式 SPI 介面相容的模式. 參看 How to Use MMC/SDC
SPI 架構及介面接腳
SPI 為一主從式架構, 通常有一個 Master (主設備) 和一個 (或多個) Slave (從設備). 介接方法及內部硬體結構很簡單, 如下面的示意圖:
SPI 結構示意圖 (傳輸部份)
介面上總共有 4 支接腳:
| 接腳名稱 | 中文 | 說明 |
|---|---|---|
| MOSI | 主出從入 | master 數據輸出, slave 數據輸入 |
| MISO | 主入從出 | master 數據輸入, slave 數據輸出 |
| SCLK | 時脈訊號 | 時脈信號, 由 master 產生並控制 |
| /SS | 晶片致能 | slave 選擇信號, 由 master 控制. slave 只有在 /SS 信號為低電位時, 才會對 master 的操作指令有反應. |
介接時只要把相同名稱接腳接在一起即可
SPI 的接腳有另一套常用的名稱:
- SDO: Serial Data Out, 資料輸出 (不分主從)
- SDI: Serial Data In, 資料輸入 (不分主從)
- SCK: 對應 SCLK
- /CS: 對應 /SS
由於這種標示方法不分主從, 資料輸出都是 SDO, 資料輸入都是 SDI, 所以介接時必需把二個設備的 SDO 和 SDI 接腳對接: master 的 SDO 接到 slave 的 SDI, master 的 SDI 接到 slave 的 SDO.
在實際應用上, 如果不需要由 slave 讀回資料時 (如: Output Port Expander, 或者 DAC 晶片), 則 MISO 接腳可以省略. 有看到一部份資料說: 只有一主一從時, /SS 訊號可以省略, 只要將 slave 的 /SS 直接接地即可. 對某些 slave 晶片來說這是不對的, 因為有些 slave 晶片會拿 /SS 訊號的下降緣來識別 master 送來的第一個 bit. 這是非常重要的錯誤回復機制, 遇到這類 slave 晶片只把 /SS 接腳直接接地是不會動作的. 另外後述的 Daisy-Chain 接法也需要這個 /SS 訊號的上昇緣才能運作. Daisy-Chain 模式用它 (/SS 訊號的上昇緣) 來栓鎖指令, 如此多個 slave 晶片才能同時載入不同的指令.
由上面的結構示意圖, 我們很清楚的看出它其實是利用二組頭尾相連的位移暫存器 (Shift Rigister) 來完成 master 和 slave 之間的資料交換, 而且是接收與發送同時進行 (全雙工). 而 SCLK 就是用來控制二者同步位移的時脈信號, 它是由 master 產生送出給雙方的位移暫存器. 這樣子的結構允許資料一位元一位元的傳送, 可快可慢, 甚至允許暫停 (可以暫停在任意點上, 完全沒有限制), 因為 SCLK 沒有變動時, 雙方的 shift register 是不會有動作的. 所以如果你的微控制器沒有硬體式的 SPI 可以用, 直接用軟體加一般的 GPIO 接腳, 就可以模擬 SPI master. (用軟體模擬 SPI slave 則不建議, 因為如果我們不知道對方會送多快的 SCLK).
在介接方面, 除了簡單的一主一從架構之外, SPI 也可以一個 master 連接多個 slave. 接法上有二種, 一種是利用多條獨立的 /SS 訊號, 另一種則利用 Daisy-Chain 的方式.
SPI Master 介接多個 Slave 的二種接法
使用 Daisy-Chain 的方法, 不需要額外的硬體接線腳來擴充 /SS 訊號, 但是傳送及接收程式需要大改, 非常的麻煩. 另外還有一個障礙是, slave 晶片必需在同一個模式下工作, 還有也不能有接腳缺省的情形 (有許多 DAC 晶片沒有 MISO 接腳), 也因此常見的應用 Daisy-Chain 的例子都是用來串連多個同一型號的晶片, 例如: 需要多組 DAC 或者是 ADC 一起工作的情況. 另外要注意的是: 並非每一顆 SPI 晶片都可以支援 Daisy-Chain 的接法, 必需詳細檢視晶片的使用手冊是否有支援 Daisy-Chain 介接方法, 或者是檢視讀取的指令格式是否符合 Daisy-Chain 的需求. 否則到時候硬體接線接好了, Master 卻怎樣也無法命令 slave 晶片正常的工作.
Daisy-Chain 的運作方法是以倍數擴充每次傳輸的指令/資料長度 (有二個 slave 晶片串在一起, 傳輸長度就 x2; 三個 slave 晶片串在一起, 傳輸長度就 x3). 由於上一顆 slave 晶片的 MISO 是連接到下一顆 slave 晶片 MOSI, 所以多出來的傳輸訊號很自然把先前的訊號擠出來, 送到下一顆晶片. 等到所有訊號都送出去了, 再來就是利用 /SS 訊號的上昇緣來通知每一顆 slave 晶片: 要給你的指令/資料已經準備好了, 請把它栓鎖 (latch) 起來了. 同樣的讀回資料也會串在一起. 所以原本的驅動程式必需把要給各個 slave 晶片的指令暫存起來然後依 slave 晶片串連的次序將指令串起來再送出, 收回來的資料也必需先裁切好再依 slave 晶片串連的次序分配給對應的接收單元.
是故比較常用的是多條獨立的 /SS 訊號. 有的 master 晶片是直接提供額外的 /SS1, /SS2, /SS3...等接腳. 有的則需要利用原本的 /SS 再以一組 3to8 解碼器 (或者是 4to16 解碼器) 配合 3~4 條 GPIO 接腳來產生需要的多組 /SS. 更有的 SoC 乾脆提供多組 SPI 單元及多條獨立的 /SS 訊號 (當然的, 代價是 master 晶片的接腳數比較多, 單價拉高.).
SPI 工作模式及時序圖
使用 SPI, 最麻煩一件事是確認周邊晶片的工作模式. SPI 一共有 4 種工作模式, 但這 4 種模式的時序圖差異非常小, 常令初學者 '霧剎剎' 抓不到重點. 如下圖:
各種工作模式下的 SPI 時序圖
首先, SPI 的 4 種工作模式是依其時脈 (Clock) 的極性 (polarity, 有 2 種) 和相位 (phase, 也有 2 種) 區分的.
上圖的上半部是 SCLK 的時序, 有兩種選擇: CPOL=0 或者 CPOL=1. 中間及下半部是 MOSI MISO 的時序, 一樣是有兩種選擇: 中間是 MOSI MISO 是在 SCLK 的奇數次變化栓鎖資料, 下半部則是 MOSI MISO 是在 SCLK 的偶數次變化栓鎖資料.
解說:
- SPI slave 晶片一般只支援一種工作模式, 所以通常 master 必需牽就 slave 把工作模式設成和 slave 一致, 才能正常運作. (因為二者內部均是位移暫存器, 所以 MOSI 和 MISO 的時序需求是一樣)
- 首先, 第一個不同是 SCLK 的極性 (polarity), 所謂極性其實是指 SPI 不工作時, SCLK 是停留在高電位還是低電位. CPOL=0 是 SCLK 在不工作時停留在低電位, CPOL=1 則是停留在高電位.
- 再來要注意 slave 晶片是在 SCLK 的下降緣栓鎖資料, 還是在 SCLK 的上升緣. 要讓對方栓鎖資料, 我們就必需把資料 Hold 住, 保持穩定, 所以 Slave 晶片在 SCLK 的下降緣栓鎖資料, 相對的 master 就必需要在上升緣送出資料. 反之, slave 晶片在 SCLK 的上升緣栓鎖資料, 相對的 master 就必需要在下降緣送出資料.
- 但是 CPHA 的定義並不是依上升緣/下降緣. CPHA 設定的是晶片栓鎖資料的時機是在 /SS 訊號下降之後, SCLK 的奇數次變化 (CPHA=0), 還是偶數次變化 (CPHA=1).
- 所以 CPHA 配合 CPOL (SCLK 的極性) 設定, 組合起來一共有 4 種工作模式. 不過模式的命名順序出現了分歧沒有統一, 現有的晶片出現了二種順序 (參閱 Wiki 網站 Serial Peripheral Interface Bus). 所以撰寫程式時不要只是把 Mode 設成相同的數值, 小心 master 晶片和 slave 晶片二者的模式順序不同. 不過仔細對照一下, 差異只有 mode 的數值不同而已, CPOL 及 CPHA 的定義並無不同.
SPI Mode Mode # of
Model AMode # of
Model BCPOLCPHA資料栓鎖時機 MISOMOSI
時序圖1 0 CPOL=0 CPHA=0 奇數次 上升緣 上半組 0 1 CPOL=0 CPHA=1 偶數次 下降緣 下半組 3 2 CPOL=1 CPHA=0 奇數次 下降緣 上半組 2 3 CPOL=1 CPHA=1 偶數次 上升緣 下半組 Model A: For ARM-based and Microchip PIC
Model B: 其他 - 一旦正確辨識出 slave 晶片的工作模式, 只要把 master 設定成一樣的工作模式即可正確的傳送指令及接收資料.
結語
總結一下辨識的技巧:
- 先確認 slave 晶片需求的 SCLK 極性, 不工作時是在低電位還是高電位, 由此確認 CPOL 為 0 或 1.
- 再由 slave 晶片 datasheet 中的時序圖確認 slave 晶片是在 SCLK 的下降緣栓鎖資料, 還是在 SCLK 的上升緣.
- 直接比對上面的模式表, 確認出 CPHA 值為 0 或 1.
- 確認傳輸時序圖是否正確 (是奇數組 SCLK 變化, 還是偶數組 SCLK 變化)
補充說明一點, 從 /SS 的下降緣到第一個 SCLK latch edge 有一小段時間的 delay, 這一小段 delay 必需滿足 slave device 的規格需求, 尤其是 SCLK 的頻率偏高的時候. 否取 slave device 會無法正常工作. 有些 MCU 的 SPI 硬體模組把這一段設成固定的 CLK 數; 有些 MCU 的 SPI 硬體模組則可以讓使用者自行調整. (2018/06/14)
還有一點在圖中有標示, 但上文沒有提到的是: SPI 的資料是 msb (Most Significant Bit)bit7 (MSB) 先傳 (傳輸的資料格式是 8 Bits 就 bit7 先傳, 是 16 Bits 就 bit15 先傳, 是 24 Bits 就 bit23 先傳), 如果你是用軟體來模擬 SPI master 需注意到這一點. 話雖如此, 有些許 MCU 的 SPI port 是允許你把它改為 lsb (Least Significant Bit) 先傳, 這是為了要能應付一些沒有依照標準設計的晶片, 並不是標準狀況, 也請小心.
另外 SPI 只是硬體的傳輸協定, 完全沒有提及定址(選擇晶片/暫存器位址), 指令, 資料長度...等等, 這一部份是完全由 salve 晶片制定, master 想要控制 slave 動作必需完全依據 slave 晶片 datasheet 上的規範.
好了, 實例資料現下沒有時間整理, 以後整理好了再補充.
再談 Daisy-Chain
(2019/01/27 補充) 下二張圖是 SPI Daisy-Chain 部份的接線圖及其時序圖. 其中 SPI Master (MCU) 串接了二顆 Slave 晶片, Slave 晶片的指令/資料格式為 16 bits. 接線圖上我們標示了 ➀ ➁ 二個點, 就是後面時序圖的量測點. 時序圖中的 (DOUTM)DINS1 是 SPI Master (MCU) 的 MOSI 及 Slave1 的 MOSI (DIN) 輸入接腳連線上的時序 (接線圖上點 ➀ 所量測到的訊號), (DOUTS1)DINS2 是 Slave1 的 MISO (DOUT) 輸出接腳和 Slave2 的 MOSI (DIN) 輸入接腳連線上的時序 (接線圖上點 ➁ 所量測到的訊號).
SPI Daisy-Chain 連接 2 顆 slave 晶片
SPI Daisy-Chain 時序圖
(2顆 slave, data 16 bits)
如前面說的 Slave 晶片的指令/資料格式為 16 bits, 所以時序圖上的 Byte1 及 Byte2 二個合起來才是一組 16 bits 的 SPI 指令/資料. Byte3 及 Byte4 則是另一組. 由於 SPI 的電路結構使用的是串列位移暫存器, 所以我們其實可以把 Slave1 和 Slave2 合起來看, 變成一個長度為 32 bits 的串列位移暫存器 (點 ➀ 的時序圖). 由 Slave1 的觀點來看: 前 16 bits 資料 ( Byte1 及 Byte2) 當然是先把自己的串列位移暫存器填滿, 可是 Master 又接著送 Byte3 及 Byte4 進來, 所以先前的 Byte1 及 Byte2 就又都被擠出去給 Slave2 了. 由 Slave2 的觀點來看: 狀況看 Slave1 是一樣的, 只不過前 16 bits 是原先 Slave1 肚子裡的垃圾, 後 16 bits 才是由 Master 送來的 Byte1 及 Byte2.
所以 Master 送完 4 bytes 資料時, Slave1 收到了後二個 bytes, Slave2 收到了前二個 bytes. 接著 /SS 接腳訊號向上拉, Slave1 和 Slave2 一起把資料栓鎖, 開始解碼及相關動作.
總結 SPI Daisy-Chain 的注意事項有三:
- 傳輸時, 給遠端晶片 (離 MCU 的 MOSI 接腳比較遠的, 即 Slave2) 的資料要先送 (Byte1 及 Byte2), 再接著送給近端 (Slave1) 的資料 (Byte3 及 Byte4).
- 每一次傳輸都必需是完整的 N 組晶片所需的指令/資料 (N 為 Chain 裡的 slave 晶片數, 圖示為 N=2), 否則遠端晶片會收到別人的資料 (上一次傳輸所送出的資料), 產生不正確的動作.
- 還有一個狀況是除非晶片有支援 NOP (no operation) 的指令, 否則無法只針對 chain 裡其中一顆晶片下達指令/資料 (原因如上一項所述). 例如: 74HC595 就沒有 NOP 指令; 但是 MAX 7219/7221 就有 NOP 指令可用.
連結
SPI 參考文件
- SPI 設計指南 V4 (Revised: 14 JUL 2004): SPI Block Guid V04.01
- SPI 設計指南規範 V3 (Revised: 04 FEB 2003): SPI Block Guid V03.06
- SPI 設計指南規範 V2 (Revised: 06 MAR 2002): SPI Block Guid V02.06
I2C 的部份請參看:
- I2C 簡介: I2C bus 簡介 (Inter-Integrated Circuit Bus)
- 有關 I2C 提升電阻: I2C Bus 提升電阻之計算

功能簡單的東西,並不代表容易徹底瞭解, 謝謝你,花這麼多時間,寫的這麼詳細. 讓我對SPI 的認識更精進一步, 對我很有幫助. 謝謝啦.
不客氣, 真心希望對你有幫助. 如有誤謬煩請指正. 謝謝
清楚明瞭! 讚!!
謝謝!!
這篇和I2C那篇真是太有幫助了 謝謝你!
不客氣
感謝分享
不客氣
非常實用的一篇文章,讓我受益非淺,謝謝您。
不客氣
*****
*****
寫的真好!
多謝您的稱讚.
講解十分精闢!! 尤其在描述一些容易搞混的部分做了很棒的說明!!!
多謝稱讚. 希望大家能確實掌握 SPI.
感謝您寫這篇文章,讓對這方面沒什麼概念的我受益匪淺。
不客氣 有不明白地方, 歡迎提問.
感謝您整理之後用簡單的方式讓我能快速了解.
不客氣啊
太棒了, 感謝.
不客氣
超級詳細,太感謝了
不客氣呦 :)
非常詳細的解說! 想另外請教您 SCI與UART的區別? 搜尋國外的討論提到說兩個其實是一樣的只是叫法不同 想請問您的看法?
SCI 是 Motorola 獨規的東西,有點像有人把 UART 擴充成 USART 可以同步丶非同步通吃。 也有人把 SPI、I2C、UART 三者合併,反正三者都是一組 並列轉串列 加上 一組串列轉並列 再加上一堆控制邏輯的東西。 其實最主要是想讓使用者可以自由的依據需求調配,晶片廠則簡化 SoC 晶片的規格,不必猜到底哪種組合的使用者會多一點丶又有哪一種組合少一點? 如此而已
真的解說得非常詳細!!! 感謝您!!!!
:)
詳細說明,謝謝你的教學 另外請教SPI以及SPIM(Memory)的差異?
SPI 和 SPIM 二者並不是對等的東西 SPIM (memory) 應該只是利用 SPI 作為存取介面的記憶體晶片. 像是 SEEPROM (Serial Electrically-Erasable Programmable Read-Only Memory) 一般常見的就有 I2C 和 SPI 二種介面 而它只是把記憶體的存取介面設計改成接腳比較少的 I2C 或 SPI, 好讓電路 layout 佔用的面積可以縮小, 同時也不必佔用 MCU 太多接腳. 終究 SPIM 還是要依照 SPI 的規範來設計介面, 不然 MCU 或是其他要和它介接的晶片就會很麻煩
謝謝解說,受益很多. 請問圖2左半部若改為有4個spi slave,由於master之/ss只有2個,是否可用master之1個/ss輸出到解多工器,再將解多工器之4個輸出分別接到4個spi slave之/ss ?或者是將master之SCLK輸出到解多工器,再將解多工器之4個輸出分別接到4個spi slave之SCLK ?(之所以用解多工器是因為master一次只能與一個slave溝通往來,所以用解多工器一個一個輪流)
Sorry, 這兩天有事, 現在才回你 是的, 你所說的二個方法都可以 可能是我用的字眼不標準,我在圖片下方的第三段有提到用 “3to8” 解碼器, 其實說的就是用 de-multiplexer DEMUX 不過這二個方法都有但書: 方法一: 控制 /SS 要注意的是: 晶片的 /SS 和 SCLK接腳訊號規格. 是不是 /SS 為HI 時 SCLK 亂送都OK? (理論上應該是) 方法二: 控制 SCLK 則要注意高速 (20MHz以上) 傳輸時 DEMUX 晶片 對 SCLK 訊號產生的 delay 是否還在規格內 以上
很受用,謝謝您的分享:)
不客氣啊,:)
寫得很清楚 有基礎的了解了 非常感謝
:)
謝謝分享!很清楚
:)
Jack, You are so magic! 臨時被指派去支援SPI的問題. 透過你這篇詳細的文章, 讓我成功拿下救援點, 避免領便當. 謝謝囉.
這也是我寫部落格的用意啊! 不希望將來老了走了, 什麼都沒留下.
Hi Jack, 你的文章讓我迅速的了解SPI的相關知識,但其中還是有些問題想像你請教一下 1. 在motorola SPI Block Guid V03.06提到 back to back transfers,為什麼當CPHA = 0時,SS要先拉回做一個pulse才能繼續,而CPHA = 1則不用? 2. 為什麼當初motorola設計SPI時,要有CPHA 及 CPOL去設定,而不是一種規格就好? 還麻煩達人幫忙解惑,謝謝~
關於第一點, 你可能對它有所誤解了. 我的理解是: 1. CPHA=1 有支援 back to back transfers 所以 SS 可以不必拉回做一個 pluse. 2. 所謂 back to back transfers 是只有一個 master 對一個 slave, 而且沒有使用 SS 接腳來控制選擇 slave. 所以我在文中有提到對於某一些 slave 晶片來說這種接法是錯的 (因為使用者誤以為別的晶片可以這樣子接, 現在要用的這一顆應該也可以) 另外, 也有一些 MCU 的 master mode 實作不出沒有 gap 的 back to back transfer, 二組資料中間一定會出現一定時間的 delay. 關於第二點我也感覺有點困惑. 可能是設計過頭了? 也可能是電路剛好有這個特性, 所以也就不把它規定死, 而是讓使用者自己選擇?
Hi Jack, 所以關於 back to back 的問題是否要回歸於選擇 CPHA = 0或1 哪種mode的用意呢? 或是因為 CPHA = 0或1 的設計差異,導致只能在CPHA = 1的時候才能支援back to back ? 很抱歉一直向你詢問,但關於這個問題還是想要釐清一下原因,再麻煩你了,謝謝
1. 依據 4.4.2 CPHA=0: 是 /SS 一拉低, 第一個 bit 已經 ready 而且輸出了, 所以是先 latch 再 shift. (第一個 SCLK 改變時是 latch, 下一個是 shift.). 而且 /SS 拉低到第一個 SCLK 改變需要等半個 SCLK cycle. 2. 依據 4.4.3 CPHA=1: 則是 /SS 拉低後, 第一個 SCLK 改變拿來 shift out, 下一個 SCLK 改變拿來 latch data. 所以 /SS 拉低到第一個 SCLK 改變不必再等半個 SCLK cycle. 由以上描述 SPI 內部的工作應該是一個 SCLK edge 拿來 latch 資料, 下一個 edge 則來拿 shift 資料. 問題是哪一個先來而已. 當 CPHA=1 時: A. 在第16次 SCLK 改變是用來 latch data (第8個 bit). B. 之後有時間把下一組要傳的資料由 MCU 的 SPI Data Register 轉移到 SPI 的 shift out register, 於是第17次 SCLK 改變可以再 shift out. 但是, CPHA=0 時: A. 在第14次 SCLK 改變是用來 shift out data (第8個 bit). B. 在第15次 SCLK 改變是用來 latch data (第8個 bit). C. 第16次 SCLK 改變改經沒有 data 可以 shift out 了. D. CPHA=0 要支援 back to back transfer 除非在第15次 SCLK 改變時下一組資料由 MCU 的 SPI Data Register 轉移到 SPI 的 shift out register. 但是這樣子作就會使得下一組資料 SPI Data Register 轉移到 SPI 的 shift out register 的條件在 back to back 和非 back to back 二種模式下不一致, 所以 CPHA=0 時不支援 back to back 可以讓電路簡單一些. 以上.
Hi Jack, 謝謝你詳細的解釋,你部落格的存在真的給裸很多的助益,謝謝 相信很多人都能夠因為你的幫助下而成長
You're welcom. :)
感謝介紹
:)
Hi Jack, 關於圖4看得不是很懂 可否麻煩你做更多的解說
整段已經更新, 請參考.
Hi Jack 我想請教一下, Host端在接收MISO訊號時是參考哪端的CLOCK?Host side 還是 slave side?
Clock 就只有一個,哪來的要參考哪一邊的? :(
Hi Jack, 參考哪一邊的clock問題是, 假設我要量測Host side 的Setup time 跟Hold time, 我的clock該點在哪一邊?
1. 請參考 圖1. 你覺得 SCLK 靠近 master side 和靠近 slave side 會相差多少? 你的視波器可以解析到多快? 原則上二者的差異是幾乎等於零. 2. 除非你在線路中有加入其他元件來延伸 SPI 的路徑長度, 那麼你應該以 slave side 的 input 為量測點, 因為那才是 (比較接近) slave 端 "看" 到的訊號. 一般延伸 SPI 的路徑長度的元件都有規格書說明訊號上昇及下降的延遲, 並會直接了當的說明你的 SCLK 可以送到多快 (這個參數比較重要, 其他的應該都在 master 可調整的範圍內). 3. 當然, 如你前一個問題所問的要量 master 的 input (MISO), 在使用延伸 SPI 的路徑長度的元件之後, 我們要量測的訊號 (包含 SCLK) 應該都是靠 master 這一端. 4. 參考文件 http://www.ti.com/lit/an/slla142/slla142.pdf 以上
感謝版大幫忙解惑
不客氣! 寫 blog 很怕自己對技術認識不夠清楚, 也怕慱達了錯誤的資訊. 希望真的對你有幫助.
hi jack, daisy chain有個問題想詢問一下, 1.daisy所串接在一起的slave chip的length可否不相同,例如第一個slave是8 bits第二個slave是16 bits,如果可以這樣接的話,那我打write或read要怎麼傳輸呢? 2.前面有講到NOP,是如何直接控制某個slave呢?是沒有控制到的slave傳個全0訊號之類湊齊N-group這樣傳輸控制嗎? 麻煩了 感謝
1. daisy chain 使用時真的限制很多, 不過這些限制絕大部份並非來自硬體的限制, 而是趨動程式的問題. 想像一下, 如果你把 2 顆功能完全不同的 SPI 晶片串在一起, 可能會出現 上層的應用程式 A 在寫入 Chip1時, 應用程式 B 卻是需要執行 Chip2 的讀出動作. 這樣的組合不是不可以, 而是你得再多加一層 Queue 接收二個 Chip 的指令, 並多花許多心思去考慮 Queue1, 和 Queue2 中指令可能的組合, 並去除會有問題的 case..., 而且一換晶片組合就得重新來一遍, 底層的趨動程式也得跟著改, 徒然增加系統的複雜度又不容易維護. 所以一如我在文章中說的: "常見的應用 Daisy-Chain 的例子都是用來串連多個同一型號的晶片". 同時還有一個現象: 實際的應用以輸出型晶片為大宗 (因為不必管回讀的 case.) 2. 是的. 傳送指令時, 不需要動作的晶片所對應的指令要填入 NOP. 有支援 Daisy chain 的晶片都會支援 NOP 操作, 也真的都是用 0 來作為 NOP 指令.
hi jack, 非常感謝你的回答!! 從妳這篇文章學到許多spi的觀念,非常感謝你!!
不客氣! :)
Hello Jack, 看完這篇我想到=> 請問我們有辦法定期地對其中一個SS輸出data(0x01),來當成一個clock嗎? 我感覺是可行的,但頻率的部分就要自己再計算了 還請您回答了~麻煩了 感謝!
可以的, 如果你把 SPI driver 掛在 timer 中斷上的話 不過需要再多實作一組 Queue, 作為上層 SPI IO 需求和底層 driver 的緩衝, 並且在沒有確實 SPI IO 需求時 (Queue Empty 時) 自加送 NOP 指令, 這樣 /SS pin 就會有 '穩定' 的 pulse 輸出. 另外, 由於從 SPI input 資料不會馬上有結果回來, 上層的應用程式必需改成 '非同步' 模式才行 (除非可以接受讀回資料的時間差, 改由 driver 自動定時讀回放在 buffer 中, 上層應用程式則只使用 buffer 中的資料). 一般大型應用改成 '非同步' 模式應該 OK, 但是小型的 SoC 應用可能得不償失了 (需要修改程式的結構, 並加入一堆 library)
請問板大, 一主一從得 SPI 時假設 slave 可以接受SS直接接地, 那是否就可以直接接地就好? 另外那如果是一主多從的狀況是否就一定要將ss接上以確保傳輸的訊號正確被擷取到?
一主一從時, 如果 slave 可以接受 SS 直接接地, 就可以直接接地就好. 一主多從時, 通常是要將 SS 接上不同的 SS 來源, 不然就得用 daisy-chain 接法. 需要將 SS 接上不同的 SS 來源, 主要是為了確保 slave 晶片輸出的 MISO 線不會撞在一起 (其中一個變成三態的高阻抗狀態).
Dear Jack版大: 非常感謝您詳細的介紹! 關於介紹CPHA的部分: "CPHA 設定的是晶片栓鎖資料的時機是在 /SS 訊號下降之後...",想請問 1."栓鎖資料"應該是指接收端的行為吧? 2.該敘述中的"晶片"是單純指"Slave晶片"還是"接收端(無論Master or Slave)的晶片"呢? 謝謝!
Q1 Ans: 是 "接收端" 沒錯, 不過請注意: Master/Slave 是互為傳送接收端的, 參看圖 1. Q2 Ans: 解說的第一點: "SPI slave 晶片一般只支援一種工作模式...", 如果你有看懂這句話: Master 晶片才會是讓我們可以自由設定 CPHA=0 or 1, 還有 CPOL=0 or 1 啊! 我建議你找一顆有 SPI 介面的 MCU 仔細讀一下它的使用說明, 會比較容易弄懂. 我文章中說的那麼多個 '晶片', 到底哪個是指二個, 哪個是指 master, 哪個是指 slave. Sorry, 讓你有點混亂.
i Jack, 量測Master clock問題, 假設我要量測Host side 的Setup time 跟Hold time, clock探棒該點在哪一邊??? 因為當量 master 的 input (MISO), 在沒有使用延伸 SPI 元件, clock 部分探棒直接點在master 端(BGA 出pin)位置,看到訊號的波形改變很多,有注意到SPI路徑上連接的設備都有裝上,波形上看來受反射狀況導致,與slave端的不同, 這樣導致用SPI spec判斷示波準位時fail, 請問要如何處理? 或是當量 master input 時clock 是要改放在Slave 端?
你的問題應該在: >> 波形上看來受反射狀況導致,與slave端的不同 先把它解決了吧. 又不是在搞 '類比' 電路, 數位電路不應該有這些問題. 會出現這種問題應該是晶片接腳的 '功能' 設定錯誤 (大部份 host 端都能設定這個), 或者 '接腳' 的 '輸出/輸入方向' 及 '模式' 設定錯誤. 也有可能是應該要附加調整線路阻抗的電容及電阻, 但是你沒有接上(或者搞錯數值). 2020-02-26: 如果是一般的 SPI 介面 (20MHz 以下的版本) 應該是用不到調整線路阻抗的電容及電阻 (99.9% 實務上不需要, 除非 layout 走線太細太長), 高速的 SPI 介面才會要調整線路阻抗的電容及電阻. 2020-02-26: 如果二組晶片的工作電壓不同, 則請在中間安置一個電壓轉換電路. 2020-20-26: 還有嗎? ....想不出來了. '學軟體的' 還是要有一點基本電子電路的基本認識, 這樣才不會被誤導了 (二十年前我師傅教我的, 至今奉為圭臬)
簡單明瞭 棒
謝謝你的讚許 :)
100分
Thank you!
原本在搜尋引擎找出一堆 Blog 文章,不知哪幾篇值得花時間一看, 後來用 PTT搜尋引擎,輾轉看到您這的好文而有緣來到這, 謝謝您用心分享有價值的內容, 也回饋給您這實用的主題排名網站資訊,可查看與您 Blog 內容相關的排名好文,應該對寫 Blog 也有所幫助,期待您持續產出好文章 ^^ https://searchptt.cc/
感謝你. 可是, 不知你是用什麼 keyword 才找到這裡來的? 我試了一會兒, 不知要如何才能找到自己的文章? (orz 真的老了??...)
赞!写得非常详细专业,其中关于CPHA 的定义第一次看到,终于解答了我多年的疑惑,感谢!
謝謝捧場!!
傑克大大,剛好搜尋到這篇文章,收益良多 有些Daisy chain的問題想請教,是每一個SPI deive都支援Shift register buffer嗎?
是的 SPI 的設計就是以 shift register 為基礎. 同時在支援 Daisy Chain 的 SPI 晶片中, /SS 訊號的上升緣被用來當作 command/data lock (指令/資料栓鎖). 也就是 shift register 的後面還有一級 command/data buffer. 如此可使多個 SPI 晶片可以同步工作而不致於紊亂.
"所以 Slave 晶片在 SCLK 的下降緣栓鎖資料, 相對的 master 就必需要在上升緣送出資料. 反之, slave 晶片在 SCLK 的上升緣栓鎖資料, 相對的 master 就必需要在下降緣送出資料." 請問這樣做的目的是為了有足夠的setup time和hold time嗎? 另外,SPI是屬於push pull的output,理論上訊號不需要外接上拉電阻。 但大部分的晶片規格書上都會建議加10k~22k左右的上拉電阻。 請問這個電阻的用意是不是當作訊號的termination,以避免layout routing造成的訊號反射? 謝謝。
Q1: YES. Q2: 上拉電阻一般是為了確保開機及平時的電位狀態. 至於是不是 termination? 我不是很確定 (硬體部份不是我的主要工作範圍, 尤其是 EMI 部份) Sorry, 我沒有注意到你的留言, 所以現在才回你. (好像是網站的問題?)