Giao tiếp SPI là gì? Cách kết nối với Arduino

Giao tiếp SPI được sử dụng rất nhiều trong các dự án điện tử và lập trình nhúng, cho phép hệ thống có thể kết nối và truyền dữ liệu giữa các thiết bị với nhau. Trong bài viết này, hãy cùng tìm hiểu kỹ hơn về khái niệm, lợi ích và cách ứng dụng SPI để điều khiển mạch chiết áp trên Arduino UNO.

Giao tiếp SPI là gì?

SPI là viết tắt của Serial Parallel Interface, đây là một chuẩn kết nối đồng bộ. Điều này đồng nghĩa với SPI sẽ truyền dữ liệu được tính giờ bằng xung đồng hồ. SPI giúp truyền dữ liệu giữa một Master và nhiều Slave qua các đường tín hiệu, như hình:

Khái niệm giao tiếp SPI

SPI được sử dụng trong các hệ thống cần truyền dữ liệu trong khoảng cách gần, thường là dưới 10m. Giao tiếp này thường được sử dụng phổ biến trong nhiều ứng dụng khác nhau như điều khiển ngoại vi, viễn thông, làm việc với cảm biến, đèn LED, quạt mini hoặc nhiều thiết bị khác. 

Cấu tạo của mạng SPI

Để có thể giao tiếp và truyền dữ liệu, một giao thức SPI sẽ bao gồm một thiết bị chính (Master) và nhiều thiết bị phụ (Slave) được kết nối thông qua bus:

1. Thiết bị Master

Thiết bị này có vai trò gửi dữ liệu đi và nhận dữ liệu từ các thiết bị phụ. Trong một mạng SPI chỉ có 1 thiết bị Master.

2. Thiết bị Slave

Thiết bị này nhận yêu cầu từ thiết bị Master và gửi trả kết quả, dữ liệu về cho Master. Trong một mạng SPI có thể có một hoặc nhiều Slave.

3. Bus SPI

Bus SPI là các đường truyền giúp kết nối Master với Slave. Các Master và Slave cần có 4 chân sau để kết nối với nhau:

  • Master Out Slave In (MOSI): Cho phép Master gửi dữ liệu đến Slave
  • Master In Slave Out (MISO): Cho phép Slave gửi dữ liệu về lại Master
  • Serial Clock (SCLK): Tín hiệu xung đồng hồ được tạo ra từ Master, điều khiển việc đồng bộ truyền dữ liệu
  • Slave Select/Chip Select (SS/CS): Cho phép Master thông báo đến Slave rằng nó sẽ gửi yêu cầu dữ liệu, khi đó chân này sẽ có giá trị là LOW. Ở trạng thái bình thường. chân sẽ có giá trị là HIGH. 

Trong quá trình kết nối, các thiết bị Master sẽ chọn Slave cần làm việc bằng cách chỉnh chân SS/CS thành LOW.

Cách kết nối các thiết bị Master và Slave

Mình sẽ hướng dẫn bạn cách kết nối 2 mô hình thường gặp nhất trong giao tiếp SPI:

Mô hình 1 Master – 1 Slave

Việc kết nối 1 – 1 như vậy rất đơn giản, chúng ta chỉ cần đấu các dây tương ứng với nhau như hình dưới:

Cách kết nối 1 Master 1 Slave trong giao tiếp SPI
Cách kết nối 1 Master 1 Slave trong giao tiếp SPI

Với mô hình này, để gửi dữ liệu từ Master đến Slave, chúng ta sẽ cấu hình chân SS/CS thành LOW và giữ nguyên cấu hình này trong suốt thời gian gửi dữ liệu. Đây là tín hiệu để Slave biết được phải nhận dữ liệu.

Ở trạng thái LOW này, Master có thể gửi dữ liệu đến Slave thông qua MOSI và tạo ra các xung đồng hồ qua chân SCLK đồng bộ.

Mô hình 1 Master – Nhiều Slave

Với các mạng giao tiếp SPI có nhiều thiết bị con (Slave), bạn có thể chọn nối dây độc lập hoặc nối dây nối tiếp. Cụ thể:

1. Nối dây độc lập

Ở cách kết nối nãy, mỗi chân SS/CS của Master sẽ kết nối với một Slave riêng biệt:

Kết nối dây độc lập trong giao thức SPI

Trong mô hình này, khi cần gửi dữ liệu đến Slave nào, Master sẽ đổi cấu hình chân SS/CS kết nối đến thiết bị đó thành LOW. Trạng thái này sẽ giữ nguyên trong suốt khoảng thời gian diễn ra sự trao đổi dữ liệu.

Tương tự như mô hình 1 – 1, khi cấu hình SS/CS thành LOW, thiết bị Master sẽ tự động gửi dữ liệu qua MOSI và gửi xung đồng hồ qua SCLK. Nếu Master cần nhận được phản hồi kết quả từ Slave, chúng sẽ liên tục gửi xung đồng hồ mãi cho đến khi nhận được dữ liệu phản hồi trên chân MISO.

2. Nối dây nối tiếp

Điểm khác biệt của mô hình SPI Protocol này là Master chỉ dùng 1 chân SS/CS để làm việc với tất cả các thiết bị Slave trong hệ thống. Cụ thể như hình:

Giao tiếp SPI theo mô hình nối tiếp

