
SPI (Serial Peripheral Interface) là một giao thức truyền thông nối tiếp đồng bộ (synchronous serial communication) thường được sử dụng để trao đổi dữ liệu giữa vi xử lý (microprocessor) và các thiết bị ngoại vi như cảm biến, màn hình, bộ nhớ…
Không như giao thức I2C, SPI chỉ hỗ trợ một Master và đa Slave. SPI phù hợp với các ứng dụng cần truyền dữ liệu nhanh như giao tiếp với màn hình (LCD), cảm biến tốc độ cao, và bộ nhớ Flash.
Xem thêm: Giao thức I2C là gì?
Các chân của giao thức SPI
SPI sử dụng 4 dây cơ bản để truyền dữ liệu:
- MOSI (Master Out Slave In) – Dữ liệu từ Master đến Slave.
- MISO (Master In Slave Out) – Dữ liệu từ Slave đến Master.
- SCK (Serial Clock) – Xung nhịp do Master cung cấp.
- SS (Slave Select) / CS (Chip Select) – Tín hiệu chọn Slave.

Nguyên lý hoạt động của SPI
SPI chỉ có một Master và có thể có nhiều Slave. Khi Master muốn giao tiếp với một Slave cụ thể, nó sẽ kéo chân SS của Slave đó xuống mức thấp (0). Master sẽ tạo xung nhịp (SCLK) để đồng bộ dữ liệu.
Dữ liệu được truyền đồng thời theo cả hai chiều:
- MOSI: Master gửi dữ liệu đến Slave.
- MISO: Slave gửi dữ liệu về Master.
- Do dữ liệu đi theo hai hướng cùng lúc, nên SPI là full-duplex.
Chỉ Master mới có quyền tạo xung nhịp (SCLK), còn Slave chỉ nhận xung.
Trường hợp có một Slave
Nếu chỉ có một Slave duy nhất, chân SS có thể nối trực tiếp xuống GND hoặc lập trình để luôn ở mức thấp (0).
Trường hợp có nhiều Slave
- Mỗi Slave có một chân SS riêng.
- Master sẽ chọn Slave cần giao tiếp bằng cách kéo SS của Slave đó xuống mức thấp (0).
- Các Slave còn lại sẽ không hoạt động khi SS ở mức cao (1).
Cách truyền dữ liệu của giao thức SPI
1. Khi nào Master và Slave trao đổi dữ liệu?
SPI thuộc loại giao thức đồng bộ, có nghĩa là Slave chỉ có thể gửi và nhận dữ liệu khi có xung nhịp từ Master. Điều này khác với giao thức bất đồng bộ (như UART), nơi dữ liệu có thể truyền mà không cần tín hiệu xung nhịp chung.
Hình 3 mô tả Master và Slave chỉ trao đổi dữ liệu khi có xung clock (SCLK) từ Master tạo ra.

Xem thêm: Xung clock là gì?
2. Nguyên tắc truyền dữ liệu
Khi một bit được dịch ra (Shift out) từ thanh ghi dữ liệu của Slave trên MISO thì đồng thời cũng có một bit được dịch vào (Shift into) thanh ghi này ở trên MOSI trong cùng một xung clock.

Dữ liệu được truyền thường là 8 bits hoặc 16 bits.
- Thứ tự truyền bit có thể là MSB trước hoặc LSB trước:
- MSB trước (Most Significant Bit First): Bit có trọng số cao được truyền trước.
- LSB trước (Least Significant Bit First): Bit có trọng số thấp được truyền trước.
3. Điều gì xảy ra khi Slave muốn gửi dữ liệu còn Master không có dữ liệu để gửi?
Trong SPI, Slave không thể tự gửi dữ liệu—nó chỉ có thể truyền khi có xung nhịp (SCLK) từ Master.
Mỗi lần có một xung nhịp, cả Master và Slave đều phải gửi một dữ liệu ra ngoài, dù cho đang có dữ liệu hay không.
Khi Slave muốn gửi dữ liệu nhưng Master không có dữ liệu nào để gửi đi, Master sẽ gửi một dữ liệu giả (dummy data), ví dụ 0xFF hoặc 0x00 qua đường MOSI để Slave có thể gửi dữ liệu về qua đường MISO.
Ví dụ thực tế:
Giả sử Master cần đọc dữ liệu nhiệt độ từ một cảm biến SPI:
- Master kéo chân SS xuống (chọn cảm biến).
- Master gửi một byte dummy (ví dụ: 0xFF) trên MOSI.
- Xung nhịp được tạo ra → Slave gửi dữ liệu nhiệt độ thực tế qua MISO.
- Master nhận dữ liệu từ MISO trong khi gửi dummy trên MOSI.
- Quá trình lặp lại nếu cần đọc thêm dữ liệu.
Xem thêm: GPIO là gì?
Clock Polarity (CPOL) và Clock Phase (CPHA)
Trong giao tiếp SPI, Master có thể điều CPOL và CPHA để phù hợp với Slave. Hai thông số này quyết định cách dữ liệu được gửi đi và được đọc.

1. Clock Polarity (CPOL)
CPOL xác định trạng thái mặc định của xung nhịp (SCLK) khi không truyền dữ liệu (idle state là lúc không có truyền dữ liệu, tức là Master chưa bắt đầu giao tiếp với Slave):
- CPOL = 0: Xung SCLK mặc định ở mức thấp (0) khi không hoạt động.
- CPOL = 1: Xung SCLK mặc định ở mức cao (1) khi không hoạt động.
2. Clock Phase (CPHA)
CPHA xác định cạnh xung nào được sử dụng để ghi và đọc dữ liệu.
3. Ví dụ
Khi CPHA = 0: cạnh đầu tiên thay đổi sẽ đọc dữ liệu và cạnh thứ hai sẽ ghi dữ liệu
- CPOL = 0: Xung SCLK mặc định ở mức thấp (0) khi không hoạt động, cạnh đầu tiên (thay đổi từ mức thấp (mức mặc định) lên mức cao) sẽ đọc dữ liệu và cạnh thứ hai (thay đổi từ mức cao xuống mức thấp) sẽ ghi (truyền) dữ liệu.
- CPOL = 1: Xung SCLK mặc định ở mức cao (1) khi không hoạt động, cạnh đầu tiên (thay đổi từ mức cao xuống mức thấp) sẽ đọc dữ liệu và cạnh thứ hai (thay đổi từ mức thấp lên mức cao) sẽ ghi (truyền) dữ liệu.
Khi CPHA = 1: cạnh đầu tiên thay đổi sẽ ghi (truyền) dữ liệu và cạnh thứ hai sẽ đọc dữ liệu
- CPOL = 0: Xung SCLK mặc định ở mức thấp (0) khi không hoạt động, cạnh đầu tiên (thay đổi từ mức thấp (mức mặc định) lên mức cao) sẽ ghi (truyền) dữ liệu và cạnh thứ hai (thay đổi từ mức cao xuống mức thấp) sẽ đọc dữ liệu.
- CPOL = 1: Xung SCLK mặc định ở mức cao (1) khi không hoạt động, cạnh đầu tiên (thay đổi từ mức cao xuống mức thấp) sẽ ghi (truyền) dữ liệu và cạnh thứ hai (thay đổi từ mức thấp lên mức cao) sẽ đọc dữ liệu.
4. Hình ảnh minh hoạ




Multi-Subnode (Multi-Slave) trong SPI
Khi sử dụng giao tiếp SPI, một Master có thể kết nối với nhiều thiết bị phụ (Subnode (Slave)). Có hai cách để kết nối các Subnode (Slave): chế độ thông thường (regular mode) và chế độ chuỗi liên tiếp (daisy-chain mode).
Xem thêm: Tổng quan về ngắt (Interrupt)
1. Chế độ thông thường (regular mode)

