Arduino ESP32 指南

Arduino ESP32 指南 > API > I2C

I2C

I2C(内部集成电路)/ TWI(两线接口)是一种广泛使用的串行通信,用于在短距离内连接设备。这是用于连接传感器、EEPROM、RTC、ADC、DAC、显示器、OLED 以及许多其他设备和微控制器的最常见外设之一。

这种串行通信被视为低速总线,多个设备可以连接在同一条双线总线上,每条总线都有一个唯一的 7 位地址(最多 128 个设备)。这两条线称为 SDA (串行数据线) 和 SCL (串行时钟线)。

注意

SDA 和 SCL 线路需要上拉电阻器。有关电阻器值和工作电压的更多详细信息,请参阅器件数据表。

I2C 模式

I2C 可以在两种不同的模式下使用:

  • I2C Master 主模式
    • 在此模式下,ESP32 生成时钟信号并启动与从设备的通信。
I2C
  • I2C Slave 从模式
    • 从 Slave 模式,clock 由 master 设备生成,如果目标地址与目标地址相同,则响应 master。
I2C

Arduino-ESP32 I2C API

ESP32 I2C 库基于 Arduino Wire Library 并实现了更多 API,如本文档所述。

I2C 通用 API

以下是用于 master 和 slave 模式的常用函数。

begin  开始

此功能用于使用默认配置启动外围设备。

bool begin();

如果外围设备已正确初始化,则此函数将返回 true。

setPins 设置引脚

此功能用于定义 SDA 和 SCL 引脚。

注意

在开始更改默认引脚之前调用此函数。

bool setPins(int sdaPin, int sclPin);
  • sdaPin 设置要用作 I2C 外设数据线的 GPIO。
  • sclPin 设置要用作 I2C 外设时钟线的 GPIO。

默认引脚可能因板而异。在通用 ESP32 上,默认 I2C 引脚为:

  • sdaPin GPIO21
  • sclPin GPIO22

如果外围设备配置正确,则此函数将返回 true。

setClock  设置时钟

使用此功能设置总线时钟。如果不使用此函数,将使用默认值。

bool setClock(uint32_t frequency);
  • frequency 设置总线频率 clock。

如果 clock 配置正确,则此函数将返回 true。

getClock

使用此功能获取总线时钟。

uint32_t getClock();

此函数将返回当前频率配置。

setTimeOut 设置超时

设置以毫秒为单位的总线超时。默认值为 50 毫秒。

void setTimeOut(uint16_t timeOutMillis);
  • timeOutMillis 以毫秒为单位设置超时。

getTimeOut

获取总线超时(以毫秒为单位)。

uint16_t getTimeOut();

此函数将返回当前的超时配置。

write  写入

此函数将数据写入缓冲区。

size_t write(uint8_t);

size_t write(const uint8_t *, size_t);

返回值将是添加到缓冲区的数据的大小。

end  结束

此功能将完成通信并释放所有分配的资源。调用 end 后,您需要再次使用 begin 才能再次初始化 I2C 驱动程序。

bool end();

I2C Master 主模式

此模式用于启动与从站的通信。

基本用法

要开始在 Arduino 上使用 I2C 主模式,第一步是将 Wire.h 接头包含在 sketch 中。

#include "Wire.h"

现在,我们可以通过调用 begin 函数来启动外设配置。

Wire.begin();

通过使用不带任何参数的 begin,所有设置都将使用默认值完成。要自行设置值,请参阅函数说明。这个函数描述在这里:i2c begin

调用 begin 后,我们可以通过调用 beginTransmission 并传入 I2C slave 地址来开始传输:

Wire.beginTransmission(I2C_DEV_ADDR);

要将一些字节写入 slave,请使用 write 函数。

Wire.write(x);

您可以使用 write 函数传递不同的数据类型。这个函数描述在这里:i2c 写入

注意

write 函数不直接写入从器件,而是添加到 I2C 缓冲区。为此,您需要使用 endTransmission 函数将缓冲的字节发送到从设备。

Wire.endTransmission(true);

调用 endTransmission 后,存储在 I2C buffer 中的数据将被传输到 slave 设备。

现在您可以从 slave 设备请求读数。requestFrom 将通过提供地址和大小来要求读取所选设备。

Wire.requestFrom(I2C_DEV_ADDR, SIZE);

readBytes 将读取它。

Wire.readBytes(temp, error);

I2C Master API

以下是 I2C Master API。这些函数仅用于主模式。

begin  开始

在 master 模式下,可以通过传递 pins 和 bus frequency 来使用 begin 函数。此功能仅用于主模式。

bool begin(int sdaPin, int sclPin, uint32_t frequency)

或者,您可以使用不带任何参数的 begin 函数来使用所有默认值。

如果外围设备已正确初始化,则此函数将返回 true。

beginTransmission  开始传输

此函数用于对与 slave 设备的通信进程进行 star 排序。在将消息写入缓冲区之前,通过传递从地址来调用此函数。

void beginTransmission(uint16_t address)

endTransmission (结束传输)

使用 i2c write 写入缓冲区后,使用函数 endTransmission 将消息发送到 beginTransmission 函数定义的从设备地址。

uint8_t endTransmission(bool sendStop);
  • sendStop 启用 (true) 或禁用 (false) 停止信号 (仅在主模式下使用)。

在没有 sendStop 的情况下调用 this 函数等效于 sendStop = true。

uint8_t endTransmission(void);

此函数将返回错误代码。

requestFrom 

要从从设备读取数据,请使用 requestFrom 函数。

uint8_t requestFrom(uint16_t address, uint8_t size, bool sendStop)
  • address 设置设备地址。
  • size 定义要请求的大小。
  • sendStop 启用 (true) 或禁用 (false) 停止信号。

此函数将返回从设备读取的字节数。

示例应用程序 - WireMaster.ino

以下是如何在 Master 模式下使用 I2C 的示例。

examples/WireMaster/WireMaster.ino

I2C Slave 从模式

此模式用于接受来自主站的通信。

基本用法

要开始在 Arduino 上使用 I2C 作为从模式,第一步是将 Wire.h 标头包含在 sketch 中。

#include "Wire.h"

在调用 begin 之前,我们必须创建两个回调函数来处理与主设备的通信。

Wire.onReceive(onReceive);

Wire.onRequest(onRequest);

onReceive 将在从设备读取请求时处理来自主设备的请求,而 onRequest 将处理对主设备的应答。

现在,我们可以通过使用设备地址调用 begin 函数来启动外设配置。

Wire.begin((uint8_t)I2C_DEV_ADDR);

通过使用不带任何参数的 begin,所有设置都将使用默认值完成。要自行设置值,请参阅函数说明。这个函数描述在这里:i2c begin

仅适用于 ESP32!

使用函数 slaveWrite 预写入从属响应缓冲区。这仅用于 ESP32,以便在芯片上添加 slave 功能并保持与 Arduino 的兼容性。

Wire.slaveWrite((uint8_t *)message, strlen(message));

I2C Slave APIs

以下是 I2C Slave API。这些函数仅用于 slave 模式。

begin  开始

在 slave 模式下,必须通过传递 slave 地址来使用 begin 函数。您还可以定义引脚和总线频率 。

bool Wire.begin(uint8_t addr, int sdaPin, int sclPin, uint32_t frequency)

如果外围设备已正确初始化,则此函数将返回 true。

onReceive

onReceive 函数用于定义从 master 接收的数据的回调。

void onReceive( void (*)(int) );

onRequest

onRequest 函数用于定义要发送到 master 的数据的回调。

void onRequest( void (*)(void) );

slaveWrite

slaveWrite 函数在接收响应消息之前写入从属响应缓冲区。此功能仅用于添加 ESP32 的 slave 兼容性。

警告

只有 ESP32 才需要此功能。ESP32-S2 和 ESP32-C3 不需要使用。

size_t slaveWrite(const uint8_t *, size_t);

示例应用程序 - WireSlave.ino

以下是如何在 Slave 模式下使用 I2C 的示例。

examples/WireSlave/WireSlave.ino