UART VS I2C VS SPI

最近用 Raspberry Pi Pico 學習驅動連接 PCF8574 的 HD44780 及 MAX7219
因此要在 Raspberry Pi Pico 重新學習編寫 I 2 C 及 SPI
亦所以簡單介紹 I 2 C 及 SPI 的運作原理

UART 協定

UARTRXDTXDUARTRXDTXD

UART 引腳

UART 只需要使用
  • RXD(資料傳送)
  • TXD(資料接收)
便可以傳送及接收資料,但 UART 只能一對一傳送及接收資料
如果 MCU 需要同時控制多個 UART裝置(從機),便需要多組 資料傳送 及 資料接收
即是 MCU最少電路數量 = 2 * 總從機數量
不過實際上 UART 允許只讓 MCU 控制從機
即是 MCU最少電路數量 = 總從機數量

UART 速度

即是 Baud值,即是每秒內傳送訊息的次數
Baud值傳送間距(納秒)
9600104167
1920052083
3840026042
5760026042
7680013021
1152008681
2304004340
4608002170
5760001736
9216001085

UART 訊號

UART 使用 TXD 傳送訊號
  1. TXD 閒置狀態 為 高電壓
  2. 開始傳送訊號,將 TXD 設定為低電壓
  3. 根據從機要求,傳送資料指定數量的位元訊號, UART 支援 5位元 至 8位元
  4. 結束傳送訊號,將 TXD 設定為高電壓,即是閒置狀態
TXDRXD
為了確保訊號取樣準度度,通常會在訊號中間位置才執行下一個訊號
假設訊號傳送間距為 1毫秒,為了確保開始訊號正確
高電壓維持 9毫秒,便可以確保 資料訊號 及 完結訊號 完成並終止
確定終步後,傳送開始訊號
要讓訊號在中間位置,先將 TXD 保持在低電壓 0.5毫秒
然後 每1毫秒 傳送資料訊號,最後傳送 完結訊號 便完成整個過程

I 2 C 協定

MCUSCL0SDA0SCL1SDA1 I 2 C I 2 C Device 1Addr=0x00Device 2Addr=0x01Device 128Addr=0x7FDevice 1Addr=0x00Device 2Addr=0x01Device 128Addr=0x7F

I 2 C 引腳

I 2 C 只需要使用
  • SCL(序列時脈)
  • SDA(序列資料)
便可以傳送及接收資料

I 2 C 地址

最多支援最多 128個從機裝置
假如 主機 用盡 128個從機裝置 ,便需要另外 1組 序列時脈 及 序列資料
即是 MCU最少電路數量 = 2 * roundup(總從機數量 / 128)
不同型號 I 2 C 晶片都預先設置了地址範圍,不會用盡 128個地址
(地址需要授權費,晶片商未必會購買 128個地址)
例如:
  • PCA6107 為 0x18 ~ 0x1F
  • PCF8574 為 0x20 ~ 0x27
  • PCF8574A 為 0x38 ~ 0x3F
  • PCA9536 為 0x40 ~ 0x4F
  • PCA9538 為 0x70 ~ 0x73
  • PCA9539 為 0x74 ~ 0x77

I 2 C 速度

共有 6種模式:
  • 低速模式 10 Kbps
  • 標準模式 100 Kbps
  • 快速模式 400 kbps
  • 快速+模式 1 Mbps
  • 高速模式 3.4 Mbps
  • 超高速模式 5 Mbps

I 2 C 訊號

I 2 C 使用 最高有效位(Most Significant Bit(MSB)) 寫入或讀取資料,即是資料由 第n-1 至 第0 的 次序運作
及 序列時脈 以 低電壓 為 閒置狀態(Idle)

I 2 C 有 4個步驟
步驟名稱方向數量
1開始訊號輸入1
2地址訊號輸入1
3資料訊號輸入/輸出n
4結束訊號輸入1
I 2 C 開始訊號
I 2 C 需要觸發 開始訊號 才開始運作
要發送 開始訊號 ,先讓 序列時脈 保持 高電壓,再將 序列資料 由高電壓到低電壓
SCLSDA
SCL = 1;
SDA = 1;
delay
SDA = 0;
I 2 C 地址訊號
地址使用 7位元資料 ,即是由 第7至第1元位 作為 發送或接收的 地址訊號
第0元位 為設定 I 2 C 寫入(0) 讀取(1) 操作
最後 寫入一個 低電壓ACK訊號 便完成 地址訊號
SCLSDA
SCL = 0;
delay;
for i from 6 to 0 {
	SDA = 0 or 1;
	SCL = 1;
	delay;
	SCL = 0;
	delay;
}

SDA = write mode or read mode;
SCL = 1;
delay;
SCL = 0;
delay;

