当前位置: 首页 > news >正文

ESP32学习-I2C(IIC)通信详解与实践

I2C(又称 IIC)是嵌入式开发中最常见的通信协议之一,广泛应用于传感器、显示屏、存储芯片等设备。ESP32 提供了灵活的 I2C 硬件接口,今天我们就来深入学习 I2C 的基本概念、使用流程及 ESP32 实践。


一、基本概念

✅ 什么是 I2C?

I2C(Inter-Integrated Circuit) 是一种由 Philips(飞利浦)发明的串行通信协议,用于主控与多个从设备之间的数据通信。它具有以下特点:

特性说明
通信方式串行通信(同步)
连接方式只需两根信号线:SCL(时钟)和 SDA(数据)
主从结构一个主控(如 ESP32)控制多个从设备
唯一地址每个从设备有唯一的 7 位或 10 位地址
半双工通信数据是双向的,但一次只能一个方向传输


❓ I2C 与 SPI 的区别

对比项I2CSPI
信号线2 根(SDA, SCL)4 根(MOSI, MISO, SCLK, CS)
速率一般 100kHz~400kHz更高,几 MHz 甚至几十 MHz
结构多主多从通常为一主多从(点对点)
成本引脚少,布线简单引脚多,布线复杂
应用场景简单控制/低速设备,如传感器高速传输,如屏幕、Flash


二、使用流程(ESP32 I2C 主机模式)

ESP32 的 I2C 驱动使用 主设备模式(Master) 最多可挂载两个 I2C 接口(I2C_NUM_0 和 I2C_NUM_1),流程如下:

  1. 配置 I2C 接口参数(GPIO、速率等)

  2. 安装 I2C 驱动

  3. 使用 i2c_master_write / read 等函数读写设备

  4. 完成通信后可卸载驱动(可选)


三、I2C 端口配置

ESP32 的 I2C 引脚是可选的(不是固定的),你可以选择任意空闲 GPIO 作为 SDA 和 SCL,只要设备支持。

例如我们选:

  • SDA:GPIO21

  • SCL:GPIO22

#include "driver/i2c.h"#define I2C_MASTER_NUM              I2C_NUM_0   // 使用 I2C0
#define I2C_MASTER_SDA_IO           21
#define I2C_MASTER_SCL_IO           22
#define I2C_MASTER_FREQ_HZ          400000      // 400kHz
#define I2C_MASTER_TX_BUF_DISABLE   0
#define I2C_MASTER_RX_BUF_DISABLE   0void i2c_master_init()
{i2c_config_t conf = {.mode = I2C_MODE_MASTER,.sda_io_num = I2C_MASTER_SDA_IO,.scl_io_num = I2C_MASTER_SCL_IO,.sda_pullup_en = GPIO_PULLUP_ENABLE,  // 上拉电阻开启.scl_pullup_en = GPIO_PULLUP_ENABLE,.master.clk_speed = I2C_MASTER_FREQ_HZ};i2c_param_config(I2C_MASTER_NUM, &conf);  // 选定iic控制器为I2C0,再配置对应端口信息i2c_driver_install(I2C_MASTER_NUM, conf.mode,I2C_MASTER_RX_BUF_DISABLE,I2C_MASTER_TX_BUF_DISABLE, 0);
}

🔍 SDA/SCL 需要接 上拉电阻(如 4.7kΩ),部分板子已内置。

🔧 I2C_MASTER_RX_BUF_DISABLETX_BUF_DISABLE 是什么?

这两个宏值为 0,表示:

  • 你不需要缓冲区(你是主机,数据是你主动读写的,不需要控制器中先存一堆数据)

  • 如果你要使用从机模式(I2C_MODE_SLAVE),那就必须配置非零缓冲区长度


💡 一句话总结

i2c_driver_install() 的作用是真正启用 I2C 控制器,它必须在 i2c_param_config() 之后调用,且主机模式下接收/发送缓冲区长度必须设为 0。


四、源代码示例(读写一个设备寄存器)

假设我们有一个从设备地址为 0x68,我们要向其写入一个寄存器,然后再读回来:

#define DEVICE_ADDR  0x68
#define REGISTER_ADDR 0x01// 写一个字节到指定寄存器
esp_err_t i2c_write_byte(uint8_t reg_addr, uint8_t data)
{i2c_cmd_handle_t cmd = i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, (DEVICE_ADDR << 1) | I2C_MASTER_WRITE, true);i2c_master_write_byte(cmd, reg_addr, true);i2c_master_write_byte(cmd, data, true);i2c_master_stop(cmd);esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd,1000 / portTICK_PERIOD_MS);i2c_cmd_link_delete(cmd);return ret;
}// 从指定寄存器读取一个字节
esp_err_t i2c_read_byte(uint8_t reg_addr, uint8_t *data)
{i2c_cmd_handle_t cmd = i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, (DEVICE_ADDR << 1) | I2C_MASTER_WRITE, true);i2c_master_write_byte(cmd, reg_addr, true);i2c_master_start(cmd); // 重启i2c_master_write_byte(cmd, (DEVICE_ADDR << 1) | I2C_MASTER_READ, true);i2c_master_read_byte(cmd, data, I2C_MASTER_NACK);i2c_master_stop(cmd);esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd,1000 / portTICK_PERIOD_MS);i2c_cmd_link_delete(cmd);return ret;
}

