25 Giới thiệu giao thức SPI 
Tài liệu tham khảo
STM32 Serial Peripheral Interface
Một số hình ảnh từ bài viết lấy từ tài liệu trên.
SPI là gì? 
SPI (Serial Peripheral Interface – Giao tiếp ngoại vi nối tiếp) là một giao thức truyền thông nối tiếp đồng bộ, dùng để truyền dữ liệu giữa vi điều khiển (MCU) và các thiết bị ngoại vi. Giao thức này hoạt động theo mô hình một master – nhiều slave, thường được sử dụng cho các kết nối tốc độ cao, khoảng cách ngắn và hỗ trợ giao tiếp song công (full-duplex).
SPI được ứng dụng rộng rãi trong các hệ thống nhúng và thiết bị điện tử như: bộ nhớ Flash, EEPROM, cảm biến, driver màn hình, mô-đun không dây, v.v.
Đặc điểm cơ bản của SPI 
- Thiết bị master là bên khởi tạo và điều khiển giao tiếp, còn thiết bị slave là bên phản hồi và xử lý lệnh từ master.
- Master điều khiển tốc độ truyền thông thông qua tín hiệu xung nhịp (clock).
- SPI sử dụng nhiều đường truyền dữ liệu hai chiều để gửi và nhận thông tin.
Nguyên lý hoạt động: 
- Master truyền dữ liệu tới slave thông qua chân MOSI (Master Out Slave In). Ở mỗi chu kỳ xung clock, một bit dữ liệu được gửi lên đường MOSI và được slave đọc ở chu kỳ kế tiếp.
- Slave truyền dữ liệu ngược lại master thông qua chân MISO (Master In Slave Out). Slave cũng gửi một bit dữ liệu ở mỗi chu kỳ xung và master đọc lại bit này.
- SPI hỗ trợ giao tiếp song công thực sự, tức là dữ liệu có thể được gửi và nhận đồng thời giữa master và slave.
- Độ dài dữ liệu truyền thường theo đơn vị byte (8 bit), nhưng có thể thay đổi tùy theo cấu hình.
- SPI cũng có thể cấu hình để truyền dữ liệu một chiều nếu cần.
- Có thể có nhiều master trong một hệ thống SPI nếu thiết kế phù hợp, nhưng cần có cơ chế điều phối tránh xung đột.
Giao tiếp phần cứng của SPI 
SPI sử dụng 4 đường tín hiệu chính để truyền thông:
| Đường tín hiệu | Chức năng | 
|---|---|
| SCLK | Đường xung nhịp (còn gọi là SCK) – được tạo ra bởi thiết bị master. | 
| MOSI | Master Out Slave In – master gửi dữ liệu đến slave (còn gọi là SDO). | 
| MISO | Master In Slave Out – slave gửi dữ liệu về master (còn gọi là SDI). | 
| CS | Chip Select (còn gọi là NSS) – tín hiệu chọn thiết bị slave do master điều khiển. | 
Giải thích hoạt động: 
- Thiết bị master chọn thiết bị slave muốn giao tiếp thông qua tín hiệu CS (Chip Select). - Khi CS = mức thấp (LOW) → slave được chọn và kích hoạt.
- Một số thiết bị đặc biệt có thể dùng mức cao (HIGH) để kích hoạt — cần kiểm tra datasheet cụ thể.
 
- Dữ liệu được đồng bộ nhờ đường xung SCLK do master tạo ra. - Xung lên (rising edge) hoặc xung xuống (falling edge) được dùng để điều khiển việc truyền và lấy mẫu dữ liệu.
 
- Kết nối giữa các thiết bị SPI cần đúng chiều: - MOSI của master nối với MOSI (hoặc SDI) của slave
- MISO của master nối với MISO (hoặc SDO) của slave
 
Lưu ý: Sau khi thiết lập vai trò master/slave, vai trò này không thay đổi trong lúc hoạt động.

