最近用 Raspberry Pi Pico 學習驅動連接 PCF8574 的 HD44780 及 MAX7219
因此要在 Raspberry Pi Pico 重新學習編寫 I 2 C 及 SPI
亦所以簡單介紹 I 2 C 及 SPI 的運作原理
因此要在 Raspberry Pi Pico 重新學習編寫 I 2 C 及 SPI
亦所以簡單介紹 I 2 C 及 SPI 的運作原理
UART 協定
UART 引腳
UART 只需要使用
如果 MCU 需要同時控制多個 UART裝置(從機),便需要多組 資料傳送 及 資料接收
即是 MCU最少電路數量 = 2 * 總從機數量
不過實際上 UART 允許只讓 MCU 控制從機
即是 MCU最少電路數量 = 總從機數量
- RXD(資料傳送)
- TXD(資料接收)
如果 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 傳送訊號
- TXD 閒置狀態 為 高電壓
- 開始傳送訊號,將 TXD 設定為低電壓
- 根據從機要求,傳送資料指定數量的位元訊號, UART 支援 5位元 至 8位元
- 結束傳送訊號,將 TXD 設定為高電壓,即是閒置狀態
為了確保訊號取樣準度度,通常會在訊號中間位置才執行下一個訊號
假設訊號傳送間距為 1毫秒,為了確保開始訊號正確
高電壓維持 9毫秒,便可以確保 資料訊號 及 完結訊號 完成並終止
確定終步後,傳送開始訊號
要讓訊號在中間位置,先將 TXD 保持在低電壓 0.5毫秒
然後 每1毫秒 傳送資料訊號,最後傳送 完結訊號 便完成整個過程
假設訊號傳送間距為 1毫秒,為了確保開始訊號正確
高電壓維持 9毫秒,便可以確保 資料訊號 及 完結訊號 完成並終止
確定終步後,傳送開始訊號
要讓訊號在中間位置,先將 TXD 保持在低電壓 0.5毫秒
然後 每1毫秒 傳送資料訊號,最後傳送 完結訊號 便完成整個過程
I 2 C 協定
I 2 C 引腳
I 2 C 只需要使用
- SCL(序列時脈)
- SDA(序列資料)
I 2 C 地址
最多支援最多 128個從機裝置
假如 主機 用盡 128個從機裝置 ,便需要另外 1組 序列時脈 及 序列資料
即是 MCU最少電路數量 = 2 * roundup(總從機數量 / 128)
不同型號 I 2 C 晶片都預先設置了地址範圍,不會用盡 128個地址
(地址需要授權費,晶片商未必會購買 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)
及 序列時脈 以 低電壓 為 閒置狀態(Idle)
I 2 C 有 4個步驟
| 步驟 | 名稱 | 方向 | 數量 |
|---|---|---|---|
| 1 | 開始訊號 | 輸入 | 1 |
| 2 | 地址訊號 | 輸入 | 1 |
| 3 | 資料訊號 | 輸入/輸出 | n |
| 4 | 結束訊號 | 輸入 | 1 |
I 2 C 開始訊號
I 2 C 需要觸發 開始訊號 才開始運作
要發送 開始訊號 ,先讓 序列時脈 保持 高電壓,再將 序列資料 由高電壓到低電壓
要發送 開始訊號 ,先讓 序列時脈 保持 高電壓,再將 序列資料 由高電壓到低電壓
SCL = 1; SDA = 1; delay SDA = 0;
I 2 C 地址訊號
地址使用 7位元資料 ,即是由 第7至第1元位 作為 發送或接收的 地址訊號
第0元位 為設定 I 2 C 寫入(0) 或 讀取(1) 操作
最後 寫入一個 低電壓ACK訊號 便完成 地址訊號
第0元位 為設定 I 2 C 寫入(0) 或 讀取(1) 操作
最後 寫入一個 低電壓ACK訊號 便完成 地址訊號
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訊號 便完成 資料訊號
資料訊號 可以發送或接收超過一次
最後 寫入或讀取一個 ACK訊號 便完成 資料訊號
資料訊號 可以發送或接收超過一次
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 完成資料發送或接收後,便要執行 結束訊號
要發送 開始訊號 ,先讓 序列時脈 保持 高電壓,再將 序列資料 由低電壓到高電壓
要發送 開始訊號 ,先讓 序列時脈 保持 高電壓,再將 序列資料 由低電壓到高電壓
SCL = 1; SDA = 0; delay; SDA = 1;
SPI 協定
SPI 並列連接
並列連接 的優點是 微控制器 可以獨立控制每個不同的 SPI從機
但缺點是每增加一個 SPI從機 ,微控制器 便需要多一支 SS引腳
但缺點是每增加一個 SPI從機 ,微控制器 便需要多一支 SS引腳
SPI 串列連接
串列連接 的優點是將連接的責任交給從機,降低 微控制器 線路的負擔
但缺點是需要傳送多次空訊號,才能將實際訊號送達 節點多 的 從機
但缺點是需要傳送多次空訊號,才能將實際訊號送達 節點多 的 從機
不論 並列連接 還是 串列連接 ,SPI 最少使用
如果要接收資料便需要 MISO(主機輸入從機輸出) 第4條電路
- SCK(序列時脈)
- MOSI(主機輸出從機輸入)
- SS(從機選擇)
如果要接收資料便需要 MISO(主機輸入從機輸出) 第4條電路
SPI 沒有從機上限,只要主機能夠選擇從機便可以將訊號及資料傳送到從機
即是 MCU最少電路數量 = 2 + 總從機數量 (+1)
沒有速度模式,速度介乎於 10 Mbps 至 80 Mbps 之間
(SPI 最慢的速度都比 I 2 C 的超高速模式還要快)
即是 MCU最少電路數量 = 2 + 總從機數量 (+1)
沒有速度模式,速度介乎於 10 Mbps 至 80 Mbps 之間
(SPI 最慢的速度都比 I 2 C 的超高速模式還要快)
SPI 次序
SPI 區分 最高有效位 及 最低有效位 (Least Significant Bit (LSB)) 兩種次序
最低有效位即是資料由 第0 至 第n-1 的 次序運作
最低有效位即是資料由 第0 至 第n-1 的 次序運作
SPI 模式
SPI 有 2種極性(Polarity) 及 2種取樣(Phase) ,共 4種模式
極性 為 序列時脈 閒置(Idle) 的狀態
取樣 為
極性 為 序列時脈 閒置(Idle) 的狀態
取樣 為
- 低電壓時,當 序列時脈 由閒置轉變為運作時 獲取序列輸入的狀態
- 高電壓時,當 序列時脈 由運作回到為閒置時 獲取序列輸入的狀態
| 模式 | 極性 | 取樣 |
|---|---|---|
| 0 (最常使用) | 低 | 低 |
| 1 | 低 | 高 |
| 2 | 高 | 低 |
| 3 | 高 | 高 |
| 取樣低 | 取樣高 | |
|---|---|---|
| 極性低 | 模式0 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 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 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 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 每次操作都應該只選取一個從機傳送資料
即使相同型號的晶片都有機會發出不同的訊號,導致訊號衝突
除非 MCU 不需要接收 從機 的訊號,否則 MCU 每次操作都應該只選取一個從機傳送資料
總結
從比較中會發現 I 2 C 即使使用 超高速模式,仍然不及 SPI 的低速度,因此經常發現很多電子產品都是使用 SPI
雖然比較下當裝置越多, SPI 便需要更多電路,但在受限制的平台上,所使用的裝置實際上不會太多
雖然比較下當裝置越多, SPI 便需要更多電路,但在受限制的平台上,所使用的裝置實際上不會太多
但如果不受限制的平台,例如 Arduino, Raspberry Pi 等平台
當要自製裝置時,便可能需要考慮不同協定的可行性
例如要接駁裝置多,但不需要速度快,便可以考慮 I 2 C ;接駁裝置少,但需要速度快,便可以考慮 SPI
當要自製裝置時,便可能需要考慮不同協定的可行性
例如要接駁裝置多,但不需要速度快,便可以考慮 I 2 C ;接駁裝置少,但需要速度快,便可以考慮 SPI