2022-08-14

UART VS I2C VS SPI

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

UART 協定

UART RXD TXD UART RXD TXD

UART 引腳

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

UART 速度

即是 Baud值,即是每秒內傳送訊息的次數
Baud值 傳送間距(納秒)
9600 104167
19200 52083
38400 26042
57600 26042
76800 13021
115200 8681
230400 4340
460800 2170
576000 1736
921600 1085

UART 訊號

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

I2C 協定

MCU SCL0 SDA0 SCL1 SDA1 I2C I2C Device 1 Addr=0x00 Device 2 Addr=0x01 Device 128 Addr=0x7F Device 1 Addr=0x00 Device 2 Addr=0x01 Device 128 Addr=0x7F

I2C 引腳

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

I2C 地址

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

I2C 速度

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

I2C 訊號

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

I2C 有 4個步驟
步驟 名稱 方向 數量
1 開始訊號 輸入 1
2 地址訊號 輸入 1
3 資料訊號 輸入/輸出 n
4 結束訊號 輸入 1
I2C 開始訊號
I2C 需要觸發 開始訊號 才開始運作
要發送 開始訊號 ,先讓 序列時脈 保持 高電壓,再將 序列資料 由高電壓到低電壓
SCL SDA
SCL = 1;
SDA = 1;
delay
SDA = 0;
I2C 地址訊號
地址使用 7位元資料 ,即是由 第7至第1元位 作為 發送或接收的 地址訊號
第0元位 為設定 I2C 寫入(0)讀取(1) 操作
最後 寫入一個 低電壓ACK訊號 便完成 地址訊號
SCL SDA
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;
I2C 資料訊號
資料使用 8位元資料 ,即是由 第7至第0元位 作為 發送或接收的 資料訊號
最後 寫入或讀取一個 ACK訊號 便完成 資料訊號
資料訊號 可以發送或接收超過一次
SCL SDA
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;
I2C 結束訊號
當 I2C 完成資料發送或接收後,便要執行 結束訊號
要發送 開始訊號 ,先讓 序列時脈 保持 高電壓,再將 序列資料 由低電壓到高電壓
SCL SDA
SCL = 1;
SDA = 0;
delay;
SDA = 1;

SPI 協定

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

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

SPI 次序

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

SPI 模式

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

取樣低 取樣高
極性低 模式0
SS SCK MOSI MISO
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
SS SCK MOSI MISO
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
SS SCK MOSI MISO
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
SS SCK MOSI MISO
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 每次操作都應該只選取一個從機傳送資料

總結

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

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

參考資料

沒有留言 :

張貼留言