IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> ESP32 的 I2C 原理 & 应用入门 -> 正文阅读

[嵌入式]ESP32 的 I2C 原理 & 应用入门

集成电路总线 ( Inter-Integrated Circuit ,缩写 I2C ),详细说明参见:I2C(维基百科)

I2C 总线介绍

  • I2C 总线由数据线 SDA 和 时钟线 SCL 两条线构成通信线路,即可发送数据,也可接收数据。在 I2C 通信中,支持一主多从多主多从,即可以有多个 I2C 设备同时并联到 I2C 总线上。
  • 在 I2C 通信过程中,CPU 发出的控制信号分为地址码数据码两部分
    • 地址码用来选址,即接通需要控制的电路。每个 I2C 设备都有唯一的地址,在信息传输过程中,通过不同的设备地址来识别通信对象。这样各 I2C 设备虽然挂在同一条总线上,却彼此独立。
    • 数据码是通信的内容。

地址码(7 bit):

  • 以 24C02 (EEPROM)芯片为例,高 4 bit 是固定的 1010,而低 3 bit 的地址取决于具体的硬件电路设计,由芯片的 A2、A1、A0 这 3 个管脚的实际电平决定。
    在这里插入图片描述
    如图,A2、A1、A0 这 3 个管脚都接 GND,即地址码的低 3 bit 都为 0 ,规则为 :1010(A0)(A1)(A2)(R/W),R/W 位我们要设置为0 (写操作)。因此 24C02 (EEPROM)芯片的地址码为:(0b)1010000 , 即 0x50 。

I2C 接口的优点:

  • 接口线少
  • 控制简单
  • 通信速率较高
  • 器件封装形式小

I2C 通信格式

I2C 通信格式包含起始信号数据传输停止信号

在这里插入图片描述

  • 起始信号SCL处于高电平,SDA 由高到低。I2C 通信的起始信号的定义是在 SCL 为高电平器件,SDA 由高电平向低电平变化产生一个下降沿,表示起始信号,如上图 Start 部分所示。
  • 数据传输SDA 上的数据必须在 SCL 高电平周期时保持稳定,数据的高低电平翻转变化发生在 SCL 低电平时期。I2C 时序要求当 SCL 在低电平的时候,SDA 运行变化,即发送方必须先保持 SCL 是低电平,才可以改变数据线 SDA,输出要发送的当前数据的一位;而 SCL 在高电平的时候,SDA 绝对不可以变化,因为此时接收方要来读取当前 SDA 的电平信号是 0 还是 1 ,所以需要保证 SDA 的稳定。如图中的每一位数据的变化,都是在 SCL 为低电平的位置。数据位后面跟着的是1 bit 应答位(ACK)
  • 停止信号SCL 处于高电平,SDA 由低到高。I2C 通信停止信号的定义是 SCL 为高电平期间,SDA 由低电平向高电平变化产生一个上升沿,表示结束信号,如图中的 Stop 部分所示。

I2C 数据传输有 3 种情形:写传输读传输混合传输。对于一次完整的数据传输,由多个字节传输组成。

  • 写传输:
    在这里插入图片描述
    如上图所示。在主机发出 START 之后的第 1 次字节传输中,主机发送 7bit 从机地址,1bit 写指示(0)。被寻址的从机在收到第 1 次字节传输后回复 ACK。之后主机根据需要进行多次的字节传输,向对应从机写数据。从机每一次字节传输均需要回复ACK。当主机数据发送完毕后,发出 STOP 指示(图中的 P)告知从机本次写传输完成。

  • 读传输:

在这里插入图片描述
如上图所示。在主机发出 START 之后的第 1 次字节传输中,主机发送 7bit 从机地址,1bit 读指示(1)。被寻址的从机在收到第 1 次字节传输后回复 ACK,并接管数据线向主机传递数据,主机每收到一字节数据则向从机回复一次 ACK。最后一次字节传输时,主机回复 NACK 并且发出 STOP 告知从机读传输完成。


说明:

  • SDA 数据线和 SCL 时钟线在空闲状态下均保持高电平,连到总线上的任一器件输出的低电平都将使总线的信号变低,即各 I2C 器件的 SDA 与 SCL 都是 “与” 关系。
  • ACK(应答信号):当传输完 8 位数据以后,在第 9 个 SCL 时钟周期。主机释放 SDA 控制权交给从机,由于上拉电阻的作用,此时该电平为高,但是如果从机正确接受了数据,就会将 SDA 拉低
  • NACK(非应答信号):如果第 9 个 SCL 时钟周期,SDA 保持高电平,则代表非应该信号

