SPI, UART, I2C: So sánh 3 chuẩn giao tiếp cơ bản

Các vi điều khiển (MCU) truyền nhận dữ liệu với nhau hoặc với thiết bị ngoại vi thông qua tín hiệu điện áp trên các chân được cấu hình riêng. Để việc truyền nhận dễ dàng và tương thích giữa nhiều dòng chip, người ta tạo ra các chuẩn giao tiếp. Bài viết trình bày lý thuyết 3 chuẩn giao tiếp cơ bản: SPI, UART, I2C – nguyên lý, số dây, khung truyền – kèm bảng so sánh để bạn chọn đúng giao thức cho từng ứng dụng.

SPI (Serial Peripheral Interface)

SPI – giao diện ngoại vi nối tiếp, được phát triển bởi Motorola. Đây là chuẩn đồng bộ, truyền dữ liệu ở chế độ full-duplex (song công toàn phần): tại một thời điểm có thể vừa truyền vừa nhận. Mọi quá trình đều được đồng bộ với xung clock sinh bởi thiết bị Master. SPI cho tốc độ rất cao – thường đạt hàng Mbps, thậm chí hàng chục Mbps.

Kết nối SPI Master và Slave qua 4 dây SCK, MOSI, MISO, CS
Hình 1. SPI dùng 4 đường giao tiếp giữa Master và Slave

SPI dùng 4 đường nên còn gọi là chuẩn “4 dây”:

  • SCK (Serial Clock): Master tạo xung SCK cấp cho Slave, giữ nhịp cho giao tiếp. Mỗi nhịp báo 1 bit đến/đi → ít lỗi, tốc độ cao.
  • MISO (Master In Slave Out): tín hiệu do Slave tạo, Master nhận.
  • MOSI (Master Out Slave In): tín hiệu do Master tạo, Slave nhận.
  • SS (Slave Select): chọn Slave để giao tiếp bằng cách kéo đường SS tương ứng xuống mức 0. Còn gọi là CS (Chip Select).

Một Master có thể giao tiếp nhiều Slave qua các chân SS riêng; mỗi Slave chỉ có một chân CS còn Master có thể có nhiều chân SS.

Một SPI Master điều khiển nhiều Slave qua các chân SS0, SS1, SS2
Hình 2. Một Master điều khiển nhiều Slave – mỗi Slave một đường SS

Khung truyền SPI

Mỗi chip Master/Slave có một thanh ghi dịch 8 bit. Khi Master tạo xung clock và kéo SS của Slave xuống Low, mỗi xung clock Master gửi 1 bit qua MOSI đồng thời nhận 1 bit qua MISO. Sau 8 chu kỳ clock hoàn tất việc truyền/nhận 1 byte theo cả hai hướng.

Dạng sóng khung truyền SPI: CS, MOSI, MISO và SCK với các bit dữ liệu
Hình 3. Khung truyền SPI – dữ liệu dịch theo từng xung SCK khi CS ở mức Low

4 chế độ hoạt động (CPOL / CPHA)

SPI có 4 chế độ tùy theo cực tính xung (CPOL) và pha lấy mẫu (CPHA). CPOL chỉ trạng thái SCK khi nghỉ (0 = mức thấp, 1 = mức cao); CPHA chỉ cạnh lấy mẫu dữ liệu.

Bốn chế độ SPI theo CPOL và CPHA với dạng sóng SCK tương ứng
Hình 4. Bốn chế độ SPI theo tổ hợp CPOL và CPHA
Chế độCPOLCPHALấy mẫu dữ liệu
Mode 0 (mặc định)00SCK nghỉ ở mức thấp, lấy mẫu ở cạnh lên
Mode 101SCK nghỉ ở mức thấp, lấy mẫu ở cạnh xuống
Mode 210SCK nghỉ ở mức cao, lấy mẫu ở cạnh lên
Mode 311SCK nghỉ ở mức cao, lấy mẫu ở cạnh xuống

Chi tiết cách lập trình SPI trên STM32 (cả SPI mềm và SPI cứng), xem bài SPI trong STM32.

UART (Universal Asynchronous Receiver-Transmitter)

UART là giao thức truyền thông nối tiếp bất đồng bộ, cấu hình được tốc độ. Nó gồm hai đường độc lập: TX (truyền)RX (nhận). Dữ liệu được đóng thành các khung (frame) chuẩn gồm bit bắt đầu, các bit dữ liệu, bit chẵn lẻ tùy chọn và bit dừng.

Kết nối UART: chân TX của thiết bị này nối RX của thiết bị kia và ngược lại, chung GND
Hình 5. Chân TX của một chip nối trực tiếp với RX của chip kia (và ngược lại)

Tốc độ UART đặt theo các mức baud chuẩn: 9600, 19200, 38400, 57600, 115200… (số bit truyền mỗi giây). UART truyền theo một trong ba chế độ:

  • Simplex: giao tiếp một chiều.
  • Half duplex: dữ liệu đi một hướng tại một thời điểm.
  • Full duplex: truyền và nhận đồng thời.

UART là giao tiếp giữa một Master và một Slave (1–1). Bộ UART dịch dữ liệu song song từ thiết bị điều khiển thành nối tiếp để truyền qua TX, rồi UART bên kia biến đổi ngược lại qua RX.

