I2C, SPI, UART - ba chuẩn giao tiếp mọi robot đều dùng, hiểu trong một bài

Phân biệt I2C, SPI, UART theo số dây, tốc độ, số thiết bị - kèm code ESP32 quét địa chỉ I2C, nguyên tắc đấu chéo UART và bảng chọn chuẩn theo module. Trong bài viết này, chúng ta sẽ cùng tìm hiểu chi tiết và ứng dụng thực tế trong robot.
Vì sao cần các chuẩn giao tiếp?
Cảm biến đơn giản trả về một mức điện áp — đọc bằng một chân GPIO là xong. Nhưng MPU6050 có hàng chục thanh ghi dữ liệu, màn OLED cần nhận hàng nghìn byte điểm ảnh, module GPS tuôn chuỗi văn bản liên tục — một chân điện áp không tải nổi. Ba chuẩn giao tiếp nối tiếp UART, I2C, SPI ra đời để truyền dữ liệu số có cấu trúc giữa các chip, và mọi module "thông minh" trên robot đều nói một trong ba thứ tiếng này.
Hiểu ba chuẩn, bạn nhìn tên chân trên module mới (SDA? TX? MOSI?) là biết ngay cách đấu và loại code cần viết.
Bảng so sánh tổng quát
| Tiêu chí | UART | I2C | SPI |
|---|---|---|---|
| Số dây (không kể nguồn) | 2 (TX, RX) | 2 (SDA, SCL) | 4+ (MOSI, MISO, SCK, CS mỗi thiết bị) |
| Số thiết bị trên bus | 2 (điểm-điểm) | ~112 (theo địa chỉ 7-bit) | Nhiều (mỗi con thêm 1 dây CS) |
| Tốc độ điển hình | 9600-921600 bps | 100k-400k (đến 1M) bps | 1-80 Mbps |
| Đồng hồ chung | Không (thỏa thuận baud) | Có (SCL) | Có (SCK) |
| Vai trò chủ-tớ | Ngang hàng | Master-Slave | Master-Slave |
| Cần trở kéo lên | Không | Có (4.7kΩ lên VCC) | Không |
| Điển hình trên robot | GPS, Bluetooth HC-05, debug | MPU6050, OLED, VL53L0X, PCA9685 | Thẻ SD, màn TFT, RFID RC522 |
Trực giác chọn nhanh: ít dây nhiều thiết bị → I2C; tốc độ khủng → SPI; thiết bị cũ/GPS/module thu phát → UART.
UART - lâu đời và phổ biến nhất
UART truyền không đồng hồ chung: hai bên hẹn trước tốc độ (baud rate — 9600 hay 115200 quen thuộc), mỗi byte đóng khung bởi bit start/stop.
Quy tắc đấu số một, sai nhiều nhất: đấu chéo TX-RX. TX (transmit) của module vào RX (receive) của ESP32 và ngược lại — hai TX đấu nhau thì cả hai cùng nói không ai nghe.
ESP32 có 3 khối UART: UART0 (GPIO 1, 3) dành cho USB/nạp code — tránh chiếm; UART2 (GPIO 16, 17) tự do cho module ngoài:
// đọc module GPS trên UART2
void setup() {
Serial.begin(115200); // UART0 - ra máy tính
Serial2.begin(9600, SERIAL_8N1, 16, 17); // RX2=16, TX2=17
}
void loop() {
while (Serial2.available()) {
Serial.write(Serial2.read()); // chuyển tiếp GPS ra Serial Monitor
}
}Chính Serial Monitor bạn dùng hằng ngày là UART0 — bài Debug bằng Serial Monitor ở mục Kiến thức khai thác sâu công cụ này.
I2C - hai dây cân cả rổ cảm biến
I2C dùng đúng 2 dây cho cả bus: SDA (dữ liệu) và SCL (nhịp đồng hồ), mọi thiết bị mắc song song lên đó. Master (ESP32) gọi tên thiết bị bằng địa chỉ 7-bit (MPU6050: 0x68, OLED SSD1306: 0x3C...) rồi đọc/ghi thanh ghi.
Đặc điểm cần nhớ:
- Cần điện trở kéo lên 4.7kΩ từ SDA, SCL về VCC — module bán sẵn thường tích hợp rồi, nối 2-3 module song song là dư trở kéo (vẫn chạy được, nhưng bus dài + nhiều module có thể phải gỡ bớt)
- ESP32 mặc định SDA = GPIO 21, SCL = GPIO 22 (đổi được bằng
Wire.begin(sda, scl)) - Hai thiết bị trùng địa chỉ không sống chung bus — may là nhiều module có chân chọn địa chỉ (AD0 của MPU6050) hoặc dùng IC đa hợp TCA9548A
Công cụ số một: I2C Scanner
Nghi ngờ đấu dây hay địa chỉ? Quét bus là biết:
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin(); // SDA 21, SCL 22
for (byte addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print("Thay thiet bi tai 0x");
Serial.println(addr, HEX);
}
}
}
void loop() {}Không thấy gì: kiểm tra dây, nguồn, trở kéo. Thấy địa chỉ lạ: module dùng biến thể địa chỉ khác datasheet — cập nhật vào code. Chương trình 15 dòng này tiết kiệm nhiều giờ debug hơn bất kỳ công cụ nào khác.
SPI - tốc độ đổi bằng số dây
SPI dùng 4 đường: MOSI (master ra slave), MISO (slave về master), SCK (đồng hồ) và CS/SS (chọn thiết bị — mỗi slave một dây riêng). Đổi lại tốn dây, SPI chạy hàng chục Mbps — thứ I2C không mơ tới.
Trên robot, SPI xuất hiện khi dữ liệu lớn: màn TFT màu (đẩy cả khung hình), thẻ nhớ SD (ghi log), đầu đọc RFID RC522. Chân SPI mặc định của ESP32 (bus VSPI): MOSI 23, MISO 19, SCK 18, CS 5.
Tên chân đời mới: nhiều hãng đổi MOSI/MISO thành SDO/SDI hoặc PICO/POCI — cứ nhớ "data out của bên này vào data in của bên kia".
Nhận diện chuẩn qua tên chân module
| Trên nhãn module có... | Chuẩn | Đấu với ESP32 |
|---|---|---|
| TX, RX (hoặc TXD, RXD) | UART | Chéo: TX→16, RX→17 (UART2) |
| SDA, SCL | I2C | SDA→21, SCL→22, chung bus thoải mái |
| MOSI, MISO, SCK, CS (SDO, SDI) | SPI | 23, 19, 18, CS chọn chân tùy |
| DAT, CLK (mơ hồ) | Tra datasheet | Có thể I2C, SPI hoặc riêng |
| OUT / DO / AO đơn lẻ | Không phải bus | digitalRead / analogRead |
Ba lỗi giao tiếp kinh điển và cách gỡ
- I2C "không tìm thấy thiết bị": chạy scanner trước tiên; 90% là lỏng dây SDA/SCL hoặc thiếu nguồn module. Còn lại: sai địa chỉ, bus quá dài (I2C thích dây dưới 30 cm), thiếu trở kéo với module trần
- UART nhận toàn ký tự rác: sai baud rate hai bên, hoặc quên đấu chéo TX-RX, hoặc thiếu chung GND — ba thứ kiểm tra trong 30 giây
- SPI đọc toàn 0 hoặc 255: dây MISO/MOSI đảo nhau, CS không được kéo xuống khi giao dịch, hoặc mode SPI (0-3) không khớp thiết bị — thử đổi mode trong
SPISettings
Quy tắc chung mọi chuẩn: hai thiết bị giao tiếp phải chung GND — quên nối mass chung là lỗi nền của mọi hành vi ma quái.
Câu hỏi thường gặp
Một robot dùng đồng thời cả ba chuẩn được không?
Hoàn toàn — và robot tầm trung thường đúng như vậy: MPU6050 + OLED trên I2C, thẻ SD ghi log trên SPI, module GPS trên UART2. ESP32 có đủ khối phần cứng chạy song song cả ba không tranh chấp nhau.
Vì sao cùng là 2 dây mà không dùng I2C thay luôn UART?
Khác triết lý: I2C cần master chủ động hỏi từng nhịp; UART cho thiết bị tự tuôn dữ liệu bất cứ lúc nào (GPS gửi câu NMEA mỗi giây không cần ai hỏi). Module không dây (Bluetooth HC-05) cũng chuộng UART vì truyền trong suốt hai chiều như sợi dây nối dài.
Dây I2C kéo dài 2 mét được không?
Không nên — điện dung dây làm méo tín hiệu, chuẩn thiết kế cho khoảng cách trong bo/trong hộp máy. Cần xa: giảm tốc độ xuống 100 kHz và giảm trở kéo còn 2.2kΩ (tạm ổn đến ~1 m), hoặc chuyển hẳn sang chuẩn khác (UART, RS485) cho khoảng cách thật.
Servo driver PCA9685 dùng chuẩn gì?
I2C — đó chính là sức mạnh của nó: 2 dây điều khiển 16 servo, mắc chồng 62 bo được 992 kênh. Ví dụ đẹp về lý do I2C thống trị nhóm "nhiều thiết bị, dữ liệu nhỏ".
Tài nguyên tải về
Tải bản PDF của bài viết để in giáo án hoặc gửi trước cho học viên.



