I2C(唸作 i squared c),全名是 Inter-Integrated Circuit。是一種序列通訊協定,在低速周邊當中常常使用。
上一篇我們提到了 UART,然而 UART 因為沒有 clock 信號的關係,需要雙方事先決定好 Baud rate,否則沒辦法正確解析資料,而且 UART 一次用在一組裝置(一對一)。
I2C 是一種多主從架構,使用兩條線來傳輸,一條為傳輸資料的線(通常稱作 SDA),另外一條則是傳送停止與開始信號以及時脈的線(SCL)。
在實際應用當中,有些感測器的組成比較複雜,直接讀取數據可能對 MCU 來說不容易,因此這類型的感測器會另外集成一個 I2C 的電路,對 MCU 來說,只要發送對應的指令碼,感測器就會回傳對應的資料,省下 MCU 自己測量感測器的步驟。
接下來介紹一下 I2C 的實際運作:
每次傳完 8bit 的資料時,會發送一個 1bit 的 ACK 信號。
(圖片取自維基百科)
像是溫度感測器、LCD 螢幕這類型的周邊設備,如果要求的頻率不高時,透過 I2C 來收發資料很方便。
在 Arduino 當中,I2C 被包裝成 Wire.h
,只要引入這個函式庫即可使用。
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
}
byte x = 0;
void loop()
{
Wire.beginTransmission(4); // transmit to device #4
Wire.write("x is "); // sends five bytes
Wire.write(x); // sends one byte
Wire.endTransmission(); // stop transmitting
x++;
delay(500);
}
比較常見的 API 有:
beginTransmission
:開始傳送write
:傳送資料。這邊 Arduino 會幫你處理 8bit 送 ACK 的邏輯endTransmisstion
:結束傳送跟 UART 不一樣的地方是,I2C 可以任意選擇兩個 GPIO 接腳當作 SDA 與 SCL,使用上比較有彈性一些。
背後的運作與上篇 UART 提到的有點類似,以 AVR 來說,背後都是由數個暫存器來保存狀態,發送與接收的 buffer 等等,這邊就不另外解說。