五、问题

1.为什么既要指定iic控制器,又可以随意选择端口,STM32中的硬件IIC不是直接与端口绑定了吗?

该处是硬件IIC实现,ESP32几乎所有引脚都是通用的,因此需要手动指定。而stm32固定就映射好了,因此可以不用指定。


六、总结

I2C 是 ESP32 最常用的外设通信协议之一,掌握它是开发各种传感器模块的基础。

http://www.lryc.cn/news/608703.html

相关文章:

  • C++:STL中的栈和队列的适配器deque
  • Spring Boot AOP 优雅实现异常重试机制
  • AD方案(OpenLDAP或微软AD)适配信创存在的不足以及可能优化方案
  • Nvidia Orin DK 刷机CUDA TensorRT+硬盘扩容+ROS+Realsense+OpenCV+Ollama+Yolo11 一站式解决方案
  • CUDA杂记--nvcc使用介绍
  • Elastic 9.1/8.19:默认启用 BBQ,ES|QL 支持跨集群搜索(CCS)正式版,JOINS 正式版,集成 Azure AI Foundry
  • Jupyter Notebook 中高效处理和实时展示来自 OpenCV 和 Pillow 的图像数据探究
  • Jetpack Compose for XR:构建下一代空间UI的完整指南
  • SpringBoot+Vue高校实验室预约管理系统 附带详细运行指导视频
  • 力扣经典算法篇-41-旋转图像(辅助数组法,原地旋转法)
  • RabbitMQ面试精讲 Day 9:优先级队列与惰性队列
  • 昇思学习营-开发版-模型推理和性能优化
  • Android 之 MVP架构
  • Redis+Lua的分布式限流器
  • Python 实例属性与方法命名冲突:一次隐藏的Bug引发的思考
  • Corrosion2靶机
  • NumPy库学习(三):numpy在人工智能数据处理的具体应用及方法
  • PHP入门及数据类型
  • Android 之 WebView与HTML交互
  • 【Django】-7- 实现注册功能
  • 迈向透明人工智能: 可解释性大语言模型研究综述
  • ubuntu24.04安装selenium、edge、msedgedriver
  • 大语言模型的解码策略:贪婪解码与波束搜索
  • 记一次v-if和key错误使用,导致vue2的内存爆炸修复!
  • 音视频学习(五十):音频无损压缩
  • Arrays.asList() add方法报错java.lang.UnsupportedOperationException
  • Apache Shenyu 本地启动及快速入门
  • 【abc417】E - A Path in A Dictionary
  • HTTPS的概念和工作过程
  • Kazam产生.movie.mux后恢复视频为.mp4