I2C (veya TWI - Two Wire Interface), 1982 yılında Philips Semiconductor (günümüzdeki NXP) tarafından geliştirilmiş, senkron, seri ve çoklu istemci/çoklu sunucu (multi-master/multi-slave) mimarisini destekleyen bir haberleşme protokolüdür. Kısa mesafelerde (genellikle aynı PCB üzerinde) entegreler, mikrokontrolcüler ve sensörler arası veri iletiminde hat tasarrufu sağladığı için gömülü sistemlerin vazgeçilmezidir.

I2C protokolü donanım seviyesinde sadece iki adet dijital sinyal hattı ve ortak bir GND hattı kullanır:

Pull-Up direnç değeri; bus kapasitansına (Cb), besleme gerilimine (VCC) ve çalışma frekansına göre seçilir. Tipik uygulamalarda tercih edilen değerler:
I2C hatlarında veri transferi Master cihazın kontrolünde belirli aşamalarla gerçekleşir:
| Sinyal Durumu | SDA Hat Durumu | SCL Hat Durumu | Açıklama |
|---|---|---|---|
| START (S) | HIGH → LOW düşen kenar | HIGH seviyesinde | Haberleşmeyi başlatır. |
| Address (7-bit) | MSB'den LSB'ye doğru veri | Saat pulsu üretilir | Hedef Slave cihazın adresi (Örn: 0x68, 0x27). |
| R/W Bit (1-bit) | 0 = Write (Yazma), 1 = Read (Okuma) | Saat pulsu | İşlemin yönünü belirtir. |
| ACK / NACK (1-bit) | ACK = LOW, NACK = HIGH | Saat pulsu | Alıcı cihazın doğrulaması (Acknowledge). |
| Data (8-bit) | 8-bit Bayt paketleri | Saat pulsu | Register adresi veya okunan/yazılan veri. |
| STOP (P) | LOW → HIGH yükselen kenar | HIGH seviyesinde | Haberleşmeyi sonlandırır, hattı boşa çıkarır. |
Örneğin bir MPU6050 ivmeölçer sensörünün PWR_MGMT_1 (0x6B) register'ına 0x00 yazarak cihazı uyandırma işlemi:
#include <Wire.h>
#define MPU6050_ADDR 0x68
#define PWR_MGMT_1 0x6B
void setup() {
Serial.begin(115200);
// ESP32 için özel SDA/SCL pinleri belirtilebilir: Wire.begin(SDA_PIN, SCL_PIN);
Wire.begin();
// MPU6050 Cihazına Yazma İsteği Başlat
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(PWR_MGMT_1); // Hedef Register Adresi
Wire.write(0x00); // Uyandırma Komutu
uint8_t status = Wire.endTransmission(); // STOP Biti Gönder ve Durum Al
if (status == 0) {
Serial.println("I2C Yazma Başarılı (ACK Alındı)");
} else {
Serial.printf("I2C Hata Kodu: %d\n", status);
}
}
void loop() {
// Okuma işlemi örneği (2 Bayt Veri İsteme)
Wire.beginTransmission(MPU6050_ADDR);
Wire.write(0x3B); // ACCEL_XOUT_H register adresi
Wire.endTransmission(false); // Repeated START (Hattı bırakma)
Wire.requestFrom((uint8_t)MPU6050_ADDR, (uint8_t)2); // 2 Bayt Oku
if (Wire.available() >= 2) {
int16_t accelX = (Wire.read() << 8) | Wire.read();
Serial.printf("Accel X: %d\n", accelX);
}
delay(1000);
}
Hatta bağlı bilinmeyen sensör veya LCD ekranların 7-bitlik adresini (0x07 - 0x7F arası) bulmak için kullanılan standart I2C Tarama algoritması:
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(115200);
while (!Serial);
Serial.println("\nI2C Cihaz Taraması Başlatılıyor...");
}
void loop() {
byte error, address;
int nDevices = 0;
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.printf("I2C cihazı bulundu! Adres: 0x%02X\n", address);
nDevices++;
} else if (error == 4) {
Serial.printf("0x%02X adresinde bilinmeyen hata!\n", address);
}
}
if (nDevices == 0) {
Serial.println("Hiçbir I2C cihazı bulunamadı.\n");
} else {
Serial.println("Tarama tamamlandı.\n");
}
delay(5000);
}
| Özellik | I2C (Inter-Integrated Circuit) | SPI (Serial Peripheral Interface) |
|---|---|---|
| Pin Sayısı | 2 Pin (SDA, SCL) | 4+ Pin (MOSI, MISO, SCK, CS/SS) |
| Maksimum Hız | Daha yavaş (100kHz - 3.4MHz) | Çok hızlı (10MHz - 80MHz+) |
| Donanım Karmaşıklığı | Open-Drain + Pull-Up gerektirir | Push-Pull (Doğrudan bağlantı) |
| Doğrulama (ACK/NACK) | Var (Donanımsal onay mekanizması) | Yok (Verinin gidip gitmediği bilinmez) |
| Cihaz Seçimi | Yazılımsal 7-bit / 10-bit Adresleme | Donanımsal Chip Select (CS) Pinleri |
Henüz yorum yapılmamış. İlk yorumu siz yapın!