I.Giới thiệu
Giao tiếp ngoại vi nối tiếp hoặc SPI (Serial Peripheral Interface) là một chuẩn đồng bộ nối tiếp để truyền dữ liệu ở chế độ song công toàn phần (full – duplex) tức trong cùng một thời điểm có thể xảy ra đồng thời quá trình truyền và nhận.
Giao tiếp ngoại vi nối tiếp (SPI) là một loại giao thức kiểu Master – Slave cung cấp một giao diện chi phí đơn giản và chi phí thấp giữa vi điều khiển và các thiết bị ngoại vi của nó.
Bus giao tiếp SPI thường được sử dụng để giao tiếp vi xử lý hoặc vi điều khiển với bộ nhớ như EEPROM, RTC (Đồng hồ thời gian thực), ADC (Analog to Digital Converter – Bộ chuyển đổi tương tự sang số), DAC (Digital-to-Analog Converter – Bộ chuyển đổi số sang tương tự), thiết bị hiển thị như màn hình LCD, IC âm thanh, các loại cảm biến như nhiệt độ và áp suất, thẻ nhớ như MMC hoặc thẻ SD hoặc thậm chí các bộ vi điều khiển khác.
Chúng ta đã thấy về UART trong bài trước. Trong UART (hoặc bất kỳ cổng nối tiếp phổ biến nào) giao tiếp xảy ra trên đường RX và TX, không có tín hiệu đồng hồ tức là nó là một giao tiếp không đồng bộ. Trong loại giao tiếp này, không có kiểm soát dữ liệu được gửi hoặc liệu bộ phát và bộ thu có cùng tốc độ dữ liệu hay không.
Để khắc phục điều này, UART sử dụng các bit đồng bộ hóa tức là bit bắt đầu và bit kết thúc cũng như tốc độ truyền dữ liệu được thỏa thuận trước (thường là 9600 bps). Nếu tốc độ truyền của bộ phát và bộ thu không khớp, dữ liệu được gửi từ bộ phát sẽ không đến được bộ thu đúng cách và dữ liệu nhận được là không chính xác.
Đối với giao tiếp khoảng cách ngắn, giao tiếp nối tiếp đồng bộ sẽ là lựa chọn tốt hơn và trong đó giao tiếp ngoại vi nối tiếp hoặc SPI nói riêng là lựa chọn tốt nhất. Khi chúng ta nói truyền thông khoảng cách ngắn, nó thường có nghĩa là giao tiếp với một thiết bị hoặc giữa các thiết bị trên cùng một board mạch in (PCB).
Loại giao thức truyền thông đồng bộ nối tiếp khác là I2C (Inter-Integrated Communication. Đối với bài viết này, chúng ta sẽ tập trung vào SPI. Bạn có thể xem bài viết về giao thức I2C.
SPI là một kiểu truyền thông nối tiếp kiểu đồng bộ tức là nó sử dụng tín hiệu đồng hồ chuyên dụng để đồng bộ hóa bộ phát và bộ thu hoặc Master và Slave. Bộ phát và bộ thu được kết nối với dữ liệu riêng biệt và tín hiệu đồng hồ sẽ giúp bộ thu khi tìm kiếm dữ liệu trên bus.
Tín hiệu đồng hồ phải được cung cấp bởi Master tới Slave (hoặc tất cả các Slave trong trường hợp thiết lập nhiều Slave). Có hai loại cơ chế kích hoạt trên tín hiệu đồng hồ được sử dụng để báo cho bên nhận biết về dữ liệu: Kích hoạt cạnh và kích hoạt mức.
Kích hoạt thường được sử dụng nhất là kích hoạt cạnh và có hai loại: cạnh lên (chuyển đổi từ thấp lên cao trên đồng hồ) và cạnh xuống (chuyển đổi từ cao xuống thấp). Tùy thuộc vào cách bộ thu được cấu hình, lên trên phát hiện các cạnh, bộ thu sẽ tìm kiếm dữ liệu trên bus dữ liệu từ bit tiếp theo.
Bởi vì cả tín hiệu đồng hồ và dữ liệu được gửi bởi Master (hoặc bộ phát), chúng ta không cần phải lo lắng về tốc độ truyền dữ liệu.
Điều làm cho SPI trở nên phổ biến trong các giao thức truyền thông đồng bộ nối tiếp khác (hoặc bất kỳ giao tiếp nối tiếp nào) là nó cung cấp tốc độ truyền dữ liệu bảo mật cao với phần cứng khá đơn giản giống như thanh ghi dịch với chi phí tương đối thấp.
1.SPI hoạt động như thế nào?
SPI hoặc giao tiếp ngoại vi nối tiếp được Motorola phát triển vào những năm 1980 như một giao diện tiêu chuẩn, chi phí thấp và đáng tin cậy giữa vi điều khiển (Vi điều khiển của Motorola lúc đầu) và các IC ngoại vi của nó.
Nhờ giao diện đơn giản, linh hoạt và dễ sử dụng, SPI đã trở thành một tiêu chuẩn và các nhà sản xuất bán dẫn khác bắt đầu sử dụng giao thức này trong các chip của mình.
Trong giao thức SPI, các thiết bị được kết nối trong một mối quan hệ Master – Slave trong một giao diện đa điểm. Trong loại giao diện này, một thiết bị được coi là Master của bus (thường là một vi điều khiển) và tất cả các thiết bị khác (IC ngoại vi hoặc thậm chí các vi điều khiển khác) đều được coi là Slave.
Trong giao thức SPI, có thể chỉ có một thiết bị Master nhưng nhiều thiết bị Slave.
Bus SPI bao gồm 4 tín hiệu hoặc chân. Chúng là
- Master – Out / Slave – In (MOSI hay SI): cổng ra của bên Master, cổng vào của bên Slave, dành cho việc truyền dữ liệu từ thiết bị Master đến thiết bị Slave .
- Master – In / Slave – Out (MISO hay SO): cổng vào của bên Master, cổng ra của bên Slave, dành cho việc truyền dữ liệu từ thiết Slave đến thiết bị Master.
- Serial Clock (SCK hay SCLK): xung giữ nhịp cho giao tiếp SPI
- Chip Select (CS) hay Slave Select (SS): chọn chip
Lưu ý: Các nhà sản xuất khác nhau sử dụng thuật ngữ khác nhau cho bus SPI. Tham khảo datasheet để biết thông tin chính xác.
Bởi vì bus SPI được thực hiện bằng cách sử dụng 4 tín hiệu hay 4 dây nên đôi khi nó được gọi là chuẩn giao tiếp 4 dây (four-wire). Đầu tiên chúng ta hãy xem một giao diện đơn giản giữa một Master và một Slave được kết nối bằng giao thức SPI và sau đó chúng ta sẽ tìm hiểu về 4 dây này.
Hình ảnh sau mô tả một thiết bị Master (Bộ xử lý) được kết nối với thiết bị Slave (Ngoại vi) sử dụng bus SPI.
Master – Out / Slave – In hay MOSI, như tên cho thấy, là dữ liệu được tạo ra bởi Master và nhận bởi Slave. Do đó, các chân MOSI trên cả Master và Slave được kết nối với nhau.
Master – In / Slave – Out hay MISO là dữ liệu được tạo ra bởi Slave và phải được truyền tới Master.Các chân MISO trên cả Master và Slave được kết nối với nhau. Mặc dù tín hiệu trong MISO được tạo ra bởi Slave, đường tín hiệu này được điều khiển bởi Master.
Master tạo tín hiệu đồng hồ SCLK và được cung cấp cho đầu vào đồng hồ của Slave. Xung này có chức năng giữ nhịp cho giao tiếp SPI, vì SPI là chuẩn truyền đồng bộ nên cần 1 đường giữ nhịp, mỗi nhịp trên chân SCK báo 1 bit dữ liệu đến hoặc đi. Sự tồn tại của xung SCK giúp quá trình tuyền ít bị lỗi và vì thế tốc độ truyền của SPI có thể đạt rất cao.
Chip Select (CS) hoặc Slave Select (SS) được sử dụng để chọn một Slave cụ thể bởi Master. Nếu Master kéo đường SS của một Slave nào đó xuống mức thấp thì việc giao tiếp sẽ xảy ra giữa Master và Slave đó.
Vì đồng hồ được tạo ra bởi Master, luồng dữ liệu được điều khiển bởi Master. Với mỗi chu kỳ đồng hồ, một bit dữ liệu được truyền từ Master đến Slave và một bit dữ liệu được truyền từ Slave đến Master.
Quá trình này xảy ra đồng thời và sau 8 chu kỳ đồng hồ, một byte dữ liệu được truyền theo cả hai hướng và do đó, SPI là một giao tiếp song công toàn phần (full – duplex).
Nếu dữ liệu phải được truyền bởi chỉ một thiết bị, thì thiết bị kia phải gửi một cái gì đó (dữ liệu giả) và nó phụ thuộc vào thiết bị cho dù dữ liệu được truyền là dữ liệu thực tế hay không.
Điều này có nghĩa là đối với mỗi bit được truyền bởi một thiết bị, thiết bị kia phải gửi dữ liệu một bit, tức là Master truyền dữ liệu đồng thời trên MOSI và nhận dữ liệu từ Slave trên đường MISO.
Nếu Slave muốn truyền dữ liệu, Master phải tạo ra tín hiệu đồng hồ cho phù hợp bằng cách biết khi nào Slave muốn gửi dữ liệu trước. Nếu một Master được kết nối với nhiều Slave thì sơ đồ kết nối như hình ảnh sau đây.
Mặc dù nhiều Slave được kết nối với Master trong bus SPI, ở một thời điểm bất kỳ thì chỉ có một Slave hoạt động. Để chọn Slave, Master sẽ kéo đường SS (Slave Select) hoặc CS (Chip Select) của Slave tương ứng xuống mức thấp.
Do đó, phải có một chân CS riêng trên Master tương ứng với từng thiết bị Slave. Chúng ta cần phải kéo xuống đường SS hoặc CS xuống thấp để chọn Slave bởi vì đường này tích cực mức thấp.
2.Phần cứng SPI
Yêu cầu phần cứng để thực hiện SPI rất đơn giản khi so sánh với UART và I2C. Hãy xem xét một Master và một Slave đơn được kết nối bằng bus SPI. Hình ảnh sau đây cho thấy các yêu cầu hệ thống tối thiểu cho cả hai thiết bị.
Từ hình ảnh trên cho thấy thiết bị Master bao gồm một thanh ghi dịch (Shift Register), một mạch chốt dữ liệu (Latch) và một bộ tạo xung nhịp (Clock Generator). Thiết bị Slave bao gồm phần cứng tương tự: một thanh ghi dịch (Shift Register) và một mạch chốt dữ liệu (Latch). Cả hai thanh ghi dịch được kết nối để tạo thành một vòng. Thông thường, kích thước của thanh ghi là 8 – bit nhưng thanh ghi kích thước lớn hơn 16 bit cũng rất phổ biến.
Thiết bị Master bắt đầu việc trao đổi dữ liệu bằng cách truyền đi một Byte vào thanh ghi dịch của nó, sau đó Byte dữ liệu sẽ được đưa sang Slave theo đường tín hiệu MOSI, Slave sẽ truyền dữ liệu nằm trong thanh ghi dịch của chính nó ngược trở về Master thông qua đường tín hiệu MISO. Bằng cách này, dữ liệu của hai thanh ghi sẽ được trao đổi với nhau. Việc đọc và ghi dữ liệu vào Slave diễn ra cùng một lúc nên tốc độ trao đổi dữ liệu diễn ra rất nhanh. Do đó, giao thức SPI là một giao thức rất có hiệu quả.
Bởi vì với mỗi chu kỳ đồng hồ, một bit dữ liệu được truyền theo từng hướng tức là từ Master đến Slave và từ Slave đến Master. Vì vậy, đối với một byte dữ liệu được truyền từ mỗi thiết bị, nó sẽ mất 8 chu kỳ đồng hồ.
3.Chế độ hoạt động SPI
Chúng ta đã thấy rằng công việc của thiết bị Master là tạo ra tín hiệu đồng hồ và phân phối nó tới Slave để đồng bộ dữ liệu giữa Master và Slave. Công việc của Master không chỉ dừng lại ở việc tạo tín hiệu đồng hồ ở tần số cụ thể.
Trong thực tế, Master và Slave phải đồng ý về các giao thức đồng bộ hóa nhất định. Đối với điều này, hai đặc điểm của xung đồng hồ là cực tính đồng hồ (Clock Polarity – CPOL hoặc CKP) và pha đồng hồ (Clock Phase – CPHA) được đưa vào để xem xét.
Clock Polarity (CPOL hoặc CKP) xác định trạng thái của đồng hồ. Khi CPOL ở mức thấp, xung đồng hồ được tạo bởi Master tức là SCK sẽ ở mức thấp khi nhàn rỗi (idle) và chuyển sang mức cao trong trạng thái hoạt động (trong khi truyền dữ liệu). Tương tự, khi CPOL ở mức cao, SCK ở mức cao khi nhàn rỗi và chuyển sang mức thấp trong trạng thái hoạt động.
Phase Clock (CPHA) xác định quá trình chuyển đổi trạng thái của xung đồng hồ tức là lên (thấp lên cao) hoặc xuống (cao xuống thấp), tại đó dữ liệu được truyền đi. Khi CPHA bằng 0, dữ liệu được truyền ở cạnh lên của xung đồng hồ. Dữ liệu được truyền ở cạnh xuống khi CPHA là 1.
Tùy thuộc vào các giá trị của Clock Polarity (CPOL) và Clock Phase (CPHA), có 4 chế độ hoạt động của SPI
Mode 0:
Mode 0 xảy ra khi Clock Polarity và Clock Phase là 0 (CPOL = 0 và CPHA = 0). Trong Mode 0, truyền dữ liệu xảy ra trong khi cạnh lên của xung đồng hồ.
Mode 1:
Mode 1 xảy ra khi Clock Polarity là 0 và Clock Phase là 1 (CPOL = 0 và CPHA = 1). Trong mode 1, việc truyền dữ liệu xảy ra trong khi cạnh xuống của xung đồng hồ.
Mode 2:
Mode 2 xảy ra khi Clock Polarity là 1 và Clock Phase là 0 (CPOL = 1 và CPHA = 0). Trong mode 2, truyền dữ liệu xảy ra trong khi cạnh lên của xung đồng hồ.
Mode 3:
Mode 3 xảy ra khi Clock Polarity là 1 và Clock Phase là 1 (CPOL = 1 và CPHA = 1). Trong mode 3, truyền dữ liệu xảy ra trong khi cạnh lên của xung đồng hồ.
4.Cấu hình SPI
Có hai loại cấu hình trong đó các thiết bị SPI có thể được kết nối trong một bus SPI. Đó là
- Cấu hình Master và các Slave độc lập (Independent Slave Configuration) và
- Cấu hình Daisy Chain (Daisy Chain Configuration).
Trong cấu hình Master và các Slave độc lập, Master đã dành riêng các đường Slave Select cho tất cả các Slave và mỗi Slave có thể được chọn riêng lẻ. Tất cả tín hiệu đồng hồ của các Slave được kết nối với chung với SCK của Master.
Tương tự, tất cả các chân MOSI của tất cả các SLave được kết nối với chân MOSI của Master và tất cả các chân MISO của tất cả các Slave được kết nối với chân MISO của Master.
Trong cấu hình Daisy Chain, chỉ có một đường Slave Select được kết nối với tất cả các Slave. MOSI của Master được kết nối với MOSI của Slave 1. MISO của Slave 1 được kết nối với MOSI của Slave 2 và v.v.. MISO của Slave cuối cùng được kết nối với MISO của Master.
Giả sử Master truyền đi 3 byte dữ liệu lên bus SPI. Byte đầu tiên được dịch vào Slave 1. Khi byte thứ hai truyền đến 1, byte đầu tiên sẽ bị đẩy ra khỏi Slave 1 và truyền đến Slave 2. Tương tự, khi byte thứ ba truyền vào Slave 1, byte thứ hai sẽ bị dịch sang Slave 2 và byte đầu tiên sẽ bị dịch Slave 3.
Nếu Master muốn đọc lại dữ liệu trong Slave 1, nó phải truyền lại chuỗi 3 byte dữ liệu (giả) lần nữa. Khi đó dữ liệu trong Slave 1 sẽ chuyển sang Slave 2 rồi chuyển sang Slave 3, sau đó về Master.
Suốt quá trình xử lý, Master luôn nhận được byte dữ liệu từ Slave 2 và 3.
Tuy nhiên, cầu hình Daisy Chain không phải lúc nào cũng áp dụng được cho tất cả các thiết bị Slave. Do đó, ta cần phải tham khảo datasheet trước khi tiến hành kết nối.
5.Ứng dụng của SPI
Giao thức SPI được tích hợp trong một số loại thiết bị như:
- Các bộ chuyển đổi (ADC và DAC)
- Các loại bộ nhớ (SD Card , MMC , EEPROM , Flash)
- Các loại IC thời gian thực
- Các loại cảm biến (nhiệt độ, áp suất…)
- và một số loại khác như: bộ trộn tín hiệu, LCD, Graphic LCD, video game controller,…