Cấu trúc gói dữ liệu UART: 1 start bit, 5-9 data bits, 0-1 parity bit, 1-2 stop bits
Hình 6. Gói dữ liệu UART: 1 start bit, 5–9 data bit, 0–1 parity bit, 1–2 stop bit

Quá trình truyền bắt đầu bằng start bit (đường từ mức cao kéo xuống thấp), tiếp theo là 5–9 bit dữ liệu, bit chẵn lẻ tùy chọn để kiểm tra, và kết thúc bằng 1–2 stop bit (đường về mức cao).

Dạng sóng UART truyền byte 0x71 với even parity và odd parity
Hình 7. Dạng sóng UART truyền 0x71 với chẵn lẻ chẵn (even) và lẻ (odd)

Chi tiết cấu hình ngắt UART trên STM32, xem phần UART trong bài Ngắt trong STM32.

I2C (Inter-Integrated Circuit)

I2C kết hợp ưu điểm của SPI và UART. Giống UART, I2C chỉ dùng hai dây; giống SPI, I2C là đồng bộ:

  • SDA (Serial Data): đường truyền dữ liệu cho master và slave.
  • SCL (Serial Clock): đường xung nhịp, luôn do master điều khiển.

Dữ liệu I2C truyền trong các tin nhắn (message), chia thành các khung. Mỗi tin nhắn có một khung địa chỉ (địa chỉ nhị phân của slave) và một hoặc nhiều khung dữ liệu, kèm điều kiện Start/Stop, bit đọc/ghi và bit ACK/NACK.

Cấu trúc bản tin I2C: Start, Address frame 7/10 bit, R/W, ACK, các Data frame 8 bit, Stop
Hình 8. Cấu trúc bản tin I2C – Start, khung địa chỉ, R/W, ACK và các khung dữ liệu
  • Điều kiện Start: SDA chuyển cao → thấp trước khi SCL chuyển cao → thấp.
  • Điều kiện Stop: SDA chuyển thấp → cao sau khi SCL chuyển thấp → cao.
  • Khung địa chỉ: 7 hoặc 10 bit duy nhất cho mỗi slave.
  • Bit R/W: mức thấp = master ghi dữ liệu; mức cao = master yêu cầu đọc.
  • Bit ACK/NACK: mỗi khung được theo sau bởi bit xác nhận; nhận thành công thì trả về ACK (mức thấp).
Dạng sóng I2C trên SDA và SCL: 7 bit địa chỉ, R/W, ACK, 8 bit dữ liệu, Start/Stop
Hình 9. Dạng sóng SDA/SCL – 7 bit địa chỉ + R/W + ACK, rồi 8 bit dữ liệu + ACK

Các bước truyền dữ liệu I2C

  • Master gửi điều kiện Start tới mọi slave.
  • Master gửi địa chỉ 7/10 bit của slave cần giao tiếp kèm bit đọc/ghi.
  • Mỗi slave so sánh địa chỉ với chính nó; nếu trùng, kéo SDA xuống thấp trả về ACK.
  • Master gửi hoặc nhận khung dữ liệu; sau mỗi khung, bên nhận trả về ACK.
  • Master gửi điều kiện Stop để kết thúc.

Vì dùng địa chỉ nên I2C hỗ trợ nhiều slave (địa chỉ 7 bit cho 128 thiết bị, 10 bit cho 1024) và cả nhiều master (mỗi master kiểm tra SDA trước khi truyền để tránh xung đột bus).

Một I2C Master điều khiển nhiều Slave qua địa chỉ, chung SDA/SCL với điện trở kéo lên
Hình 10. Một Master điều khiển nhiều Slave qua địa chỉ – chung SDA/SCL và điện trở kéo lên

Chi tiết cách lập trình I2C trên STM32 (I2C mềm và I2C cứng), xem bài I2C trong STM32.

So sánh SPI, UART, I2C

Tiêu chíUARTSPII2C
Số dây2 (TX, RX)4 (SCK, MOSI, MISO, SS)2 (SDA, SCL)
Đồng bộBất đồng bộĐồng bộ (có clock)Đồng bộ (có clock)
Song côngFull duplexFull duplexHalf duplex
Chọn thiết bị1–1, không cần chọnChân SS/CS riêng mỗi slaveĐịa chỉ 7/10 bit
Số thiết bị1 master – 1 slave1 master – nhiều slaveNhiều master – nhiều slave
Tốc độTheo baud (≤ 115200…)Rất cao (hàng chục Mbps)Trung bình (100k–400k+)

Kết luận

Ba chuẩn giao tiếp cơ bản SPI, UART, I2C mỗi loại có thế mạnh riêng: UART đơn giản, 2 dây, bất đồng bộ, phù hợp giao tiếp 1–1; SPI nhanh nhất, full-duplex, 4 dây, hợp truyền dữ liệu lớn tốc độ cao (màn hình, thẻ nhớ); I2C chỉ 2 dây nhưng nối được nhiều thiết bị qua địa chỉ, hợp đọc nhiều cảm biến trên cùng bus.

Hiểu bản chất từng giao thức giúp bạn chọn đúng chuẩn cho hệ thống automotive embedded. Để đi sâu vào cách lập trình trên STM32, tham khảo các bài chi tiết: SPI trong STM32, I2C trong STM32 và phần UART trong bài Ngắt trong STM32.

Leave a Reply