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.

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.

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.

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.

| Chế độ | CPOL | CPHA | Lấy mẫu dữ liệu |
|---|---|---|---|
| Mode 0 (mặc định) | 0 | 0 | SCK nghỉ ở mức thấp, lấy mẫu ở cạnh lên |
| Mode 1 | 0 | 1 | SCK nghỉ ở mức thấp, lấy mẫu ở cạnh xuống |
| Mode 2 | 1 | 0 | SCK nghỉ ở mức cao, lấy mẫu ở cạnh lên |
| Mode 3 | 1 | 1 | SCK 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) và 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.

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.

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).

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.

- Đ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).

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).

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í | UART | SPI | I2C |
|---|---|---|---|
| Số dây | 2 (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ông | Full duplex | Full duplex | Half duplex |
| Chọn thiết bị | 1–1, không cần chọn | Chân SS/CS riêng mỗi slave | Địa chỉ 7/10 bit |
| Số thiết bị | 1 master – 1 slave | 1 master – nhiều slave | Nhiề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.