Dưới đây là sơ đồ kết nối cơ bản giữa một vi điều khiển (MCU) ở vai trò master và một thiết bị ngoại vi (slave) sử dụng giao tiếp SPI:
         Master (MCU)                    Slave (Thiết bị ngoại vi)
        ┌──────────────┐                ┌────────────────────────┐
        │              │                │                        │
        │     SCLK     ├───────────────►│     SCLK (CLK)         │
        │              │                │                        │
        │     MOSI     ├───────────────►│     MOSI (SDI)         │
        │              │                │                        │
        │     MISO     │◄───────────────┤     MISO (SDO)         │
        │              │                │                        │
        │      CS      ├───────────────►│      CS (NSS/SS)       │
        └──────────────┘                └────────────────────────┘          ┌──────────────┐
          │   Master     │
          │ (Vi điều khiển)│
          ├──────────────┤
          │   SCLK       ├──────────────SCLK
          │   MOSI       ├──────────────MOSI
          │   MISO       ◄──────────────MISO
          │   CS1 (NSS1) ├───────CS1
          │   CS2 (NSS2) ├──────────────CS2
          │   CS3 (NSS3) ├───────────────────CS3
          └──────────────┘                                                
    ┌────────────────────┐   ┌────────────────────┐   ┌────────────────────┐
    │     Slave 1        │   │      Slave 2       │   │     Slave 3        │
    │    (e.g. Flash)    │   │     (e.g. OLED)    │   │   (e.g. Sensor)    │
    ├────────────────────┤   ├────────────────────┤   ├────────────────────┤
    │    SCLK ◄──────────┘   │     SCLK ◄─────────┘   │    SCLK ◄──────────┘
    │    MOSI ◄──────────    │     MOSI ◄─────────    │    MOSI ◄──────────
    │    MISO ───────────►   │     MISO ──────────►   │    MISO ───────────►
    │    CS   ◄──────── CS1  │     CS   ◄─────── CS2  │    CS   ◄──────── CS3
    └────────────────────┘   └────────────────────┘   └────────────────────┘- Lựa chọn chế độ SPI - Giao thức SPI định nghĩa nhiều chế độ truyền dữ liệu, còn được gọi là SPI Mode hoặc chế độ xung nhịp, nhằm điều khiển trình tự truyền dữ liệu và thời điểm lấy mẫu theo tín hiệu đồng hồ (clock). - SPI có 2 thông số cốt lõi xác định chế độ: - CKPL (Clock Polarity – Cực tính xung): Xác định mức điện áp của đường SCK khi ở trạng thái nhàn rỗi (idle). - CKPL = 0: SCK mặc định là mức thấp
- CKPL = 1: SCK mặc định là mức cao
 
- CKPH (Clock Phase – Pha xung): Xác định cạnh xung nào dùng để lấy mẫu và cập nhật dữ liệu. - CKPH = 0: Lấy mẫu ở cạnh đầu tiên của xung (tức cạnh lên nếu CKPL=0, cạnh xuống nếu CKPL=1)
- CKPH = 1: Lấy mẫu ở cạnh thứ hai của xung
 
 - Bảng tóm tắt 4 chế độ SPI chuẩn: - Chế độ - CKPL - CKPH - Trạng thái SCK khi idle - Lấy mẫu tại cạnh - Mode 0 - 0 - 0 - Mức thấp - Cạnh lên (rising) - Mode 1 - 0 - 1 - Mức thấp - Cạnh xuống (falling) - Mode 2 - 1 - 0 - Mức cao - Cạnh xuống (falling) - Mode 3 - 1 - 1 - Mức cao - Cạnh lên (rising) 
- CKPL (Clock Polarity – Cực tính xung): Xác định mức điện áp của đường SCK khi ở trạng thái nhàn rỗi (idle). 
 

Ví dụ về sử dụng các chế độ SPI 
Việc lựa chọn chế độ SPI (Mode 0 ~ Mode 3) phụ thuộc vào yêu cầu kỹ thuật của thiết bị slave và giao thức truyền thông cụ thể của thiết bị đó.
- Mỗi thiết bị ngoại vi (như cảm biến, bộ nhớ Flash, màn hình SPI...) có thể yêu cầu chế độ SPI khác nhau.
- Trước khi giao tiếp với thiết bị slave, cần phải tra datasheet hoặc tài liệu kỹ thuật để biết chế độ SPI được hỗ trợ.
Trường hợp không rõ chế độ SPI: 
Nếu thiết bị không ghi rõ chế độ SPI nào được sử dụng, có thể thử:
- Mode 0 (CKPL=0, CKPH=0)
- hoặc Mode 3 (CKPL=1, CKPH=1) vì đây là hai chế độ phổ biến nhất được sử dụng trong thực tế.
Lưu ý thêm: 
- Ngoài CKPL/CKPH, cần kiểm tra giới hạn tần số xung nhịp SPI của thiết bị slave. - Nếu xung SPI từ master quá nhanh, thiết bị slave có thể không phản hồi đúng hoặc lỗi dữ liệu.
- Ví dụ: nhiều EEPROM SPI chỉ hỗ trợ tần số tối đa 5MHz, trong khi master mặc định có thể chạy 10–20MHz → cần giảm tốc độ SPI phù hợp.
 
