概要
I2C(Inter-Integrated Circuit:アイ・スクエア・シー、またはI2Cと読む)は、フィリップス社(現NXP)が1982年に開発した2線式の同期シリアルバスプロトコルです。SDA(シリアルデータ)とSCL(シリアルクロック)の2本のワイヤだけで、マスターデバイスと複数のスレーブデバイスを接続できる「マルチスレーブ」アーキテクチャが特徴です。
組み込みシステムでは、温湿度センサー・気圧センサー・IMU(加速度・ジャイロセンサー)・EEPROMなど、多数のセンサーや周辺デバイスをI2Cで接続するのが一般的です。7ビットアドレスを使うため、理論上は128個(実際は112個)のデバイスを1本のバスに接続できます。
通信速度は標準モード(100kbps)、ファストモード(400kbps)、ファストモードプラス(1Mbps)、ハイスピードモード(3.4Mbps)の4段階があり、用途に応じて選択します。
歴史・背景
I2Cはフィリップス・セミコンダクターが1982年にテレビのコンポーネント間通信を目的として開発しました。当初は100kbpsの「スタンダードモード」のみでした。1992年に仕様がVersion 2.0として公開され、400kbpsの「ファストモード」が追加されました。
1998年にはバージョン2.1でハイスピードモード(3.4Mbps)が追加。2007年のVersion 3.0では10ビット拡張アドレス対応が強化されました。2012年のVersion 4.0ではUltra Fast-mode(UFm、単方向5Mbps)も規定されています。
フィリップスがかつて特許を持っていたため、「TWI(Two-Wire Interface)」という別名でAVRマイコン(Atmel)が採用していた時代もあります。現在はNXPが知的財産を管理しており、スペック文書を公開しています。
技術仕様
速度モード
| モード | 速度 | 略称 |
|---|---|---|
| スタンダードモード | 100 kbps | Sm |
| ファストモード | 400 kbps | Fm |
| ファストモードプラス | 1 Mbps | Fm+ |
| ハイスピードモード | 3.4 Mbps | Hs |
| ウルトラファストモード | 5 Mbps(単方向) | UFm |
アドレス体系
- 7ビットアドレス: 最大112デバイス(0x00〜0x07, 0x78〜0x7Fは予約)
- 10ビットアドレス: 最大1008デバイス(拡張仕様)
代表的なデバイスのI2Cアドレス(7ビット):
| デバイス | アドレス |
|---|---|
| MPU-6050(IMU) | 0x68 または 0x69 |
| BME280(温湿度・気圧) | 0x76 または 0x77 |
| ADS1115(ADC) | 0x48〜0x4B |
| OLED SSD1306 | 0x3C または 0x3D |
| AT24CXX EEPROM | 0x50〜0x57 |
電気的特性
- 電圧レベル: 3.3V系または5V系(バス電圧はプルアップ電源に依存)
- プルアップ抵抗: 必須(外付け)。標準は4.7kΩ(100kbps)、1kΩ(400kbps)
- バス容量: 最大400pF(Smモード・Fmモード)
- ドライブ方式: オープンドレイン(Wired-AND)
オープンドレイン構成により、複数デバイスが同じバスラインをLowに引き下げることができます。これがI2Cの「Wired-AND」バスと呼ばれる理由です。
動作原理
トランザクションの基本構造
[スタート条件] [アドレス(7bit) + R/W(1bit)] [ACK] [データ(8bit)] [ACK] ... [ストップ条件]
スタート条件(START): SCLがHighの間にSDAがHighからLowへ変化 ストップ条件(STOP): SCLがHighの間にSDAがLowからHighへ変化 アクノレッジ(ACK): 受信側が9クロック目にSDAをLowに引き下げることで「受信OK」を返す
書き込みトランザクション例
Master→Slave: スタート → 0x68<<1|W → ACK → レジスタアドレス(0x6B) → ACK → データ(0x00) → ACK → ストップ
読み取りトランザクション例(Repeated START)
Master→Slave: スタート → 0x68<<1|W → ACK → レジスタアドレス(0x3B) → ACK
Master→Slave: リピートスタート → 0x68<<1|R → ACK
Slave→Master: データ1 → ACK → データ2 → ACK → ... → データN → NACK
Master: ストップ
// STM32 HALを使ったI2C通信例(MPU-6050初期化)
#define MPU6050_ADDR (0x68 << 1) // HALはアドレスを1ビット左シフト
#define PWR_MGMT_1 0x6B
// スリープ解除(PWR_MGMT_1レジスタへ0x00書き込み)
uint8_t data = 0x00;
HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, PWR_MGMT_1,
I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY);
// 加速度データ読み取り(6バイト)
uint8_t accel_buf[6];
HAL_I2C_Mem_Read(&hi2c1, MPU6050_ADDR, 0x3B,
I2C_MEMADD_SIZE_8BIT, accel_buf, 6, HAL_MAX_DELAY);
// 16ビット値に結合
int16_t ax = (int16_t)(accel_buf[0] << 8 | accel_buf[1]);
int16_t ay = (int16_t)(accel_buf[2] << 8 | accel_buf[3]);
int16_t az = (int16_t)(accel_buf[4] << 8 | accel_buf[5]);
クロックストレッチング
スレーブデバイスが処理に時間がかかる場合、SCL線をLowに保持してマスターを待機させる「クロックストレッチング」機能があります。すべてのマスターがこれに対応しているわけではないため注意が必要です。
マルチマスター調停
複数のマスターが同時に送信を開始した場合、「バス調停(アービトレーション)」によって一方が優先されます。SDAをHighに出力したつもりがLowを検出した場合、そのマスターは送信を停止します。これにより衝突なく共存できます。
用途・ユースケース
I2Cが特に適した用途:
- センサーネットワーク: BME280(温湿度・気圧)、MPU-6050(IMU)、BH1750(照度)などをまとめて1本のI2Cバスに接続
- 低速EEPROM: 設定値や校正データの保存(AT24C系EEPROM)
- 小型ディスプレイ: SSD1306 OLEDディスプレイ(128x64ドット)はI2Cで制御可能
- RTC(リアルタイムクロック): DS3231やPCF8523はI2C接続
- 電源管理IC(PMIC): 電圧や電流の設定をI2Cで行う
- DAC/ADC: ADS1115(16ビットADC)、MCP4725(12ビットDAC)
実装・開発のポイント
プルアップ抵抗の計算
プルアップ抵抗の値はバス容量と速度によって決まります:
最小抵抗 = (VDD - 0.4V) / 3mA (Lowレベル時のシンク電流制限)
最大抵抗 = 立ち上がり時間 / (0.8473 × バス容量)
(立ち上がり時間:Smで1μs、Fmで300ns)
例(3.3V、400kbps、100pFの場合):
最小: (3.3 - 0.4) / 0.003 ≈ 967Ω → 1kΩ以上
最大: 300ns / (0.8473 × 100pF) ≈ 3.5kΩ → 3.3kΩ以下
アドレス競合の解決
同じアドレスを持つデバイスが複数ある場合の対策:
- ADDRピンで変更: 多くのセンサーはADDRピンをHigh/Lowに設定してアドレスを変更できる
- I2Cバスマルチプレクサ: TCA9548AなどのI2Cマルチプレクサで複数の独立バスに分割
- 別バスを使用: マイコンに複数のI2Cペリフェラルがあれば別々のバスに接続
バスハング(ロックアップ)対策
通信途中の電源断などでスレーブがSDAをLowに保持し続けるバスハングが発生することがあります:
// I2Cバスリセット手順(ビットバン)
void i2c_bus_reset(void) {
// SCLを9クロック分トグル(スレーブのシフトレジスタをクリア)
for (int i = 0; i < 9; i++) {
HAL_GPIO_WritePin(I2C_SCL_PORT, I2C_SCL_PIN, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(I2C_SCL_PORT, I2C_SCL_PIN, GPIO_PIN_SET);
HAL_Delay(1);
}
// STOPコンディション送出
HAL_GPIO_WritePin(I2C_SDA_PORT, I2C_SDA_PIN, GPIO_PIN_SET);
}
ロジックアナライザでのデバッグ
I2C通信のデバッグにはロジックアナライザが有効です。SigrokやPulseViewを使うとI2Cのデコードが自動で行われ、アドレス・読み書き方向・データ・ACK/NACKが視覚的に確認できます。
他技術との比較
I2C vs SPI
| 項目 | I2C | SPI |
|---|---|---|
| 配線数 | 2本(全デバイス共有) | 最低4本(デバイスごとにCSが増加) |
| 速度 | 最大3.4Mbps | 数十〜数百Mbps |
| マルチスレーブ | アドレスで識別 | CSピンで識別 |
| 複雑性 | アドレス/ACK管理が必要 | シンプルなプロトコル |
| 用途 | 低速センサー・設定 | ディスプレイ・フラッシュ |
I2C vs UART
UARTは1対1の非同期通信で、プロトコルが非常にシンプルです。I2Cはマルチスレーブ対応の代わりにプロトコルが複雑で、プルアップ抵抗などのハードウェア要件があります。デバイスが1つだけならUART、複数センサーをまとめて接続するならI2Cという使い分けが一般的です。