How to use I2C Communication in STM32 Microcontroller
Trong các hướng dẫn trước đây, chúng ta đã tìm hiểu về giao tiếp SPI và I2C giữa hai bo mạch Arduino. Trong hướng dẫn này, chúng tôi sẽ thay thế một bảng Arduino bằng bảng Blue Pill là STM32F103C8 và sẽ giao tiếp với bảng Arduino bằng bus I2C.
STM32 có nhiều tính năng hơn board Arduino. Vì vậy, sẽ thật tuyệt khi tìm hiểu về giao tiếp giữa STM32 và Arduino bằng cách sử dụng bus SPI & I2C. Trong hướng dẫn này, chúng tôi sẽ sử dụng bus I2C để giao tiếp giữa Arduino và STM32F103C8, và sẽ tìm hiểu về bus SPI trong hướng dẫn tiếp theo. Để biết thêm về bảng STM32, hãy kiểm tra các dự án STM32 khác.
STM32F103C8 I2C Overview
I2C pins in STM32F103C8
SDA: PB7 or PB9, PB11.
SCL: PB6 or PB8, PB10.
I2C pins in Arduino
SDA: A4 pin
SCL: A5 pin
Components Required
- STM32F103C8
- Arduino Uno
- LED (2-Nos)
- Push Button (2-Nos)
- Resistors (4-Nos [10k-2 & 2.2k-2])
- Breadboard
- Connecting Wires
Circuit Diagram and Connections
Bảng sau đây cho thấy kết nối giữa STM32 Blue Pill và Arduino Uno để sử dụng bus I2C. Nó chỉ yêu cầu hai dây.
STM32F103C8 | Arduino | Pin Description |
B7 | A4 | SDA |
B6 | A5 | SCL |
GND | GND | Ground |
Quan trọng
Đừng quên kết nối Arduino GND và STM32F103C8 GND với nhau.
Sau đó kết nối một điện trở kéo xuống 10k với các chân nút nhấn của cả hai bảng riêng biệt.
Trong hướng dẫn STM32 I2C này, chúng ta sẽ cấu hình STM32F103C8 làm Master và Arduino làm Slave. Cả hai bảng đều được gắn đèn LED và nút nhấn riêng biệt.
Để chứng minh giao tiếp I2C trong STM32, chúng tôi điều khiển đèn LED STM32 chính bằng cách sử dụng giá trị nút nhấn Arduino phụ và điều khiển đèn LED Arduino phụ bằng cách sử dụng giá trị nút nhấn STM32F103C8 chính. Các giá trị này được gửi qua bus giao tiếp I2C.
I2C Programming in STM32
Master STM32 Programming Explanation
#include<Wire.h> #include<SoftWire.h>
2. In void setup()
- We Start Serial Communication at Baud Rate 9600.
Serial.begin(9600);
- Next we start the I2C communication at pin (B6,B7)
Wire.begin();
3. In Void loop()
- First we get the data from the Slave Arduino so we use requestFrom() with the slave address 8 and we request one byte.
Wire.requestFrom(8,1);
The received value is read using Wire.read()
byte a = Wire.read();
- Depending upon the received value from slave the Master LED is turned ON or OFF by using digitalwrite at pin PA1 and also serial print is used to print value in serial monitor
if (a==1) { digitalWrite(LED,HIGH); Serial.println("Master LED ON"); } else { digitalWrite(LED,LOW); Serial.println("Master LED OFF"); }
- Next we need to read the status of the pin PA0 that is the master STM32 push button.
int pinvalue = digitalRead(buttonpin);
- Next send the pin value according to the logic, so we use if condition and then begin the transmission with slave arduino with 8 as address and then write the value according to the push button input value.
if(pinvalue==HIGH) { x=1; } else { x=0; } Wire.beginTransmission(8); Wire.write(x); Wire.endTransmission();
Slave Arduino Programming Explanation
1. First of all we need to include the Wire library for using I2C communication functions.
#include<Wire.h>
2. In void setup()
- We Start Serial Communication at Baud Rate 9600.
Serial.begin(9600);
- Next start the I2C communication at pin (A4, A5) with slave address as 8. Here it is important to specify the slave address.
Wire.begin(8);
Next we need to call Wire.onReceive function when Slave receives value from master and Wire.onRequest function call when Master request value from Slave.
Wire.onReceive(receiveEvent); Wire.onRequest(requestEvent);
3. Next we have two functions one for request event and one for receive event
For request Event
When Master STM32 request value from slave this function will execute. This function does take input value from the Slave Arduino push button and send a byte (1 or 0) to Master STM32 according to push button value by using Wire.write().
void requestEvent() { int value = digitalRead(buttonpin); if (value == HIGH) { x=1; } else { x=0; } Wire.write(x); }
For Receive Event
When Master sends data to slave with slave address (8), this function will execute. This function reads the received value from master and store in a variable of type byte and then use if logic to turn slave LED ON or OFF depending upon the value received. If received value is 1 then LED turns ON and for 0 LED turns OFF.
void receiveEvent (int howMany) { byte a = Wire.read(); if (a == 1) { digitalWrite(LED,HIGH); Serial.println("Slave LED ON"); } else { digitalWrite(LED,LOW); Serial.println("Slave LED OFF"); } delay(500); }
Master STM32 Code
//I2C Master Code (STM32F103C8)
//I2C Communication between STM32 and Arduino
//Circuit Digest
#include<Wire.h>
#include<SoftWire.h> //Library for I2C Communication functions
#define LED PA1
#define buttonpin PA0
int x = 0;
void setup()
{
Serial.begin(9600); //Begins Serial Communication at 9600 baud rate
pinMode(buttonpin,INPUT); //Sets pin PA0 as input
pinMode(LED,OUTPUT); //Sets PA1 as Output
Wire.begin(); //Begins I2C communication at pin (B6,B7)
}
void loop()
{
Wire.requestFrom(8,1); // request bytes from slave arduino(8)
byte a = Wire.read(); // receive a byte from the slave arduino and store in variable a
if (a==1) //Logic to turn Master LED ON (if received value is 1) or OFF (if received value is 0)
{
digitalWrite(LED,HIGH);
Serial.println("Master LED ON");
}
else
{
digitalWrite(LED,LOW);
Serial.println("Master LED OFF");
}
{
int pinvalue = digitalRead(buttonpin); //Reads the status of the pin PA0
if(pinvalue==HIGH) //Logic for Setting x value (To be sent to slave Arduino) depending upon inuput from pin PA0
{
x=1;
}
else
{
x=0;
}
Wire.beginTransmission(8); // starts transmit to device (8-Slave Arduino Address)
Wire.write(x); // sends the value x to Slave
Wire.endTransmission(); // stop transmitting
delay(500);
}
}
Slave Arduino Code
//I2C Slave Code (Arduino)
//I2C Communication between STM32 and Arduino
//Circuit Digest
#include<Wire.h> //Library for I2C Communication functions
#define LED 7
#define buttonpin 2
byte x =0;
void setup()
{
Serial.begin(9600); //Begins Serial Communication at 9600 baud rate
pinMode(LED,OUTPUT); //Sets pin 7 as output
Wire.begin(8); // join i2c bus with its slave Address as 8 at pin (A4,A5)
Wire.onReceive(receiveEvent); //Function call when Slave Arduino receives value from master STM32
Wire.onRequest(requestEvent); //Function call when Master STM32 request value from Slave Arduino
}
void loop()
{
delay(100);
}
void receiveEvent (int howMany) //This Function is called when Slave Arduino receives value from master STM32
{
byte a = Wire.read(); //Used to read value received from master STM32 and store in variable a
if (a == 1) //Logic to turn Slave LED ON (if received value is 1) or OFF (if received value is 0)
{
digitalWrite(LED,HIGH);
Serial.println("Slave LED ON");
}
else
{
digitalWrite(LED,LOW);
Serial.println("Slave LED OFF");
}
delay(500);
}
void requestEvent() //This Function is called when Master STM32 wants value from slave Arduino
{
int value = digitalRead(buttonpin); //Reads the status of the pin 2
if (value == HIGH) //Logic to set the value of x to send to master depending upon input at pin 2
{
x=1;
}
else
{
x=0;
}
Wire.write(x); // sends one byte of x value to master STM32
}
}