ack = SDA;
SCL = 1;
delay;
SCL = 0;
delay;
I 2 C 資料訊號
資料使用 8位元資料 ,即是由 第7至第0元位 作為 發送或接收的 資料訊號
最後 寫入或讀取一個 ACK訊號 便完成 資料訊號
資料訊號 可以發送或接收超過一次
SCLSDA
SCL = 0;
delay;
for i from 7 to 0 {
	SDA = 0 or 1;
	SCL = 1;
	delay;
	SCL = 0;
	delay;
}

ack = SDA;
SCL = 1;
delay;
SCL = 0;
delay;
I 2 C 結束訊號
當 I 2 C 完成資料發送或接收後,便要執行 結束訊號
要發送 開始訊號 ,先讓 序列時脈 保持 高電壓,再將 序列資料 由低電壓到高電壓
SCLSDA
SCL = 1;
SDA = 0;
delay;
SDA = 1;

SPI 協定

SPI 並列連接
並列連接 的優點是 微控制器 可以獨立控制每個不同的 SPI從機
但缺點是每增加一個 SPI從機 ,微控制器 便需要多一支 SS引腳
SPISCKMOSIMISOSS1SS2...SSnMCUDevice 1Device 2Device n
SPI 串列連接
串列連接 的優點是將連接的責任交給從機,降低 微控制器 線路的負擔
但缺點是需要傳送多次空訊號,才能將實際訊號送達 節點多 的 從機
SPISCKMOSIMISOSSMCUDevice 1Device 2Device n
不論 並列連接 還是 串列連接 ,SPI 最少使用
  • SCK(序列時脈)
  • MOSI(主機輸出從機輸入)
  • SS(從機選擇)
需要3條電路才可以傳送資料
如果要接收資料便需要 MISO(主機輸入從機輸出) 第4條電路

SPI 沒有從機上限,只要主機能夠選擇從機便可以將訊號及資料傳送到從機
即是 MCU最少電路數量 = 2 + 總從機數量 (+1)
沒有速度模式,速度介乎於 10 Mbps 至 80 Mbps 之間
(SPI 最慢的速度都比 I 2 C 的超高速模式還要快)

SPI 次序

SPI 區分 最高有效位 及 最低有效位 (Least Significant Bit (LSB)) 兩種次序
最低有效位即是資料由 第0 至 第n-1 的 次序運作

SPI 模式

SPI 有 2種極性(Polarity) 及 2種取樣(Phase) ,共 4種模式
極性 為 序列時脈 閒置(Idle) 的狀態
取樣 為
  • 低電壓時,當 序列時脈 由閒置轉變為運作時 獲取序列輸入的狀態
  • 高電壓時,當 序列時脈 由運作回到為閒置時 獲取序列輸入的狀態
模式極性取樣
0 (最常使用)
1
2
3

取樣低取樣高
極性低模式0
SSSCKMOSIMISO
data = 0;
SS = 0;
SCK = 0;
delay;
for i from 7 to 0 {
	MOSI = 0 or 1;
	SCK = 1;
	delay;
	data |= MISO << i
	SCK = 0;
	delay;
}
SS = 1;
模式1
SSSCKMOSIMISO
data = 0;
SS = 0;
SCK = 0;
delay;
for i from 7 to 0 {
	SCK = 1;
	delay;
	MOSI = 0 or 1;
	SCK = 0;
	delay;
	data |= MISO << i
}
SS = 1;
極性高模式2
SSSCKMOSIMISO
data = 0;
SS = 0;
SCK = 1;
delay;
for i from 7 to 0 {
	MOSI = 0 or 1;
	SCK = 0;
	delay;
	data |= MISO << i
	SCK = 1;
	delay;
}
SS = 1;
模式3
SSSCKMOSIMISO
data = 0;
SS = 0;
SCK = 1;
delay;
for i from 7 to 0 {
	SCK = 0;
	delay;
	MOSI = 0 or 1;
	SCK = 1;
	delay;
	data |= MISO << i
}
SS = 1;

SPI訊號衝突

當使用並列連接時,會將所有從機裝置的 MISO 都會連在一起傳回給 MCU
即使相同型號的晶片都有機會發出不同的訊號,導致訊號衝突
除非 MCU 不需要接收 從機 的訊號,否則 MCU 每次操作都應該只選取一個從機傳送資料

總結

從比較中會發現 I 2 C 即使使用 超高速模式,仍然不及 SPI 的低速度,因此經常發現很多電子產品都是使用 SPI
雖然比較下當裝置越多, SPI 便需要更多電路,但在受限制的平台上,所使用的裝置實際上不會太多

但如果不受限制的平台,例如 Arduino, Raspberry Pi 等平台
當要自製裝置時,便可能需要考慮不同協定的可行性
例如要接駁裝置多,但不需要速度快,便可以考慮 I 2 C ;接駁裝置少,但需要速度快,便可以考慮 SPI

參考資料