ESP32 I2C 接口

参考资料说明:

1 总体描述

ESP32 有 2 个 I2C 总线接口,根据用户的配置,总线接口可以用作 I2C 主机从机模式。I2C 接口支持:

  • 标准模式 (100 Kbit/s)
  • 高速模式 (400 Kbit/s)
  • 速度最高可达 5 MHz,但受制于 SDA 上拉强度
  • 支持多主机多从机通信
  • 支持 7-bit 以及 10-bit 寻址模式
  • 双寻址模式
  • 支持关闭 SCL 时钟实现连续数据传输
  • 支持可编程数字噪声滤波功能
  • 用户可以配置指令寄存器来控制 I2C 接口,从而实现更多灵活的应用。

2 管脚说明

ESP32 的 I2C 管脚可使用任意 GPIO 管脚映射,请参见《ESP32 技术规格书》中 “4.2 外设管脚分配” 说明。
在这里插入图片描述


3 硬件设计

  • I2C 仅使用两个双向开漏线,串行数据线(SDA)和串行时钟线(SCL),以及上拉电阻。使用的典型电压是 +5 V+3.3 V(虽然其他电压系统也是允许的)
  • 通常来说,所选择的频率越高,需要的上拉电阻越小 (但是不要小于 1K 欧姆)。这是因为高电阻会减小电流,这会延长上升时间从而使频率变慢。通常我们推荐的上拉阻值范围为 2K 欧姆到 5K 欧姆,但是用户可能也需要根据他们的实际情况做出一些调整。
  • 将 SCL 的 pad 配置成开漏方式时,SCL 从低电平转向高电平的时间会变长,这个转变时间由 SCL 线上的上拉电阻以及电容共同决定。开漏模式下,SCL 的输出频率会偏低。
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • Deep-sleep 模式下,仅 ULP 协处理器处于工作状态时,可以操作如下 RTC_GPIO 作为低功耗 I2C 管脚, 可参见《ESP32 技术参考手册》中关于 “4.11 RTC_MUX 管脚清单” 说明。
    在这里插入图片描述

4 ESP32 I2C 常见的应用

  • 为了保存用户的设置而访问 NVRAM 芯片
  • 访问低速的数字模拟转换器(DAC)和模拟数字转换器(ADC)
  • 改变监控器的对比度、色调及色彩平衡设置(VESA显示数据频道)
  • 控制小型液晶或 OLED 屏幕
  • 调节音量大小
  • 获取硬件监控及诊断资料,例如中央处理器的温度及风扇转速
  • 读取实时时钟(Real-time clock)
  • 在系统设备中用来开启或关闭电源供应

4.1 I2C 配置说明

建议阅读 ESP32 的 I2C 驱动程序 编程指南

  • I2C 时钟速度由 I2C Master(主机)设置
  • I2C 的 SDA 和 SCL 管脚必须上拉(软件上拉或硬件上拉)

4.2 配置示例:

  • I2C 主机配置示例
int i2c_master_port = 0;
i2c_config_t conf = {
    .mode = I2C_MODE_MASTER,
    .sda_io_num = I2C_MASTER_SDA_IO,         // select GPIO specific to your project
    .sda_pullup_en = GPIO_PULLUP_ENABLE,
    .scl_io_num = I2C_MASTER_SCL_IO,         // select GPIO specific to your project
    .scl_pullup_en = GPIO_PULLUP_ENABLE,
    .master.clk_speed = I2C_MASTER_FREQ_HZ,  // select frequency specific to your project
    // .clk_flags = 0,          /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
};

当 I2C 控制器工作于 Master 模式,SCL 为输出信号。

  • I2C 从机配置示例
int i2c_slave_port = I2C_SLAVE_NUM;
i2c_config_t conf_slave = {
    .sda_io_num = I2C_SLAVE_SDA_IO,          // select GPIO specific to your project
    .sda_pullup_en = GPIO_PULLUP_ENABLE,
    .scl_io_num = I2C_SLAVE_SCL_IO,          // select GPIO specific to your project
    .scl_pullup_en = GPIO_PULLUP_ENABLE,
    .mode = I2C_MODE_SLAVE,
    .slave.addr_10bit_en = 0,
    .slave.slave_addr = ESP_SLAVE_ADDR,      // address of your project
};

当 I2C 控制器工作于 Slave 模式,SCL 为输入信号。

