---
title: SPI 界面解密 — PART 4
description: "**作者：Bird** 上篇文章[【Maker電子學】SPI 界面解密—PART…"
url: "https://makerpro.cc/docs/spi-interface-part-4/"
updated: "2025-05-09"
category: SPI
---

# SPI 界面解密 — PART 4

**作者：Bird**

上篇文章[【Maker電子學】SPI 界面解密—PART 3](https://makerpro.cc/2020/04/spi-interface-part3/)，我們詳細說明了 SPI 工作時的波形，以及它的各種變化，這次我們要用一個實際的例子來看看週邊裝置如何透過 SPI 與 MCU 溝通。

### **MCP3008**

我們要拿來當作範例的 SPI 週邊，是一顆叫做 MCP3008 的 10-bit 類比數位轉換晶片（A/D converter）。這顆 ADC 晶片是 Microchip 的產品，由於它很容易使用，速度也不差，常用在 Raspberry Pi 上作爲類比訊號的輸入界面，用以彌補 Raspberry Pi 先天沒有類比輸入界面的遺憾。

 [![](https://makerpro.cc/wp-content/uploads/2020/04/MCP3008.jpg)](https://makerpro.cc/wp-content/uploads/2020/04/MCP3008.jpg)

MCP3008（[Source](https://ricelee.com/product/MCP3008-IC)）

我們先簡單來看一下 MCP3008 的規格。它有 8 個 channel 的輸入（但是同時只能選一個來用）、在 5 V 供電的情況下可以達到最快 200 K samples/sec 的取樣及轉換速度、10-bit 的解析度、以及最大 +/-1 LSB 的非線性。

關於它的轉換速度，我們來看看它的 datasheet：

 ![](https://makerpro.cc/wp-content/uploads/2020/04/1-20.png)

（圖片來源：Bird 提供）

在 V~DD= 5 V 時，最快可以到 200 Ksps，也就是每秒做 20 萬次取樣、轉換；V~DD= 3.3 V 時它的動作會慢一點，只能跑到 75 Ksps。重點來了，它的取樣時間是 1.5 個 clock cycles，轉換時間是 10 個 clock cycles，但是 MCP3008 的電路中其實並沒有外加的 clock source，那麼這裡的 clock cycle 指的到底是什麼 clock 呢？

MCP3008 是所謂的「同步轉換型 ADC」，它的轉換動作與界面的動作是同步綁在一起的，因此這裡 conversion time 的 10 clock cycles，其實指的就是 SPI 上的 10 個 clock；換句話所，MCP3008 的 A/D 轉換速度完全由 SPI 界面的速度來控制。

### **訊號與連接**

MCP3008 使用的是四線式的 SPI，但它的訊號命名與我們之前介紹的有點不同。它的 MOSI 叫做 D~IN（data in 的意思）、MISO 稱為 D~OUT、Slave select 叫做 CS（意思是 chip select），一樣是低電位動作。

MCU 與 MCP3008 的 SPI 連接如下圖：

 ![](https://makerpro.cc/wp-content/uploads/2020/04/1-21.png)

（圖片來源：Bird 提供）

爲了避免混肴，以下介紹時序都用 MCP3008 的訊號命名。

### **時脈圖中的細節**

我們來看一下 MCP3008 的 SPI 時脈圖和轉換的關係吧！

 ![](https://makerpro.cc/wp-content/uploads/2020/04/1-22.png)

（圖片來源：Bird 提供）

先看 D~IN 與 CLK 的關係。從圖中可以看出來，每個 bit 都是在 CLK 的上升緣取樣，接著再看 CS 與 CLK 的關係，我們第一個有效的資料位元 start bit 在 CS 下降後的第一個 CLK 變化瞬間取樣，因此我們可以知道這個 SPI 的時序是：

- CPHA = 0
- CPOL = 0

事實上這也是四線式 SPI 最常見的時序（如果不清楚 CPHA 和 CPOL 是什麼，趕快翻一下[上一篇文章](https://makerpro.cc/2020/04/spi-interface-part3/)複習一下唷！）。

接下來要來看控制訊號的輸入和轉換資料的輸出。當 CS 下來到 low，會叫醒 MCP3008 請它準備工作時，第一個透過 D~IN 送過去的 bit 就是 start bit，這是個固定爲 1 的 bit，用意也是叫 MCP3008 準備開始工作，但明明前面 CS 訊號已經叫它準備開工了，爲什麼還要多一個 start bit 呢？這跟 SPI 的非典型時序有關（這裡先賣個關子，後面會解釋）。

緊接著 start bit 後，是四個 bit 的控制訊號，其中包含一個 bit 的 SGL/DIFF，用來控制 MCP3008 是要用單端（single-end）還是差動（differential）模式輸入。其實 MCP3008 可以將相鄰的兩個輸入當作一組差動輸入來用，而它的極性（也就是誰正誰負）也是可以設定的，另外有三個 bit 的 channel number，是用來選擇使用哪一個輸入的。

MCP3008 總共有 8 個輸入， single-end 模式下 8 個輸入可以任意選擇，而在 differential 模式下，則是相鄰的兩個輸入爲一組，總共有 4 組可以選，每一組又有正反兩種極性，所以也是 8 個組合，剛好用 3 個 bit：D0、D1、D2 來設定。

包含 start bit 及 4 個 bit 的控制訊號從 D~IN 送入 MCP3008 後，D~IN 就功成身退了，之後雖然 clock 訊號會繼續跑，但 MCP3008 不會再從 D~IN 上讀取任何資料。

接著，從第 5 個 clock 的後半以及下一個 clock，也就是 CS 下降後的第 6 個 clock，MCP3008 會對設定的輸入做取樣。「取樣」是數位訊號處理上很特殊的一個概念，它的意思是 MCP3008 這一次的轉換，所取的就是現在這個 moment 所指定輸入上的狀態；換句話說，在第 5 個 clock 後半及第 6 個 clock 的這段時間，選定輸入 channel 上的電壓後，一會就會被轉換成數字，從 SPI 上被送出去。

我們前面說過，MCP3008 的 t~SAMPLE（也就是取樣時間）需要 1.5 個 clock，事實上指的就是 SPI 的第 5 個 clock 後半段以及第 6 個 clock；雖然整體轉換、讀出的時間長達十多個 clock cycle，但我們讀到的，就是這短短 1.5 個 clock 中的狀態。

接著，clock 繼續跑，D~OUT 上會開始吐出資料。首先會先吐出一個無關緊要的 bit，稱之爲 null bit，它沒有任何意義，接下來就會是 10 個 bits 的轉換資料，會先從 MSB 開始，B9、B8、B7 依序一直到 B0。在讀取 B0 的那個 clock 結束後，CS 會上升，結束這 1+4+1+1+10 共 17 個 clock 的轉換週期，讓一切歸於平靜。

此時，如果要繼續發起下一次轉換，CS 必需要維持至少一小段時間的 high，讓 MCP3008 休息喘口氣，才能再次變 low，開始下一個轉換週期。這段最短休息時間在圖上用 t~CSH表示，根據 datasheet 上的 timing 規格，它至少要 27 0ns，在大部分的狀況下，我們可以用一個 clock cycle 來代表它，因此可以說，MCP3008 的一次轉換週期總共需要 18 個 SPI clock cycles。

在這 18 個 clock cycles 中，總共傳了 5 個 bit 進去、10 個 bit 出來，還有 3 個沒有傳資料的 clock。

### **8-bit 的魔咒**

那...我們上次不是說過，SPI 的資料傳輸都必須以 8-bit，也就是 byte 爲基本單位嗎？MCP3008 怎麼會有這種 5 個 bit、10 個 bit、18 個 bit 的傳輸週期呢？

事實上經過多年的發展，現在確實有很多週邊晶片會使用像 MCP3008 這樣，不是以 byte 爲基本單位的 SPI 傳輸，但由於大部分的 MCU 仍然遵循以 byte 爲單位的 SPI 傳輸，MCP3008 也設計了一套可以用 byte 爲單位傳輸的時序。

而這整件事情的奧祕，就在於我們前面提到，看似無用的「start bit」。

根據前面的說明，在整個 CS 爲 low 的期間，SPI 的 clock 總共動了 17 個 cycle，也就是有 17 個 data bits 在 17 個 clock 的上升緣被讀入或讀出。

爲了要讓這整件事情可以用 8 的倍數運作，我們在這 17 個 bit 前面再補 7 個 bit，讓它變成總共 17 + 7 = 24 bits，就剛好是 3 個 bytes。如此一來，就變成 CS 下降之後，我們可以用標準的 SPI 界面同時對 MCP3008 寫入和讀取 3 個 bytes（還記得嗎？SPI 因爲有 MISO 和 MOSI 兩根線各自負責讀寫，所以是全雙工的，讀和寫可以同時發生）。

 ![](https://makerpro.cc/wp-content/uploads/2020/04/1-23.png)

（圖片來源：Bird 提供）

我們先看 D~IN 上寫入 MCP3008 的資料。前面補上的 7 個 clock，D~IN 全部填上 0，接著後面就跟著永遠爲 1 的 start bit 及 4 個控制 bit，再接下來的 11 個 clock，如同前面所說的，由於該寫的都寫完了，D~IN 上的狀態不再重要，這裡要送什麼都無所謂。

巧妙的地方就在這裡：MCP3008 會等到收到 D~IN 上的 start bit 才開始接收 control bit 並開始工作，因此在 start bit 前面補的 7 個 0 其實會被 MCP3008 完全忽略，直到第 8 個 clock（也就是 start bit），才開始照著前面說明的時序運作，這也就是前面說需要一個看似無用的 start bit 的原因。

至於 D~OUT 上，我們一樣可以從 CS 被拉下來就開始讀取，連續讀 24 bits 或 3 bytes，不過 MCP3008 會一直等到第 15 個 clock 才開始吐資料出來；也就是說，它輸出的資料會位在第 15 到第 24 總共 10 個 clock 上。

我們把送出去和讀回來的這 3 個 bytes 排列一下，就可以知道要送要收的資料位在這 3 個 bytes 的哪一個 bit 了：

 ![](https://makerpro.cc/wp-content/uploads/2020/04/1-24.png)

（圖片來源：Bird 提供）

那麼我們就可以巧妙地將資料安排在 24 個 clock 中，利用標準的 3 個 byte SPI 傳輸來控制 MCP3008 完成一次轉換。

不過其實當我們爲了遷就標準 SPI 時序這麼做時，其實我們浪費了 7 個 clock 的時間在餵沒有用的資料給 MCP3008，因此如果我們想要追求 MCP3008 的最大轉換速率，這樣無疑是在拖慢速度。

事實上由於 SPI 只是個很簡單的 shift register，如果 MCU 的 I/O 速度允許，有時候用軟體控制 GPIO 實作而成的 bit-bang SPI 不見得會比硬體的 SPI 慢，而且也不用受到 8-bit 爲一個傳輸單位的限制，可以直接實作出 17 個 clock 的傳輸週期。

### **小結**

關於 SPI 的介紹，我們大概就說到這邊。SPI 只定義了傳輸的訊號該長什麼樣子，並沒有標準化的裝置地址或標準的 register number 等協定，所以其實算是個相對簡單的界面（實作的細節都藏在界面晶片的規格中，而且可能各不相同）。

下一回我們要開始來聊 I2C，它大概是我們所介紹的這三個界面中最複雜、最博大精深的一個了，我們下回見！

（責任編輯：賴佩萱）
