Knowledge / Electronics and Communication Engineering / Embedded interfaces: UART, SPI and I2C

Embedded interfaces: UART, SPI and I2C

Electronics and Communication Engineering (B.E./B.Tech) · Microprocessors and embedded · free study notes for exams, placements and interviews

In short

UART, SPI and I2C are the three serial interfaces that connect a microcontroller to the world - a GPS module, a display, a flash chip, a sensor, a PC terminal. They differ in three things only: whether a clock line is shared (synchronous or asynchronous), how many devices can hang on the same wires, and how fast they go. These three protocols appear in almost every embedded interview in India (Bosch, Continental, Qualcomm, Texas Instruments, Tata Elxsi, L&T Technology Services, HCL, Wipro, Cyient, ISRO/DRDO/BEL, Mindteck) and are standard questions in university exams; in GATE EC they sit under Digital Circuits (microprocessor, memory and I/O interfacing). Expect to be asked not only the pinouts but the timing arithmetic - baud rate, bits per frame, bus throughput - and the failure modes.

Explained

1. Serial basics and the vocabulary

2. UART - asynchronous serial

3. SPI - Serial Peripheral Interface

ModeCPOLCPHASCLK idleData sampled onData shifted out on
000LowRising edgeFalling edge
101LowFalling edgeRising edge
210HighFalling edgeRising edge
311HighRising edgeFalling edge

Mode 0 and mode 3 are the most common. A mismatched mode is the classic cause of data shifted by one bit or read as 0x00/0xFF.

4. I2C - Inter-Integrated Circuit

5. Choosing between them, and related buses

Key points

Formulas and examples

UART bits per frame N = 1 (start) + D (data, 5-9) + P (parity, 0 or 1) + S (stop, 1, 1.5 or 2)
Byte transfer time t = N / baud (seconds); throughput = baud × D / N bits/s (÷ 8 for bytes/s)
Bit time T_bit = 1 / baud (seconds)
8051 baud (mode 1, Timer 1, 8-bit auto-reload) baud = f_osc / (12 × 32 × (256 − TH1)), and × 2 if SMOD = 1
AVR/typical UBRR UBRR = f_osc / (16 × baud) − 1 (normal mode); replace the 16 with 8 for double-speed mode
Baud error % = (actual − desired) / desired × 100
SPI clock f_SCLK = f_peripheral / prescaler; time for n bytes ≈ 8n / f_SCLK (plus CS and gap overhead)
I2C transfer time ≈ (9 × number_of_bytes_including_address + ~2 for START/STOP) / f_SCL
I2C pull-up limits R_max = t_r / (0.8473 × C_b); R_min = (V_cc − V_OL(max)) / I_OL
Symbols: f_osc oscillator frequency (Hz), baud in bits/s, t_r allowed rise time (300 ns Fast mode, 1,000 ns Standard mode), C_b bus capacitance (F, limit 400 pF), I_OL sink current (3 mA), V_OL(max) = 0.4 V.

Example 1 - UART frame time and throughput. A GPS module streams at 9,600 baud, 8N1.

Example 2 - 8051 baud rate reload value. Find TH1 for 9,600 baud with f_osc = 11.0592 MHz, SMOD = 0.

Example 3 - AVR UBRR and baud error. f_osc = 16 MHz, desired 115,200 baud, normal mode.

Example 4 - I2C versus SPI time for the same job. Read 6 bytes (X, Y, Z accelerometer data) from an MPU-6000 (the MPU-6050 is the I2C-only version of the same part).

Example 5 - I2C pull-up resistor. Fast mode, 400 kHz, V_cc = 3.3 V, measured bus capacitance C_b = 150 pF, t_r allowed = 300 ns, I_OL = 3 mA, V_OL(max) = 0.4 V.

FeatureUARTSPII2C
Wires (excl. ground)2 (TX, RX)3 + n (CS each)2 (SDA, SCL)
ClockNone (asynchronous)SCLK from masterSCL from master
DuplexFullFullHalf
Devices2 (point-to-point)1 master, many slavesMulti-master, 112 addresses (7-bit)
Typical speed9.6 kbit/s - 1 Mbit/s1-50 MHz (QSPI higher)100 k / 400 k / 1 M / 3.4 Mbit/s
AddressingNoneChip select lineIn-protocol address byte
AcknowledgementNone (parity only)NoneACK/NACK each byte
Error detectionParity, framing, overrunNoneACK, (PEC in SMBus)
Overhead20% at 8N1~0%1 ACK bit/byte + address byte
Distance15 m RS-232, 1,200 m RS-485Centimetres, on-boardA few metres (400 pF limit)
Pull-ups neededNoNoYes
Typical useGPS, GSM modem, console, ModbusSD card, flash, TFT, ADC, IMUEEPROM, RTC, sensors, OLED, PMIC
/* Bare-metal shape of each - register names are device-specific */

/* UART, AVR, 8N1 */
void uart_init(uint32_t baud){
    uint16_t ubrr = F_CPU/(16UL*baud) - 1;   /* round: ((F_CPU+8UL*baud)/(16UL*baud))-1 */
    UBRR0H = ubrr >> 8;  UBRR0L = ubrr;
    UCSR0B = (1<<TXEN0)|(1<<RXEN0);
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);        /* 8 data, 1 stop, no parity */
}
void uart_tx(uint8_t c){ while(!(UCSR0A & (1<<UDRE0))); UDR0 = c; }

/* SPI master: one function both writes and reads - full duplex */
uint8_t spi_xfer(uint8_t out){
    SPDR = out;
    while(!(SPSR & (1<<SPIF)));
    return SPDR;                              /* the byte clocked in */
}
/* read a register: CS low, send reg|0x80, send dummy, CS high */

/* I2C write of one register (polled, master mode) */
/* START -> addr<<1|0 -> reg -> data -> STOP, checking ACK at each step */

Where it is used

Interview questions

Common mistakes

Related topics

Microcontroller peripherals: timers, ADC, PWM and interrupts · 8051 microcontroller · ARM and embedded C · Sensors and actuators for embedded systems · Internet of Things basics · PCB design, EMI and EMC

Open in the Knowledge reader →Find jobs →