Mạch tích hợp liên (I2C) là hệ thống trao đổi dữ liệu nối tiếp giữa vi điều khiển và mạch tích hợp chuyên dụng thế hệ mới. Nó được sử dụng khi khoảng cách giữa chúng ngắn (máy thu và máy phát thường nằm trên cùng một bảng in). Kết nối được thiết lập thông qua hai dây dẫn. Một được sử dụng để truyền dữ liệu và một được sử dụng để đồng bộ hóa (tín hiệu đồng hồ).
Như được thấy trong hình sau, một thiết bị luôn là thiết bị chính. Nó thực hiện định địa chỉ của một chip phụ trước khi bắt đầu giao tiếp. Bằng cách này, một vi điều khiển có thể giao tiếp với 112 thiết bị khác nhau. Tốc độ truyền thường là 100 Kb / giây (chế độ tiêu chuẩn) hoặc 10 Kb / giây (chế độ tốc độ truyền chậm). Các hệ thống có tốc độ truyền 3,4 Mb / giây đã xuất hiện gần đây. Khoảng cách giữa các thiết bị giao tiếp qua bus I2C được giới hạn trong vài mét.
Bảng I2C Pins
Bus I2C bao gồm hai tín hiệu – SCL và SDA. SCL là tín hiệu đồng hồ, và SDA là tín hiệu dữ liệu. Bus chính hiện tại luôn tạo ra tín hiệu đồng hồ. Một số thiết bị phụ có thể buộc xung nhịp ở mức thấp để trì hoãn việc gửi nhiều dữ liệu hơn cho thiết bị chính (hoặc cần nhiều thời gian hơn để chuẩn bị dữ liệu trước khi thiết bị chính cố gắng xử lý nó). Điều này được gọi là “đồng hồ kéo dài”.
Sau đây là các chân cho các bảng Arduino khác nhau:
- Uno, Pro Mini A4 (SDA), A5 (SCL)
- Mega, Do 20 (SDA), 21 (SCL)
- Leonardo, Yun 2 (SDA), 3 (SCL)
Arduino I2C
Chúng tôi có hai chế độ – mã chủ và mã phụ – để kết nối hai bảng Arduino bằng I2C. Họ là –
- Máy phát chính / Máy thu nô lệ
- Máy thu chính / Máy phát nô lệ
Máy phát chính / Máy thu nô lệ
Bây giờ chúng ta hãy xem bộ phát chính và bộ thu phụ là gì.
Máy phát chính
Các chức năng sau được sử dụng để khởi tạo thư viện Wire và tham gia bus I2C với tư cách là master hoặc slave. Điều này thường chỉ được gọi một lần.
- Wire.begin (địa chỉ) – Địa chỉ là địa chỉ nô lệ 7-bit trong trường hợp của chúng tôi vì cái chính không được chỉ định và nó sẽ tham gia xe buýt với tư cách là một cái chính.
- Wire.beginTransmission (địa chỉ) – Bắt đầu truyền đến thiết bị tớ I2C với địa chỉ đã cho.
- Wire.write (giá trị) – Xếp hàng các byte để truyền từ thiết bị chính đến thiết bị phụ (ở giữa các lệnh gọi đến beginTransmission () và endTransmission ()).
- Wire.endTransmission () – Kết thúc quá trình truyền tới một thiết bị phụ đã được bắt đầu bởi beginTransmission () và truyền các byte đã được xếp hàng bởi wire.write ().
Thí dụ
#include <Wire.h> //include wire library
void setup() //this will run only once {
Wire.begin(); // join i2c bus as master
}
short age = 0;
void loop() {
Wire.beginTransmission(2);
// transmit to device #2
Wire.write("age is = ");
Wire.write(age); // sends one byte
Wire.endTransmission(); // stop transmitting
delay(1000);
}
Người nhận nô lệ
Các chức năng sau được sử dụng:
- Wire.begin (địa chỉ) – Địa chỉ là địa chỉ nô lệ 7 bit.
- Wire.onReceive (trình xử lý dữ liệu đã nhận) – Hàm được gọi khi thiết bị phụ nhận dữ liệu từ thiết bị chính.
- Wire.available () – Trả về số byte có sẵn để truy xuất với Wire.read (). Điều này sẽ được gọi bên trong trình xử lý Wire.onReceive ().
Thí dụ
#include <Wire.h> //include wire library
void setup() { //this will run only once
Wire.begin(2); // join i2c bus with address #2
Wire.onReceive(receiveEvent); // call receiveEvent when the master send any thing
Serial.begin(9600); // start serial for output to print what we receive
}
void loop() {
delay(250);
}
//-----this function will execute whenever data is received from master-----//
void receiveEvent(int howMany) {
while (Wire.available()>1) // loop through all but the last {
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
}
Máy thu chính / Máy phát nô lệ
Bây giờ chúng ta hãy xem bộ thu chính và bộ phát phụ là gì.
Bộ thu chính
Master, được lập trình để yêu cầu, và sau đó đọc các byte dữ liệu được gửi từ Slave Arduino có địa chỉ duy nhất.
Hàm sau được sử dụng:
Wire.requestFrom (địa chỉ, số byte) – Được sử dụng bởi master để yêu cầu byte từ thiết bị phụ. Sau đó, các byte có thể được truy xuất bằng các hàm wire.available () và wire.read ().
Thí dụ
#include <Wire.h> //include wire library void setup() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop() {
Wire.requestFrom(2, 1); // request 1 bytes from slave device #2
while (Wire.available()) // slave may send less than requested {
char c = Wire.read(); // receive a byte as character
Serial.print(c); // print the character
}
delay(500);
}
Máy phát nô lệ
Chức năng sau được sử dụng.
Wire.onRequest (trình xử lý) – Một hàm được gọi khi một chủ yêu cầu dữ liệu từ thiết bị phụ này.Thí dụ
#include <Wire.h>
void setup() {
Wire.begin(2); // join i2c bus with address #2
Wire.onRequest(requestEvent); // register event
}
Byte x = 0;
void loop() {
delay(100);
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
Wire.write(x); // respond with message of 1 bytes as expected by master
x++;
}
Arduino – Giao diện ngoại vi nối tiếp
Bus Giao diện Ngoại vi Nối tiếp (SPI) là một hệ thống dành cho giao tiếp nối tiếp, sử dụng tới bốn dây dẫn, thường là ba. Một dây dẫn được sử dụng để nhận dữ liệu, một dây để gửi dữ liệu, một dây để đồng bộ hóa và một dây dẫn khác để chọn thiết bị để giao tiếp. Đó là kết nối song công, có nghĩa là dữ liệu được gửi và nhận đồng thời. Tốc độ truyền tối đa cao hơn tốc độ trong hệ thống truyền thông I2C.
Bảng SPI Pins
SPI sử dụng bốn dây sau:
- SCK – Đây là đồng hồ nối tiếp được điều khiển bởi chính.
- MOSI – Đây là đầu ra chính / đầu vào phụ do chủ điều khiển.
- MISO – Đây là đầu vào chính / đầu ra phụ do chính điều khiển.
- SS – Đây là dây lựa chọn phụ.
Các chức năng sau được sử dụng. Bạn phải bao gồm SPI.h.
- SPI.begin () – Khởi tạo bus SPI bằng cách đặt SCK, MOSI và SS thành đầu ra, kéo SCK và MOSI xuống thấp và SS cao.
- SPI.setClockDivider (bộ chia) – Để đặt bộ chia đồng hồ SPI so với đồng hồ hệ thống. Trên bo mạch dựa trên AVR, các bộ chia có sẵn là 2, 4, 8, 16, 32, 64 hoặc 128. Cài đặt mặc định là SPI_CLOCK_DIV4, đặt đồng hồ SPI thành một phần tư tần số của đồng hồ hệ thống (5 Mhz cho bo mạch ở 20 MHz).
- Dải phân cách – Có thể là (SPI_CLOCK_DIV2, SPI_CLOCK_DIV4, SPI_CLOCK_DIV8, SPI_CLOCK_DIV16, SPI_CLOCK_DIV32, SPI_CLOCK_DIV64, SPI_CLOCK_DIV128).
- SPI.transfer (val) – Truyền SPI dựa trên việc gửi và nhận đồng thời: dữ liệu nhận được sẽ được trả về trong acceptVal .
- SPI.beginTransaction (SPISettings (speedMaximum, dataOrder, dataMode)) – speedMaximum là đồng hồ, dataOrder (MSBFIRST hoặc LSBFIRST), dataMode (SPI_MODE0, SPI_MODE1, SPI_MODE2 hoặc SPI_MODE3).
Chúng tôi có bốn chế độ hoạt động trong SPI như sau:
- Chế độ 0 (mặc định) – Đồng hồ thường ở mức thấp (CPOL = 0) và dữ liệu được lấy mẫu khi chuyển đổi từ thấp lên cao (cạnh trước) (CPHA = 0).
- Chế độ 1 – Đồng hồ thường ở mức thấp (CPOL = 0) và dữ liệu được lấy mẫu khi chuyển đổi từ cao xuống thấp (cạnh sau) (CPHA = 1).
- Chế độ 2 – Đồng hồ thường ở mức cao (CPOL = 1) và dữ liệu được lấy mẫu khi chuyển đổi từ mức cao xuống mức thấp (cạnh trước) (CPHA = 0).
- Chế độ 3 – Đồng hồ thường ở mức cao (CPOL = 1) và dữ liệu được lấy mẫu khi chuyển đổi từ thấp lên cao (cạnh sau) (CPHA = 1).
- SPI.attachInterrupt (trình xử lý) – Hàm được gọi khi thiết bị phụ nhận dữ liệu từ thiết bị chính.
Bây giờ, chúng ta sẽ kết nối hai bảng Arduino UNO với nhau; một người với tư cách là chủ và người kia với tư cách là nô lệ.
- (SS): chân 10
- (MOSI): chân 11
- (MISO): chân 12
- (SCK): chân 13
Mặt bằng là chung. Sau đây là biểu diễn sơ đồ của kết nối giữa cả hai bảng
Chúng ta hãy xem các ví dụ về SPI là Master và SPI là Slave.
SPI với tư cách là MASTER
Thí dụ
#include <SPI.h>
void setup (void) {
Serial.begin(115200); //set baud rate to 115200 for usart
digitalWrite(SS, HIGH); // disable Slave Select
SPI.begin ();
SPI.setClockDivider(SPI_CLOCK_DIV8);//divide the clock by 8
}
void loop (void) {
char c;
digitalWrite(SS, LOW); // enable Slave Select
// send test string
for (const char * p = "Hello, world!\r" ; c = *p; p++) {
SPI.transfer (c);
Serial.print(c);
}
digitalWrite(SS, HIGH); // disable Slave Select
delay(2000);
}
SPI dưới dạng SLAVE
Thí dụ
#include <SPI.h>
char buff [50];
volatile byte indx;
volatile boolean process;
void setup (void) {
Serial.begin (115200);
pinMode(MISO, OUTPUT); // have to send on master in so it set as output
SPCR |= _BV(SPE); // turn on SPI in slave mode
indx = 0; // buffer empty
process = false;
SPI.attachInterrupt(); // turn on interrupt
}
ISR (SPI_STC_vect) // SPI interrupt routine {
byte c = SPDR; // read byte from SPI Data Register
if (indx < sizeof buff) {
buff [indx++] = c; // save data in the next index in the array buff
if (c == '\r') //check for the end of the word
process = true;
}
}
void loop (void) {
if (process) {
process = false; //reset the process
Serial.println (buff); //print the array on serial monitor
indx= 0; //reset button to zero
}
}