ESP32 设备作为 I2C 从机时,支持 7 bit 和 10 bit 双地址寻址,且地址码可自定义为任何 7 bit 或 10 bit 的值。 以 I2C 例程为例,默认使用的是 7 bit 地址码。若使用 10 bit (读)地址码,可以设置类似 0x329 (0011 0010 1001)的值
在这里插入图片描述

在此阶段,i2c_param_config() 还将其他 I2C 配置参数设置为 I2C 总线协议规范中定义的默认值。有关默认值及修改默认值的详细信息,请参考 用户自定义配置


4.3 参考例程:

注意: I2C 外接传感器的应用说明可参见:传感器集 指南


5 ESP32 I2C 的时钟源特性

可参见 ESP32 I2C 源时钟配置 说明

  • I2C 默认源时钟为 APB 时钟80MHz
    在这里插入图片描述
    说明:
    • 当 APB 时钟改变时,时钟的波特率不会改变。
    • 在轻度睡眠模式,不支持使用 APB 时钟。

注意:在主机模式下,SCL 的时钟频率不应大于上表中提到的 SCL 的最大频率。

typedef enum {
    I2C_SCLK_DEFAULT = 0,    /*!< I2C source clock not selected*/
#if SOC_I2C_SUPPORT_APB
    I2C_SCLK_APB,            /*!< I2C source clock from APB, 80M*/
#endif
#if SOC_I2C_SUPPORT_XTAL
    I2C_SCLK_XTAL,           /*!< I2C source clock from XTAL, 40M */
#endif
#if SOC_I2C_SUPPORT_RTC
    I2C_SCLK_RTC,            /*!< I2C source clock from 8M RTC, 8M */
#endif
#if SOC_I2C_SUPPORT_REF_TICK
    I2C_SCLK_REF_TICK,       /*!< I2C source clock from REF_TICK, 1M */
#endif
    I2C_SCLK_MAX,
} i2c_sclk_t;

6 ESP32 I2C 中断处理

  • 安装驱动程序时,默认情况下会安装中断处理程序。但是,您可以通过调用函数 i2c_isr_register() 来注册自己的而不是默认的中断处理程序。
  • 在运行自己的中断处理程序时,可以参考 ESP32 技术参考手册 > I2C 控制器 (I2C) > 中断 [PDF],以获取有关 I2C 控制器触发的中断描述。
  • 调用函数 i2c_isr_free() 删除中断处理程序。

6.1 I2C 中断触发条件

参见《ESP32 技术参考手册》中 “ 11.3.7 中断 ” 说明

  • I2C_TX_SEND_EMPTY_INT: 每当 I2C Master 或 Slave 发送 nonfifo_tx_thres 个数据,即触发该中断。
  • I2C_RX_REC_FULL_INT: 每当 I2C Master 或 Slave 接收 nonfifo_rx_thres 个数据,即触发该中断。
  • I2C_ACK_ERR_INT: 当 I2C 配置为 Master 时,接收到的 ACK 与命令中期望的 ACK 值不一致时,即触发该中断;当 I2C 配置为 Slave 时,接收到的 ACK 值为 1 时即触发该中断。
  • I2C_TRANS_START_INT: 当 I2C Master 或 Slave 发送一个 START 位时,即触发该中断。
  • I2C_TIME_OUT_INT: 在传输过程中,当 I2C SCL 保持为高或为低电平的时间超过 I2C_TIME_OUT 个时钟后,即触发该中断。
  • I2C_TRANS_COMPLETE_INT: 当 I2C Master 或 Slave 检测到 STOP 位时,即触发该中断。
  • I2C_MASTER_TRAN_COMP_INT: 当 I2C Master 发送或接收一个字节,即触发该中断。
  • I2C_ARBITRATION_LOST_INT: 当 I2C Master 的 SCL 为高电平,SDA 输出值与输入值不相等时,即触发该中断。
  • I2C_END_DETECT_INT: 当 I2C Master 处理 END 命令时,即触发该中断。

7 ESP32 I2C 错误处理

  • 大多数 I2C 驱动程序的函数在成功完成时会返回 ESP_OK ,或在失败时会返回特定的错误代码。实时检查返回的值并进行错误处理是一种好习惯。驱动程序也会打印日志消息,其中包含错误说明,例如检查输入配置的正确性。有关详细信息,请参考文件 driver/i2c.c 并用后缀 _ERR_STR 查找定义。
#define I2C_DRIVER_ERR_STR             "i2c driver install error"
#define I2C_DRIVER_MALLOC_ERR_STR      "i2c driver malloc error"
#define I2C_NUM_ERROR_STR              "i2c number error"
#define I2C_TIMING_VAL_ERR_STR        "i2c timing value error"
#define I2C_ADDR_ERROR_STR             "i2c null address error"
#define I2C_DRIVER_NOT_INSTALL_ERR_STR "i2c driver not installed"
#define I2C_SLAVE_BUFFER_LEN_ERR_STR   "i2c buffer size too small for slave mode"
#define I2C_EVT_QUEUE_ERR_STR          "i2c evt queue error"
#define I2C_SEM_ERR_STR                "i2c semaphore error"
#define I2C_BUF_ERR_STR                "i2c ringbuffer error"
#define I2C_MASTER_MODE_ERR_STR        "Only allowed in master mode"
#define I2C_MODE_SLAVE_ERR_STR         "Only allowed in slave mode"
#define I2C_CMD_MALLOC_ERR_STR         "i2c command link malloc error"
#define I2C_CMD_USER_ALLOC_ERR_STR     "i2c command link allocation error: the buffer provided is too small."
#define I2C_TRANS_MODE_ERR_STR         "i2c trans mode error"
#define I2C_MODE_ERR_STR               "i2c mode error"
#define I2C_SDA_IO_ERR_STR             "sda gpio number error"
#define I2C_SCL_IO_ERR_STR             "scl gpio number error"
#define I2C_SCL_SDA_EQUAL_ERR_STR      "scl and sda gpio numbers are the same"
#define I2C_CMD_LINK_INIT_ERR_STR      "i2c command link error"
#define I2C_GPIO_PULLUP_ERR_STR        "this i2c pin does not support internal pull-up"
#define I2C_ACK_TYPE_ERR_STR           "i2c ack type error"
#define I2C_DATA_LEN_ERR_STR           "i2c data read length error"
#define I2C_PSRAM_BUFFER_WARN_STR      "Using buffer allocated from psram"
#define I2C_LOCK_ERR_STR               "Power lock creation error"
#define I2C_CLK_FLAG_ERR_STR           "i2c clock choice is invalid, please check flag and frequency"
  • 使用专用中断来捕获通信故障。例如,如果从机将数据发送回主机耗费太长时间,会触发 I2C_TIME_OUT_INT 中断。详细信息请参考 中断处理

  • 如果出现通信失败,可以分别为发送和接收缓存区调用 i2c_reset_tx_fifo()i2c_reset_rx_fifo() 来重置内部硬件缓存区。


需要注意 ESP32 I2C 总线上的几种特殊情况:

  • I2C Master 在发送 STOP 位时,若因为 SDA 被其他设备拉低导致发送不了 STOP 位,则需要复位 I2C Master。
  • I2C Master 在发送 START 位时,若因为 SDA 或者 SCL 被其他设备拉低导致发送不了 START 位,则需要复位 I2C Master。建议软件使用超时时间来执行重置。
  • 数据传输过程中,SDA 被 I2C Slave 拉为低电平,此时 I2C Master 只需给 Slave 至多九个 SCL 时钟即可释放 SDA 线。

8 ESP32 I2C FAQ

  • 使用的 ESP32-WROOM32-32E 模块,想用 GPIO0、GPIO4 作为 I2C 信号接口,但是 GPIO0 是 PROG 的烧写口,GPIO0 这样并联状态会出现冲突吗?

GPIO0 做 I2C 时需要加上拉,固件下载的时候只要保证 GPIO0 在上电时能拉低,然后就可以释放了,不需要一直拉低,而且只有下载的时候需要拉低。


  • 使用 ESP32 在程序初始化时报一个错误,请问如何解决?
I2C_BUS: C:/Users/hpc/Desktop/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:100 (i2c_bus_write_bytes):I2C Bus WriteReg Error

报错 I2C Bus WriteReg Error,是 I2C 写寄存器出错了。WriteReg 与 Write 类似,但 WriteReg 是写入寄存器的。


  • ESP32 的 I2C 的传输速率是多大?

ESP32 I2C 的传输速率理论支持 5MHZ ,当前最大支持 1MHz 。


  • 中断方式或调高 I2C 时钟的话,是否可以优化按键处理延时?

ESP32 支持 1 MHZ 的 I2C ,I2C 时钟 越大,传输速率越快,这样延时就越小了。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 19:03:54  更:2022-07-20 19:06:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 13:25:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码