- Trong chế độ này, mỗi Subnode (Slave) cần một chân chip select (CS) riêng biệt từ Master.
- Khi Master kéo xuống mức thấp một tín hiệu CS cụ thể, chỉ Subnode (Slave) tương ứng mới nhận được dữ liệu từ đường MOSI (Master Out Slave In) và gửi dữ liệu qua đường MISO (Master In Slave Out).
- Nếu có nhiều tín hiệu CS được kích hoạt cùng lúc, dữ liệu trên đường MISO sẽ bị lỗi vì Master không thể phân biệt được Subnode (Slave) nào đang truyền dữ liệu.
Nhược điểm:
- Khi số lượng Subnode (Slave) tăng lên, số chân chip select cũng tăng theo, gây ra giới hạn về số lượng thiết bị có thể kết nối.
- Giải pháp để mở rộng số Subnode (Slave) có thể là sử dụng bộ chuyển mạch (mux) để tạo tín hiệu chip select.
2. Chế độ chuỗi liên tiếp (daisy-chain mode).

- Trong chế độ này, tất cả các Subnode (Slave) dùng chung một tín hiệu chip select (CS).
- Dữ liệu được truyền từ Master đến Subnode (Slave) đầu tiên, sau đó Subnode (Slave) này chuyển tiếp dữ liệu đến Subnode (Slave) tiếp theo, và cứ tiếp tục như vậy.
- Tất cả các Subnode (Slave) nhận cùng một xung clock SPI.
Nhược điểm:
- Dữ liệu cần nhiều chu kỳ clock hơn để đến được các Subnode (Slave) sau trong chuỗi. Ví dụ, trong hệ thống 8-bit, nếu Subnode (Slave) thứ 3 cần nhận dữ liệu, thì phải mất 24 chu kỳ clock, trong khi chế độ thông thường chỉ cần 8 chu kỳ clock.
- Không phải tất cả các thiết bị SPI đều hỗ trợ chế độ daisy-chain. Cần kiểm tra trong tài liệu kỹ thuật của thiết bị để xác nhận tính năng này.

Ưu và nhược điểm của giao tiếp SPI
1. Ưu điểm:
Đơn giản: SPI dễ triển khai do không có nhiều quy tắc phức tạp như I2C.
Tiêu thụ ít năng lượng: Do hoạt động dựa trên tín hiệu số đơn giản.
Tốc độ cao: Hỗ trợ tốc độ truyền dữ liệu lớn hơn so với I2C vì không cần xác nhận (ACK/NACK) và có thể truyền song song hai chiều (full-duplex).
2. Nhược điểm:
Không hỗ trợ nhiều Master: Chỉ có một Master duy nhất trong hệ thống, hạn chế tính linh hoạt khi cần nhiều thiết bị điều khiển.
Slave không thể chủ động giao tiếp: Chỉ có Master mới có quyền bắt đầu truyền dữ liệu, các Slave chỉ phản hồi khi được chọn.
Slave không kiểm soát được tốc độ truyền: Master quyết định toàn bộ tốc độ thông qua xung nhịp (SCLK), các Slave chỉ có thể theo tốc độ đó mà không thể thay đổi.
SPI phù hợp với các ứng dụng cần truyền dữ liệu nhanh như giao tiếp với màn hình, cảm biến tốc độ cao, và bộ nhớ Flash.
Giao thức SPI là một phương pháp truyền thông nối tiếp đồng bộ phổ biến, mang lại tốc độ cao và tính linh hoạt trong việc kết nối giữa vi điều khiển và các thiết bị ngoại vi. Với khả năng giao tiếp full-duplex và cấu trúc đơn giản, SPI được ứng dụng rộng rãi trong các hệ thống nhúng, cảm biến tốc độ cao, bộ nhớ Flash, màn hình hiển thị, và nhiều thiết bị điện tử khác. Việc lựa chọn chế độ SPI phù hợp phụ thuộc vào yêu cầu cụ thể của hệ thống, bao gồm tốc độ, số lượng thiết bị kết nối, và tài nguyên phần cứng sẵn có. Hiểu rõ nguyên lý hoạt động của SPI giúp bạn thiết kế hệ thống giao tiếp tối ưu và hiệu quả hơn trong các ứng dụng thực tế.
Xem thêm: Timer là gì?