1. Perbandingan Protokol Serial
Setelah mempelajari UART pada pertemuan sebelumnya, sekarang kita akan mempelajari dua protokol serial synchronous yang umum digunakan dalam sistem embedded: I2C dan SPI.
| Parameter | UART | I2C | SPI |
|---|---|---|---|
| Type | Asynchronous | Synchronous | Synchronous |
| Lines | 2 (TX, RX) | 2 (SDA, SCL) | 4+ (MOSI, MISO, SCK, SS) |
| Speed | Slow-Moderate | Slow-Moderate | Very Fast |
| Devices | Point-to-point | Multi-slave (128 devices) | Multi-slave (limited by CS) |
| Complexity | Simple | Moderate | Simple |
| Best For | PC communication | Sensors, small ICs | High-speed devices |
2. Inter-Integrated Circuit (I2C)
Karakteristik I2C
- Two-wire interface - SDA (Data) dan SCL (Clock)
- Multi-master capable - Beberapa master dapat mengontrol bus
- 7-bit addressing - Mendukung hingga 128 devices (112 usable)
- Speed variants - Standard (100kbps), Fast (400kbps), High-speed (3.4Mbps)
- Pull-up resistors - Diperlukan untuk kedua line
Frame Data I2C
| Sequence | Description | Purpose |
|---|---|---|
| Start Condition | SDA turun saat SCL tinggi | Memulai komunikasi |
| Address Frame | 7-bit address + R/W bit | Memilih slave device |
| ACK/NACK | Bit acknowledge | Konfirmasi penerimaan |
| Data Frames | 8-bit data + ACK | Transfer data aktual |
| Stop Condition | SDA naik saat SCL tinggi | Mengakhiri komunikasi |
i2c_master.c - Implementasi I2C Master
#include
#include
#define I2C_START 0x08
#define I2C_MT_SLA_ACK 0x18
#define I2C_MT_DATA_ACK 0x28
void I2C_Init() {
// Set bit rate (100kHz untuk 16MHz clock)
TWBR = 72;
// Enable I2C
TWCR = (1 << TWEN);
}
void I2C_Start() {
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
}
void I2C_Stop() {
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
}
void I2C_Write(uint8_t data) {
TWDR = data;
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
}
uint8_t I2C_Read(uint8_t ack) {
TWCR = (1 << TWINT) | (1 << TWEN) | (ack ? (1 << TWEA) : 0);
while (!(TWCR & (1 << TWINT)));
return TWDR;
}
// Contoh: Baca dari sensor I2C (contoh: BMP180)
void BMP180_ReadTemp() {
I2C_Start();
I2C_Write(0xEE); // Address BMP180 + Write
I2C_Write(0xF4); // Register control
I2C_Write(0x2E); // Perintah baca temperatur
I2C_Stop();
_delay_ms(5); // Tunggu konversi
I2C_Start();
I2C_Write(0xEE); // Address BMP180 + Write
I2C_Write(0xF6); // Register data MSB
I2C_Start();
I2C_Write(0xEF); // Address BMP180 + Read
uint8_t msb = I2C_Read(1); // Read dengan ACK
uint8_t lsb = I2C_Read(0); // Read dengan NACK
I2C_Stop();
int16_t temp = (msb << 8) | lsb;
// Process temperature data...
}
3. Serial Peripheral Interface (SPI)
Karakteristik SPI
- Four-wire interface - MOSI, MISO, SCK, SS
- Full-duplex - Dapat mengirim dan menerima bersamaan
- Very fast - Hingga 10Mbps+ (tergantung device)
- Simple protocol - Tidak ada addressing complex
- Multiple slaves - Dengan multiple chip select
Mode SPI (Clock Polaritas dan Phase)
| Mode | CPOL | CPHA | Description |
|---|---|---|---|
| 0 | 0 | 0 | Clock idle low, data captured on rising edge |
| 1 | 0 | 1 | Clock idle low, data captured on falling edge |
| 2 | 1 | 0 | Clock idle high, data captured on falling edge |
| 3 | 1 | 1 | Clock idle high, data captured on rising edge |
spi_master.c - Implementasi SPI Master
#include
// Pin definitions
#define SPI_DDR DDRB
#define SPI_PORT PORTB
#define MOSI PB3
#define MISO PB4
#define SCK PB5
#define SS PB2
void SPI_Init() {
// Set MOSI, SCK, dan SS sebagai output
SPI_DDR |= (1 << MOSI) | (1 << SCK) | (1 << SS);
// Set MISO sebagai input
SPI_DDR &= ~(1 << MISO);
// Enable SPI, Master, set clock rate fck/16
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
}
void SPI_CS_Low() {
SPI_PORT &= ~(1 << SS);
}
void SPI_CS_High() {
SPI_PORT |= (1 << SS);
}
uint8_t SPI_Transfer(uint8_t data) {
// Mulai transmisi
SPDR = data;
// Tunggu transmisi selesai
while (!(SPSR & (1 << SPIF)));
// Return data yang diterima
return SPDR;
}
// Contoh: Baca/write ke SPI device (contoh: SD card, flash memory)
void SPI_Example() {
SPI_Init();
SPI_CS_Low();
// Kirim command (contoh: read status register)
SPI_Transfer(0x05);
// Baca status
uint8_t status = SPI_Transfer(0x00);
SPI_CS_High();
// Process status data...
}
// Contoh dengan sensor SPI (contoh: MAX6675 - Thermocouple)
float MAX6675_ReadTemp() {
SPI_CS_Low();
_delay_us(1);
// Baca 16-bit data
uint8_t high_byte = SPI_Transfer(0x00);
uint8_t low_byte = SPI_Transfer(0x00);
SPI_CS_High();
// Combine bytes
uint16_t data = (high_byte << 8) | low_byte;
// Check error bit (D2)
if (data & 0x04) {
return -1.0; // Error
}
// Extract temperature (D15-D3)
data = data >> 3;
return data * 0.25; // Convert to Celsius
}
4. Simulator Protokol I2C & SPI
Simulator Komunikasi Multi-Device
Pilih protokol untuk melihat perbedaan implementasi
Master
Mikrokontroler
SCL
SDA
Slave 1
Address: 0x48
Status: Idle
I2C Bus Ready
Master
Mikrokontroler
SCK
MOSI
MISO
SS
Slave 1
SPI Device
Status: Idle
SPI Bus Ready
Timing Diagram - I2C vs SPI
I2C SCL
I2C SDA
SPI SCK
SPI MOSI
5. Aplikasi I2C & SPI dalam Embedded Systems
Contoh Device dengan I2C
- Sensor: BMP180 (Pressure), MPU6050 (Accel/Gyro), TMP102 (Temperature)
- Display: OLED SSD1306, LCD dengan I2C backpack
- IO Expander: MCP23017 (16-bit I/O expander)
- RTC: DS3231 (Real Time Clock)
Contoh Device dengan SPI
- Memory: SD Card, Flash memory (W25Q64)
- Display: TFT LCD, Graphic OLED
- Sensor: MAX6675 (Thermocouple), ADXL345 (Accelerometer)
- Communication: RF module (nRF24L01), Ethernet (ENC28J60)
Tips Pemilihan Protokol
- Gunakan I2C untuk: Jumlah pin terbatas, banyak device, kecepatan tidak kritikal
- Gunakan SPI untuk: Kecepatan tinggi, full-duplex communication, simple protocol
- Gunakan UART untuk: Komunikasi dengan PC, debugging, jarak lebih panjang
Latihan Praktikum
Implementasikan komunikasi dengan sensor I2C dan SPI
Tugas 1: Sensor I2C - BMP180
Buat program untuk membaca data temperatur dan tekanan dari sensor BMP180:
- Inisialisasi I2C dengan kecepatan 100kHz
- Kalibrasi sensor dengan membaca calibration data
- Baca temperatur (raw data dan konversi ke Celsius)
- Baca pressure (raw data dan konversi ke hPa)
- Tampilkan data via UART ke PC setiap 2 detik
Tugas 2: Memory SPI - W25Q64 Flash
Buat program untuk membaca dan menulis data ke SPI flash memory:
- Inisialisasi SPI dengan mode 0 dan kecepatan maksimal
- Implementasikan fungsi read manufacturer ID
- Buat fungsi write data ke sector tertentu
- Buat fungsi read data dari sector
- Implementasikan sector erase command