Kết luận: 
Trước khi cấu hình SPI:
- Xác định chế độ SPI (Mode 0 ~ 3) từ datasheet thiết bị slave.
- Điều chỉnh tần số SPI theo giới hạn của thiết bị.
- Đảm bảo master và slave cùng dùng một chế độ.
SPI phần mềm và SPI phần cứng 
Tương tự như IIC, SPI được chia thành SPI phần mềm và SPI phần cứng. Phần SPI phần mềm sẽ không được trình bày lại trong tài liệu này. Chương này tập trung giải thích về SPI phần cứng. STM32F407 được trang bị nhiều mô-đun SPI phần cứng (Giao tiếp Ngoại vi Nối tiếp), dùng để thực hiện giao tiếp nối tiếp tốc độ cao với các thiết bị bên ngoài. Mỗi mô-đun SPI phần cứng có các thanh ghi độc lập và tín hiệu điều khiển, có thể được cấu hình ở chế độ chủ (master) hoặc chế độ phụ (slave).
Ưu điểm của việc sử dụng SPI phần cứng:
- Hỗ trợ ngắt và DMA: SPI phần cứng có thể hoạt động cùng với bộ điều khiển ngắt và bộ điều khiển DMA, giúp xử lý và truyền dữ liệu hiệu quả.
- Bộ đệm phần cứng: SPI phần cứng có bộ đệm nội bộ, hỗ trợ trung chuyển dữ liệu giữa thiết bị chủ và thiết bị ngoại vi, nâng cao hiệu suất truyền dữ liệu.
- Truyền dữ liệu tốc độ cao: SPI phần cứng sử dụng mô-đun phần cứng để truyền dữ liệu, thường nhanh hơn so với SPI được thực hiện bằng phần mềm.

Sơ đồ khối SPI phần cứng
Ưu điểm và nhược điểm của giao thức SPI 
Ưu điểm 
Dễ triển khai: Giao thức SPI có cách triển khai phần cứng và phần mềm tương đối đơn giản, quá trình giao tiếp rõ ràng và dễ hiểu, thuận tiện cho việc gỡ lỗi. Điều này khiến giao thức SPI được sử dụng rộng rãi trong các hệ thống nhúng.
Truyền dữ liệu tốc độ cao: Giao thức SPI hỗ trợ truyền dữ liệu tốc độ cao. Vì SPI là giao thức giao tiếp điểm-điểm, dữ liệu được truyền trực tiếp giữa thiết bị chủ và thiết bị phụ mà không cần kiểm tra địa chỉ hay xung đột. Dữ liệu gửi và nhận được thực hiện trên các đường tín hiệu riêng biệt, do đó tốc độ truyền cao.
Linh hoạt: Giao thức SPI cho phép thiết bị chủ giao tiếp với nhiều thiết bị phụ. Thiết bị chủ có thể chọn thiết bị phụ cụ thể thông qua tín hiệu chọn chip (chip select), từ đó thực hiện giao tiếp nối tiếp với nhiều thiết bị.
Nhược điểm 
Độ dài đường tín hiệu hạn chế: Do giao thức SPI không có quy định cụ thể về độ dài của đường tín hiệu, các đường tín hiệu dài có thể gây ra vấn đề về độ ổn định và tốc độ truyền. Khi giao tiếp ở khoảng cách xa, cần xem xét độ tin cậy của việc truyền tín hiệu.
Số lượng đường tín hiệu lớn: Giao thức SPI yêu cầu một đường điều khiển riêng cho mỗi thiết bị phụ, do đó với hệ thống có nhiều thiết bị, số lượng đường tín hiệu cần thiết sẽ tăng đáng kể.
Không có cơ chế bắt tay: Giao thức SPI không cung cấp cơ chế “bắt tay” (handshake) như giao thức I2C, tức là thiết bị phụ không thể chủ động gửi yêu cầu dữ liệu đến thiết bị chủ. Do đó, SPI có thể không phù hợp với các ứng dụng yêu cầu thiết bị phụ tương tác chủ động với thiết bị chủ.
Lĩnh vực ứng dụng của giao thức SPI 
SPI là một giao diện giao tiếp nối tiếp phổ biến, được sử dụng rộng rãi trong giao tiếp giữa các thiết bị điện tử số và analog. Với đặc điểm đơn giản, hiệu quả và linh hoạt, SPI được ứng dụng rộng rãi trong nhiều lĩnh vực, tương tự như giao thức I2C.
Trong lĩnh vực bộ nhớ và chip flash, giao thức SPI được sử dụng để giao tiếp với các chip bộ nhớ (như EEPROM, SRAM) và chip flash (như thẻ SD, SPI Flash). Thông qua giao thức SPI, các chip này có thể trao đổi dữ liệu với bộ điều khiển chính, hỗ trợ đọc/ghi và lưu trữ dữ liệu tốc độ cao.
Giao thức SPI cũng được ứng dụng rộng rãi trong lĩnh vực màn hình OLED và màn hình LCD. Nhiều màn hình sử dụng giao thức SPI để truyền dữ liệu hình ảnh và tín hiệu điều khiển.
Ngoài ra, SPI còn được sử dụng trong các lĩnh vực như cảm biến và truyền thông. Cần lưu ý rằng SPI là một giao thức giao tiếp điểm-điểm, thường hoạt động theo kiến trúc chủ-phụ, trong đó một thiết bị đóng vai trò thiết bị chủ và các thiết bị khác đóng vai trò thiết bị phụ.