先前花了兩篇文章的篇幅談了非接觸式的溫度感測器,再讓我們回到通訊介面的題目吧!這次的主角是歷久彌新的 SPI 通訊介面。
作者 | Bird,本文經Makerpor同意轉載,原文連結 |
歷史悠久的 SPI
SPI 的歷史可以回溯到 1980 年代初期,當時 Motorora 仍然是微處理器市場上的主要供應商(後來 Motorola 在 2004 年將半導體事業部拆分,成立 Freescale 飛思卡爾半導體,Freescale 又在 2015 年賣給 NXP 恩智浦半導體)。Motorola 在 8-bit 的微控制器(MCU)68HC11 上首度加上了這個四隻腳的介面,並稱之為 SPI:
上圖是 1985 年出版的 MC68HC11 datasheet 中,關於這個微控制器的方塊圖(SPI 旁邊的 Serial Communication Interface 其實就是 UART),直到今日我們仍然可以在 NXP 半導體的網站上找到這份文件的最新版,而且這個零件目前還持續在生產,仍有大量的車用電子裝置跑在這個平台上。
Motorola 當年設計 SPI 的用意,主要是為了用串列介面的方式減少連接周邊裝置時所需要的接腳數量,SPI 的全名 Serial Peripheral Interface 就是這麼來的,在當年被視為一個「高速」的介面,在 68HC11 上它的 clock 可以跑到 MCU 主頻的一半(初代 68HC11 的速度大約是 1 MHz 左右),且由於它同步傳輸的設計,只要驅動電路推得動、EMI 沒有太誇張,它的速度可以隨著半導體製程的進步與速度的提升,不斷提高。
Arduino UNO 上的 SPI 可以跑到 8 MHz,而在更高階的平台上,如果使用 ESP8266,因爲 CPU 主頻高達 80 或 160 MHz,SPI 甚至可以輕易跑到數十 MHz 以上。
仍然是串列界面
我們第一次談 UART 界面時,曾經說過串列通訊的原始精神是:「把一整排的資料按照順序排列,逐一送到遠方,接收方再用同樣的順序將資料排回去」。
SPI 就是基於這個精神設計出來的界面。當年的微處理器或微控制器都是 8-bit 的,因此用並列界面傳輸資料,一次就會用掉 8 根線,但如果我們用移位暫存器將資料排成串列再依序送出,到了目的地再用移位暫存器將資料排回來,就只需要 data 和 clock 兩個訊號(也許再加上重設移位暫存器的 reset 訊號)。
用這個方法,不管你要傳 8 bits、16 bits、24 bits,還是 32 bits,都只需要三根線。由於 SPI 是在 8-bit 微處理器的年代設計出來的界面,它的所有傳輸都是以 8-bit 爲基本單位(如果你要傳 16 bits,就必須傳兩次;要傳 24 bits,就要傳三次;要傳 18 個 bits,還是得傳 三 次,然後再把多出來的 6 個 bits 丟掉)。
有了移位暫存器的概念後,我們就來看看實際的 SPI 訊號結構。SPI 是典型的主從式(master-slave)通訊架構,它可以是有多個裝置的 bus 形式,但是整個 bus 上只能有一個老大,稱之爲 master,其它的裝置都稱爲 slave。
(註:master、slave 這樣的詞彙廣泛用於各種有鮮明角色區別的通訊架構上,尤其在硬碟還是 IDE 界面的年代,一個硬碟排線上可以接兩台硬碟,一台叫 master、另一台則是 slave。2003 年加州的洛杉磯郡政府還以這樣的字眼帶有歧視意味爲由,要求電腦設備製造商改善,不應再使用 master、slave 這樣的詞彙。)
SPI 的角色與訊號
master 是整個 bus 上的主控者,它負責提供移位暫存器的 clock,並且決定要和哪個裝置通訊、發起傳輸。SPI 是全雙工的雙向界面,master 可以送資料到 slave,slave 也可以送資料到 master,而且兩路可以同時進行,因此這兩條路徑各自有其專屬的訊號:由 master 送往 slave 的資料線,稱之爲 MOSI(master out slave in)、由 slave 送往 master 的資料線,則稱爲 MISO (master in slave out)。
除了 MOSI、MISO、CLK 外,還有一個訊號稱為 SS,意思是 slave select,就是在多個 slave 裝置之間用來選擇要和哪一個 slave 通訊的訊號。如果系統中只有一個 slave 裝置,在某些狀況下可以不需要 SS,但大部分的裝置仍然需要 SS 訊號來作為傳輸的起始訊號。
上圖是 SPI bus 一對一以及一對多的連接方法。可以看到 MOSI、MISO、CLK 三條線是各自接在一起的;由於 MOSI 和 CLK 是由 master 送往所有的 slave,屬於一對多的傳輸,只要 master 的驅動能力夠且slave 的輸入阻抗夠高,這種接法不會有什麼問題。
但 MISO 必須要全部接在一起,這就會有其他特別的考量,因爲 MISO 是多個 slave 接到一個 master,而 slave 是輸出、master 是輸入,因此這根線上會有多個輸出;如果有兩個 slave 同時送訊號,就會產生邏輯訊號衝突的狀況,這該怎麼辦呢?這時候就輪到 SS 訊號上場了!
SPI 的 master 會爲每一個 slave 準備一根 SS 訊號,且只有被 SS 選到的 slave 可以操控 MISO 腳,其它沒被選到的 slave 必須要將 MISO 變爲高阻抗狀態(注意:不是 high、不是 low,只能是高阻抗,就像它沒有接在這根線上一樣),這是多裝置的 bus 很重要的一個觀念:「一次只能有一個裝置驅動 bus,否則就會有邏輯訊號衝突的問題」。
大部分的 SPI slave 裝置都支援用 SS 控制 MISO 的動作與否,但仍有少部分的晶片或裝置不支援這種工作狀態,而這種不支援 MISO 高阻抗狀態的裝置就不能用在 multi-slave 的 SPI bus 中。
小結
這次我們聊了 SPI 界面的基本原理、裝置的角色以及需要用到的訊號,下回我們再繼續深入探討這些訊號的協定、格式,以及它們的電氣特性。
*本文經Makerpor同意轉載,特此感謝