Cũng tương tự như các mô hình trên, đầu tiên thiết bị Master sẽ đổi chân SS/CS thành LOW để bắt đầu giao tiếp SPI. Sau đó, chúng bắt đầu gửi dữ liệu và tạo xung nhịp. Dữ liệu gửi từ Master sẽ được truyền từ Slave này sang Slave khác trong chuỗi. Khi còn đang trong trạng thái truyền dữ liệu thì cấu hình chân SS/CS sẽ luôn ở trạng thái LOW.

Lưu ý là trong mô hình giao tiếp SPI của mô hình 1 Master – nhiều Slave này, thiết bị Master cần gửi đủ xung đồng hồ để dữ liệu có thể truyền tới Slave cuối cùng trong hệ thống. Nếu cần nhận phản hồi về, Master sẽ duy trì việc gửi xung đồng hồ này liên tục cho đến khi nhận được dữ liệu.

Cách sử dụng giao thức SPI để điều khiển chiết áp trên Arduino

Bây giờ, mình sẽ hướng dẫn bạn cách sử dụng giao tiếp SPI bằng cách thực hiện một ví dụ minh họa trực quan: Điều khiển mạch chiết áp MCP4131 bằng mạch Arduino UNO thông qua giao thức SPI.

Chúng ta sẽ theo dõi điện trở của MCP4131 bằng cách in chúng lên màn hình Monitor Serial.

Giao diện Arduino UNO SPI

Trên phần cứng mạch Arduino UNO có tích hợp sẵn giao tiếp SPI, với sẵn các chân như hình:

Mạch Arduino UNO hỗ trợ giao tiếp SPI

Mạch chiết áp MCP4131

Về cơ bản, mạch chiết áp này chỉ là một điện trở có chân cắm chiết áp. Chúng ta có thể điều chỉnh điện trở ở chân 6 bằng cách gửi lệnh SPI qua các chân 1, 2, 3.

Dưới đây là sơ đồ của mạch chiết áp MC4131:

Sơ đồ của mạch chiết áp MCP4131

Vậy, các chân MISO, MOSI, SCLK ở đâu trong sơ đồ trên? Đôi khi các chân dùng để giao tiếp SPI sẽ được đặt với các tên khác nhau tùy vào đơn vị sản xuất. Các chân SPI trong mạch chiết áp MCP4131 là:

  • MISO: Đầu vào dữ liệu nối tiếp (SDI) ở chân 3 (được dùng kết hợp MOSI)
  • MOSI: Đầu vào dữ liệu nối tiếp (SDO) ở chân 3 (dùng kết hợp với MISO)
  • SCLK: Đồng hồ nối tiếp ở chân 2

Kết nối MCP4131 với Arduino qua giao tiếp SPI

Đầu tiên, bạn cần chuẩn bị các thiết bị sau:

  • Mạch Arduino UNO
  • Mạch chiết asp MCP4131
  • Breadboard
  • Dây Jumper

Sau đó, bạn hãy kết nối các phần cứng như hình bên dưới:

Kết nối phần cứng để bắt đầu giao tiếp SPI

Tải thư viện SPI

Bạn hãy tải thư viện SPI qua đường link sau Thư viện SPI và cài vào Arduino IDE nhé!

Nạp code

Mình đã chuẩn bị sẵn đoạn code dưới, bạn hãy dùng và nạp vào mạch của mình nhé:

#include <SPI.h>

void setup() {
  pinMode(10, OUTPUT); // set the SS pin as an output
  SPI.begin();         // initialize the SPI library
  Serial.begin(9600);
}

void loop() {

  digitalWrite(10, LOW);            // set the SS pin to LOW
  
  for(byte wiper_value = 0; wiper_value <= 128; wiper_value++) {

    SPI.transfer(0x00);             // send a write command to the MCP4131 to write at registry address 0x00
    SPI.transfer(wiper_value);      // send a new wiper value

    Serial.println(analogRead(A0)); // read the value from analog pin A0 and send it to serial
    delay(1000); 
  }

  digitalWrite(10, HIGH);           // set the SS pin HIGH
}

Kết quả

Sau khi kết nối phần cứng và nạp code vào mạch, hãy mở màn hình Serial Monitor của Arduino để xem giá trị điện áp nhé! Mạch Arduino sẽ liên tục gửi yêu cầu đến mạch chiết áp để thay đổi giá trị từ 0 đến 128 và lặp lại liên tục.

Do đó, giá trị điện trở trên Serial sẽ thay đổi từ 0 đến 1023, tùy thuộc vào giá trị điện trở trên MCP4131:

  • Khi điện trở cao, điện áp ở chân Analog A0 thấp -> Con số trên Serial sẽ nhỏ
  • Tương tự, khi điện trở thấp thì con số trên Serial sẽ lớn

Đây là một ví dụ đơn giản về dự án sử dụng chuẩn giao tiếp SPI. Bạn có thể ứng dụng hướng dẫn này vào các dự án khác với những thiết bị SPI đa dạng tùy thích.

Lời kết

Trên đây, IoTZone đã giải đáp chi tiết về giao tiếp SPI là gì, cách kết nối cũng như xây dựng một dự án đơn giản trên Arduino ứng dụng SPI. Bạn đã thực hiện thành công dự án trên chưa? Nếu có bất kỳ thắc mắc nào, bạn có thể liên hệ chúng tôi để được hỗ trợ nhé!

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *