Embedded SystemUnit 89 min read
UART, SPI, I2C: Serial Protocols for Embedded Communication
Unit 8 of Embedded System explores UART (asynchronous), SPI (synchronous master-slave), and I2C (multi-master, multi-slave) protocols—how they transmit data, their hardware/software layers, wiring, speed trade-offs, and real-world uses in sensors, displays, and microcontroller networks.
Core Concepts: What Are UART, SPI, and I2C?
Embedded systems rarely work alone—they communicate with sensors, displays, memory chips, and other MCUs. Three dominant serial communication protocols handle this:
- UART (Universal Asynchronous Receiver/Transmitter): No clock line, data sent asynchronously.
- SPI (Serial Peripheral Interface): Synchronous, full-duplex, requires 4+ wires.
- I2C (Inter-Integrated Circuit): Multi-device, half-duplex, minimal wiring (2 wires).
classDiagram
class Protocol {
<<abstract>>
+transmitData()
+wiringComplexity
+speed
}
class UART {
+asynchronous
+2 wires (TX/RX)
+no clock
}
class SPI {
+synchronous
+4+ wires (SCLK, MOSI, MISO, SS)
+master-slave
}
class I2C {
+synchronous
+2 wires (SDA, SCL)
+multi-master/slave
}
Protocol <|-- UART
Protocol <|-- SPI
Protocol <|-- I2C1. UART: Asynchronous, Simple, and Slow
How it works:
- No shared clock line; sender/receiver must agree on baud rate (bits per second).
- Data framed by start bit (0), 8/9 data bits, parity bit (optional), stop bit (1).
- No handshaking: Risk of data loss if baud rates mismatch.
Real-world use:
- Ncell SIM cards: UART connects the SIM module to the MCU for AT commands (e.g.,
AT+CMGF=1to enable SMS). - Debugging: Most MCUs (Arduino, ESP32) use UART for serial monitors (e.g.,
Serial.begin(9600)).
Worked Example: Problem: Send "HELLO" from an Arduino to a PC at 9600 baud. Draw the UART frame for 'H' (ASCII 72, no parity). Solution:
Start | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | Stop
|---|---|---|---|---|---|---|---|
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 1 |
Why? 'H' in binary is 01001000 (MSB first). UART transmits LSB first, so the frame above is correct.
Advantages/Disadvantages: | UART | ✅ Simple wiring (2 wires) | ❌ No error checking (unless parity used) | | | ✅ Low cost | ❌ Baud rate must match exactly | | | ✅ Long-distance capable | ❌ Slower than SPI/I2C |
In the Real World
Khalti’s Payment Terminals
- Uses UART to communicate between the MCU (e.g., STM32) and the card reader. The MCU sends AT commands via UART to authenticate transactions.
- Why UART? Low cost, simple wiring for point-of-sale devices.
Pathao Rider App’s GPS Module
- The ESP32 MCU talks to the GPS module (e.g., NEO-6M) via UART to fetch latitude/longitude. The module sends NMEA sentences like
$GPGGAasynchronously. - Worked Example: If the GPS sends
$GPGGA,123519,4236.1234,N,..., the MCU parses this string to update the rider’s location.
- The ESP32 MCU talks to the GPS module (e.g., NEO-6M) via UART to fetch latitude/longitude. The module sends NMEA sentences like
Daraz’s Warehouse Inventory Sensors
- SPI connects RFID readers to the central MCU for fast, full-duplex data transfer. Each shelf’s RFID tag reader (slave) sends inventory updates to the master MCU without collisions.
- Why SPI? Speed (up to 10 Mbps) and direct wiring reduce latency in high-throughput warehouses.
2. SPI: Synchronous, Fast, and Complex
How it works:
- 4+ wires:
- SCLK (Serial Clock): Master-generated clock.
- MOSI (Master Out Slave In): Master → Slave.
- MISO (Master In Slave Out): Slave → Master.
- SS/CS (Slave Select): Chip select (1 slave per line).
- Full-duplex: Send/receive simultaneously.
- No addressing: Each slave needs a dedicated SS line.
Real-world use:
- NTC’s Smart Meters
- SPI connects the MCU to the energy measurement IC (e.g., ADE7758). The meter sends voltage/current data at high speed (1 Mbps) for billing accuracy.
- eSewa’s QR Code Scanners
- The scanner’s camera module (e.g., OV7670) uses SPI to stream pixel data to the MCU for real-time QR decoding.
Worked Example: Problem: Design SPI communication between an Arduino (master) and an SD card module (slave) to read a file. Steps:
- Pull SS low to select the SD card.
- Send clock pulses on SCLK while shifting data MSB-first on MOSI.
- Read response on MISO.
- Pull SS high to deselect.
sequenceDiagram
participant Master as Arduino (Master)
participant Slave as SD Card (Slave)
Master->>Slave: SS = LOW (Select)
loop Data Transfer
Master->>Slave: SCLK pulse + MOSI (MSB first)
Slave-->>Master: MISO (data)
end
Master->>Slave: SS = HIGH (Deselect)Advantages/Disadvantages: | SPI | ✅ Fastest (up to 10+ Mbps) | ❌ Dedicated wiring per slave | | | ✅ Full-duplex | ❌ No built-in addressing | | | ✅ No clock synchronization issues | ❌ More pins used |
3. I2C: Multi-Device, Minimal Wiring
How it works:
- 2 wires:
- SDA (Serial Data): Bidirectional.
- SCL (Serial Clock): Shared clock line.
- 7-bit or 10-bit addressing: Up to 128 devices (7-bit) or 1024 (10-bit).
- Half-duplex: Only one device transmits at a time.
- Start/Stop conditions: SDA transition while SCL is high.
Real-world use:
- NEPSE Stock Terminals
- I2C connects the real-time clock (RTC) module (e.g., DS3231) to the MCU. The RTC keeps time even when power is off, critical for stock market data timestamps.
- Bank ATMs
- I2C links the keypad, display, and card reader to the main MCU. The keypad (slave 0x20) sends key presses, while the display (slave 0x38) receives commands.
Worked Example: Problem: Write I2C code to read a temperature from an LM75 sensor (address 0x48). Steps:
- Send start condition.
- Send device address + write (0x48 << 1 | 0).
- Send register address (0x00 for temp).
- Send repeated start.
- Send device address + read (0x49).
- Read 2 bytes (temp data).
- Send stop condition.
stateDiagram-v2
[*] --> Start
Start --> SendDeviceAddrWrite
SendDeviceAddrWrite --> SendRegAddr
SendRegAddr --> RepeatedStart
RepeatedStart --> SendDeviceAddrRead
SendDeviceAddrRead --> ReadData
ReadData --> Stop
Stop --> [*]Advantages/Disadvantages: | I2C | ✅ Minimal wiring (2 wires) | ❌ Limited speed (~400 kbps standard) | | | ✅ Multi-master/slave support | ❌ Collision risk (arbitration needed) | | | ✅ Addressable devices | ❌ Complex protocol (ACK/NACK) |
Protocol Comparison Table
| Feature | UART | SPI | I2C |
|---|---|---|---|
| Wiring | 2 wires (TX/RX) | 4+ wires | 2 wires (SDA/SCL) |
| Duplex | Half/Full* | Full | Half |
| Speed | Slow (115 kbps) | Fast (10+ Mbps) | Medium (400 kbps) |
| Devices | 1:1 | 1:many (dedicated) | 1:many (addressed) |
| Clock | No (asynchronous) | Master-provided | Shared |
| Error Handling | Parity/None | None | ACK/NACK |
| Cost | Low | Medium | Low |
*UART can be full-duplex with separate TX/RX pairs.
Hardware Wiring: How to Connect Them
UART
MCU TX ────┬─────► Sensor RX
│
MCU RX ────┬─────◄ Sensor TX
SPI
MCU SCLK ────┬─────► Slave SCLK
MCU MOSI ────┬─────► Slave MOSI
MCU MISO ────┬─────◄ Slave MISO
MCU SS ────┬─────► Slave SS
I2C
MCU SDA ────┬─────►► Slave1 SDA
│ │
MCU SCL ────┴─────►► Slave2 SCL
Exam Tip
Protocol Selection:
- Asked: "Which protocol would you use for a weather station with 5 sensors and a display?"
- Answer: I2C (minimal wiring for multiple devices) or SPI (if speed is critical for the display).
Frame/Byte Calculation:
- Asked: "Draw the UART frame for ASCII 'A' (65) at 115200 baud with even parity."
- Solution: Show start bit, 8 data bits (01000001), parity bit (1 for even), stop bit.
Wiring Diagrams:
- Asked: "Connect an Arduino to an OLED display using SPI. Label all pins."
- Must include: SCLK, MOSI, MISO, SS, and GND/VCC.
Speed vs. Complexity:
- Asked: "Why does SPI use more pins than I2C?"
- Answer: SPI requires dedicated SS lines per slave; I2C uses addressing on 2 wires.
Real-world Scenarios:
- Asked: "How does a bank ATM use I2C?"
- Answer: Connects keypad, display, and card reader to the MCU via I2C for minimal wiring and multi-device support.
Key Formula to Remember:
- UART Baud Rate Calculation: Example: For 9600 baud, each bit takes .
Common Pitfalls:
- Forgetting to pull SS high in SPI after communication (slave stays selected).
- Not enabling internal pull-ups on I2C lines (SDA/SCL must be high when idle).
- Mismatched baud rates in UART causing garbled data.
Based on the PU BE Computer (PU) syllabus for Embedded System (ELX320), unit 8.
Discussion
Loading…