Esp8266学习7. 点亮JMD0.96C-1 OLED屏
- 一、ESP32-C3 I2C资源简介
- 1. 简介
- 2. 准备工作
- 二、I2C协议简介
- 1. 起始条件(Start Condition):
- 2. 设备地址传输(Device Address Transmission):
- 3. 从设备响应(Slave Acknowledgment):
- 4. 数据传输(Data Transmission):
- 5. 停止条件(Stop Condition):
- 6. 重复起始条件(Repeated Start Condition):
- 三、I2C通讯示例
- 1. 接线
- 2. 基本使用 查询I2C资源地址
- 3. 点亮OLED屏
一、ESP32-C3 I2C资源简介
1. 简介
ESP8266具有一个I2C控制器,通常称为I2C主机。这个I2C控制器可以用来连接各种I2C外设,如传感器、显示屏等。
在ESP8266上,I2C控制器的引脚分配如下:
- SDA(Serial Data Line):通信数据线
- SCL(Serial Clock Line):时钟线
这两个引脚的位置可以根据具体的ESP8266开发板而有所不同。
使用ESP8266的Arduino库,可以通过以下步骤使用ESP8266的I2C功能:
- 引入Wire库:在Arduino代码中引入Wire库,该库提供了与I2C通信相关的函数。
- 初始化I2C:在setup()函数中,使用Wire.begin(sda, scl)函数初始化I2C控制器,其中sda和scl是你选择的引脚。
- 发送和接收数据:使用Wire.beginTransmission()和Wire.endTransmission()函数发送和接收数据。
- 读写数据:使用Wire.requestFrom()和Wire.write()函数来读写数据。
2. 准备工作
- NodeMCU开发板 1.0
- Arduino 开发工具 2.1.1
二、I2C协议简介
I2C(Inter-Integrated Circuit)是一种用于短距离通信的串行通信协议,通常用于连接芯片之间,比如连接微控制器、传感器、显示屏等。它使用两根信号线(SDA和SCL)来实现通信,具有简单、灵活和多设备连接的特点。
以下是I2C协议的基本通讯过程:
1. 起始条件(Start Condition):
通信开始前,主设备(通常是微控制器)发送一个起始条件,即将SDA从高电平转换为低电平,然后再将SCL从高电平转换为低电平。这表明通信开始。
2. 设备地址传输(Device Address Transmission):
主设备会发送要通信的设备的7位地址,最高位是读写位(0表示写操作,1表示读操作)。设备在总线上监听地址,匹配地址的设备响应。
3. 从设备响应(Slave Acknowledgment):
如果有设备的地址匹配,从设备会发送一个应答位,将SDA拉低表示接受通信。如果没有匹配设备,从设备不发送应答位,SDA保持高电平。
4. 数据传输(Data Transmission):
主设备发送数据位,从设备每接收一个位都会发送应答位。数据位是一个8位字节,从设备会在每个字节接收完毕后发送应答。
5. 停止条件(Stop Condition):
通信结束后,主设备发送一个停止条件,即将SDA从低电平转换为高电平,然后再将SCL从低电平转换为高电平。这表明通信结束。
6. 重复起始条件(Repeated Start Condition):
主设备可以在不释放总线的情况下发送重复的起始条件,用于在一个通信过程中切换到不同的设备。
I2C通信可以实现多主设备和多从设备的连接。在多主设备情况下,主设备之间需要协调以避免冲突。在多从设备情况下,每个从设备都有唯一的地址,主设备可以根据需要与特定的从设备通信。
三、I2C通讯示例
1. 接线
下面示例使用GPIO4作为 SDA引脚, GPIO5作为SCL引脚。
从图上看到,将 OLED 屏的SDA接到 D2引脚, SCL接到 D1引脚。
如果使用ESP32C3-mini-1开发板,则把SDA接到4脚, SCL接到5脚。
2. 基本使用 查询I2C资源地址
#include <Wire.h>
// 自定义 I2C 引脚
#define SDA_PIN 4
#define SCL_PIN 5
void setup() {
// 初始化I2C总线,指定SDA和SCL引脚
Wire.begin(SDA_PIN, SCL_PIN);
Serial.begin(9600);
while (!Serial); // Leonardo: 等待串口监视器连接
// 输出开始信息
Serial.println("I2C Scanner");
}
void loop() {
byte error, address;
int nDevices;
// 输出正在扫描信息
Serial.println("Scanning...");
// 记录找到的设备数量
nDevices = 0;
for (address = 1; address < 127; address++) {
// 启动与指定地址的I2C通信
Wire.beginTransmission(address);
// 结束I2C通信并获取错误码
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
// 输出找到的设备地址
Serial.print(address, HEX);
// 输出设备找到的标志
Serial.println(" !");
// 增加找到设备的计数
nDevices++;
} else if (error == 4) {
Serial.print("Unknown error at address 0x");
if (address < 16)
Serial.print("0");
// 输出发生错误的地址
Serial.println(address, HEX);
}
}
if (nDevices == 0){
// 输出没有找到设备的信息
Serial.println("No I2C devices found");
}
else{
// 输出没有找到设备的信息
Serial.println("done");
}
// 等待5秒进行下一次扫描
delay(5000);
}
运行结果可以看到I2C的设备(这里是OLED屏)地址是0x3C。
3. 点亮OLED屏
#include <Wire.h> // 引入Wire库
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// 在这里定义你的自定义I2C引脚
#define SDA_PIN 4
#define SCL_PIN 5
void setup() {
Serial.begin(9600);
Serial.println("begin...");
// 初始化OLED显示屏对象,设置分辨率为128x64
Wire.begin(SDA_PIN, SCL_PIN);
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
// 初始化OLED显示屏
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
// 设置文本样式
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// 显示提示信息 Drawing Shapes
display.setCursor(30, 8);
display.println("Drawing Shapes");
// 绘制文本 Square:
display.setTextSize(1);
display.setCursor(10, 25);
display.println("Square:");
// 在屏幕内部绘制正方形
display.drawRect(15, 40, 20, 20, SSD1306_WHITE); // (x, y, width, height, color)
// 显示文本 Circle:
display.setTextSize(1);
display.setCursor(60, 25);
display.println("Circle:");
// 在屏幕内部绘制圆
display.drawCircle(80, 50, 12, SSD1306_WHITE); // (centerX, centerY, radius, color)
// 更新显示内容
display.display();
Serial.println("end");
}
void loop() {
}
运行示例: