【ESP32 IDF】I2C的使用

文章目录

  • 前言
  • 一、I2C驱动使用的步骤
  • 二、I2C的使用
    • 2.1 配置驱动程序
    • 2.2 安装驱动程序
    • 2.3 主机写入数据
      • 写入数据的过程
      • 接收数据的过程
  • 总结


前言

ESP32是一款强大的微控制器,广泛应用于物联网(IoT)和嵌入式系统开发。它具备丰富的硬件接口,其中之一是I2C(Inter-Integrated Circuit),这是一种用于短距离通信的串行通信协议。I2C接口常用于连接各种外部传感器、存储器和其他外设,使得ESP32能够轻松实现与外部设备的数据交换。

本文将介绍如何在ESP32 IDF中使用I2C接口,提供一个简单而实用的示例代码。通过本文,您将了解如何初始化I2C主机、进行数据写入以及连接和配置I2C从设备的关键步骤。


一、I2C驱动使用的步骤

以下部分将指导您完成 I2C 驱动程序配置和工作的基本步骤:

  • 配置驱动程序 - 设置初始化参数(如主机模式或从机模式,SDA 和 SCL 使用的 GPIO 管脚,时钟速度等)

  • 安装驱动程序- 激活一个 I2C 控制器的驱动,该控制器可为主机也可为从机

  • 根据是为主机还是从机配置驱动程序,选择合适的项目

    • 主机模式下通信 - 发起通信(主机模式)

    • 从机模式下通信 - 响应主机消息(从机模式)

  • 中断处理 - 配置和 I2C 中断服务

  • 用户自定义配置 - 调整默认的 I2C 通信参数(如时序、位序等)

  • 错误处理 - 如何识别和处理驱动程序配置和通信错误

  • 删除驱动程序- 在通信结束时释放 I2C 驱动程序所使用的资源

二、I2C的使用

2.1 配置驱动程序

如果你需要使用I2C,你需要这个结构体:i2c_config_t,他的结构体定义如下:

typedef struct{i2c_mode_t mode;     /*!< I2C mode */int sda_io_num;      /*!< GPIO number for I2C sda signal */int scl_io_num;      /*!< GPIO number for I2C scl signal */bool sda_pullup_en;  /*!< Internal GPIO pull mode for I2C sda signal*/bool scl_pullup_en;  /*!< Internal GPIO pull mode for I2C scl signal*/union {struct {uint32_t clk_speed;     /*!< I2C clock frequency for master mode, (no higher than 1MHz for now) */} master;                   /*!< I2C master config */struct {uint8_t addr_10bit_en;  /*!< I2C 10bit address mode enable for slave mode */uint16_t slave_addr;    /*!< I2C address for slave mode */} slave;                    /*!< I2C slave config */};uint32_t clk_flags;             /*!< Bitwise of ``I2C_SCLK_SRC_FLAG_**FOR_DFS**`` for clk source choice*/
} i2c_config_t;

mode:
用途:设置I2C接口的工作模式,可以是主机模式(I2C_MODE_MASTER)或从机模式(I2C_MODE_SLAVE)。

主机模式(Master Mode)
在主机模式下,ESP32充当I2C总线的主设备,负责启动和控制通信。主机模式用于与一个或多个I2C从设备进行通信。主机发送起始信号、地址、数据和停止信号,控制整个通信过程。

从机模式(Slave Mode)
在从机模式下,ESP32作为I2C总线上的从设备,等待主机发起通信。ESP32从设备接收来自主机的地址和数据,并根据主机的命令执行相应的操作。从机模式使ESP32能够与其他I2C主机设备通信,实现更复杂的系统互联。

我们使用主机模式即可

sda_io_num:
用途:指定I2C总线的数据线(SDA)连接的GPIO引脚的编号。

scl_io_num:
用途:指定I2C总线的时钟线(SCL)连接的GPIO引脚的编号。

sda_pullup_en:
用途:控制SDA引脚的内部上拉电阻是否启用。

scl_pullup_en:
用途:控制SCL引脚的内部上拉电阻是否启用。

master(union内部的结构体):
用途:当mode为主机模式时,用于配置主机模式下的具体参数。
clk_speed:设置I2C主机模式下的时钟频率,即通信速率。

slave(union内部的结构体):
用途:当mode为从机模式时,用于配置从机模式下的具体参数。
addr_10bit_en:启用或禁用I2C从机模式下的10位地址模式。
slave_addr:设置I2C从机模式下的从机地址。

clk_flags:
用途:通过使用位掩码(bitwise flags)来指定时钟源的选择,具体取值可以是I2C_SCLK_SRC_FLAG_CORE或I2C_SCLK_SRC_FLAG_DFS。

接下来,我们需要为I2C结构体进行初始化,使用这个函数:

esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf)

i2c_num:
意义:指定要配置的I2C总线编号,即I2C控制器的索引。
取值:I2C_NUM_0 或 I2C_NUM_1,表示要配置的是I2C0或I2C1。
在这里插入图片描述
i2c_conf:
意义:指向一个 i2c_config_t 类型的结构体,用于配置I2C总线的参数。
取值:通常情况下,可以通过填充 i2c_config_t 结构体的各个成员来指定具体的配置参数。前面已经介绍过 i2c_config_t 结构体的成员及其作用。

2.2 安装驱动程序

我们可以使用下面这个函数来安装驱动程序:

esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_buf_len, size_t slv_tx_buf_len,int intr_alloc_flags)

i2c_num:
含义:指定要安装和初始化的I2C总线编号,即I2C控制器的索引。
取值:I2C_NUM_0 或 I2C_NUM_1,表示要初始化的是I2C0或I2C1。

mode:
含义:指定I2C总线的工作模式。
取值:可以是 I2C_MODE_MASTER(主机模式)或 I2C_MODE_SLAVE(从机模式)。

slv_rx_buf_len:
含义:指定从机模式下接收缓冲区的大小。
取值:正整数,表示从机模式下接收缓冲区的长度,单位是字节。如果不使用从机模式,则可以将其设置为0。

slv_tx_buf_len:

含义:指定从机模式下发送缓冲区的大小。
取值:正整数,表示从机模式下发送缓冲区的长度,单位是字节。如果不使用从机模式,则可以将其设置为0。

intr_alloc_flags:
含义:指定中断分配的标志位。
取值:可以使用ESP_INTR_FLAG_*系列宏来设置,用于指定中断服务程序的优先级、CPU核心等信息。通常可以选择 ESP_INTR_FLAG_IRAM 或 ESP_INTR_FLAG_SHARED。
如果不使用,写0即可

2.3 主机写入数据

写入数据的过程

主机发送数据有如下的过程:
在这里插入图片描述

  1. 使用 i2c_cmd_link_create() 创建一个命令链接。

    然后,将一系列待发送给从机的数据填充命令链接:

    启动位 - i2c_master_start()

    从机地址 - i2c_master_write_byte()。提供单字节地址作为调用此函数的实参。

    数据 - 一个或多个字节的数据作为 i2c_master_write() 的实参。

    停止位 - i2c_master_stop()

    函数 i2c_master_write_byte()i2c_master_write() 都有额外的实参,规定主机是否应确认其有无接受到 ACK 位。

  2. 通过调用 i2c_master_cmd_begin() 来触发 I2C 控制器执行命令链接。一旦开始执行,就不能再修改命令链接。

  3. 命令发送后,通过调用 i2c_cmd_link_delete() 释放命令链接使用的资源。

我们就可以写出下面这个函数

// 发送数据到I2C从设备
static esp_err_t i2c_master_send(uint8_t *data, size_t size) {i2c_cmd_handle_t cmd = i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, (I2C_SLAVE_ADDR << 1) | I2C_MASTER_WRITE, true);i2c_master_write(cmd, data, size, true);i2c_master_stop(cmd);esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(1000));i2c_cmd_link_delete(cmd);return ret;
}

接收数据的过程

在这里插入图片描述
在读取数据时,在上图的步骤 4 中,不是用 i2c_master_write…,而是用 i2c_master_read_byte() 和/或 i2c_master_read() 填充命令链接。同样,在步骤 5 中配置最后一次的读取,以便主机不提供 ACK 位。

我们可以写出下面这个代码:

// 从I2C从设备接收数据
static esp_err_t i2c_master_receive(uint8_t *data, size_t size) {i2c_cmd_handle_t cmd = i2c_cmd_link_create();i2c_master_start(cmd);i2c_master_write_byte(cmd, (I2C_SLAVE_ADDR << 1) | I2C_MASTER_READ, true);if (size > 1) {i2c_master_read(cmd, data, size - 1, I2C_MASTER_ACK);}i2c_master_read_byte(cmd, data + size - 1, I2C_MASTER_NACK);i2c_master_stop(cmd);esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(1000));i2c_cmd_link_delete(cmd);return ret;
}

我们实现完这几个函数就可以去实现我们的I2C操作了。如果大家需要详细的代码可以进入我的资源找到ESP32-IDF I2C代码


总结

通过本文,我们深入了解了ESP32 IDF中I2C接口的基本使用方法。首先,我们学习了如何初始化I2C主机,包括配置GPIO引脚和设置时钟频率等关键步骤。接着,我们展示了一个简单的示例代码,演示了如何使用ESP32与I2C从设备通信,向其写入数据。

这个示例代码不仅展示了ESP32 IDF中I2C API的基本用法,还为开发者提供了一个起点,可根据实际需求进行定制和扩展。通过理解I2C接口的基本原理和ESP32 IDF中的相关API,开发者可以更轻松地与各种I2C设备进行集成,从而实现更复杂的嵌入式系统和物联网应用。

总体而言,ESP32 IDF为开发者提供了丰富而强大的工具,使得利用ESP32的I2C接口进行通信变得简单而高效。这为物联网和嵌入式系统领域的开发者们带来了更多可能性,同时也推动着这一领域的不断创新和发展。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2869794.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

23. BI - 基于酒店建立内容推荐系统

本文为 「茶桁的 AI 秘籍 - BI 篇 第 23 篇」 文章目录 基于内容的推荐酒店数据说明TF-IDF基于酒店做推荐数据探索建模并计算执行推荐 总结 Hi&#xff0c;你好。我是茶桁。 上一节课咱们终于是将矩阵分解的完整内容全部都给大家讲完了。矩阵分解是推荐系统里面比较重要的一个环…

前端Vue开发中的百度地图定位组件:实现定位、反向地址查询与详细地址展示

一、引言 在前端开发中&#xff0c;地图定位是一个重要的功能&#xff0c;它能够为用户提供直观、便捷的服务。在许多应用场景中&#xff0c;我们不仅需要显示当前的地图定位&#xff0c;还需要将定位坐标反向转成地址&#xff0c;并展示详细地址。本文将介绍如何使用Vue和百度…

Django 解决新建表删除后无法重新创建等问题

Django 解决新建表删除后无法重新创建等问题 问题发生描述处理办法首先删除了app对应目录migrations下除 __init__.py以外的所有文件:然后&#xff0c;删除migrations中关于你的app的同步数据数据库记录最后&#xff0c;重新执行迁移插入 问题发生描述 Django创建的表&#xf…

接口幂等性问题和常见解决方案

接口幂等性问题和常见解决方案 1.什么是接口幂等性问题1.1 会产生接口幂等性的问题1.2 解决思路 2.接口幂等性的解决方案2.1 唯一索引解决方案2.2 乐观锁解决方案2.3 分布式锁解决方案2.4 Token解决方案(最优方案) 1.什么是接口幂等性问题 幂等性: 用户同一操作发起的一次或多…

(附数据集)基于lora参数微调Qwen1.8chat模型的实战教程

基于lora微调Qwen1.8chat的实战教程 日期&#xff1a;2024-3-16作者&#xff1a;小知运行环境&#xff1a;jupyterLab描述&#xff1a;基于lora参数微调Qwen1.8chat模型。 样例数据集 - qwen_chat.json&#xff08;小份数据&#xff09; - chat.json&#xff08;中份数据&…

【Hadoop大数据技术】——MapReduce经典案例实战(倒排索引、数据去重、TopN)

&#x1f4d6; 前言&#xff1a;MapReduce是一种分布式并行编程模型&#xff0c;是Hadoop核心子项目之一。实验前需确保搭建好Hadoop 3.3.5环境、安装好Eclipse IDE &#x1f50e; 【Hadoop大数据技术】——Hadoop概述与搭建环境&#xff08;学习笔记&#xff09; 目录 &#…

Maven项目通过CentralPortal上传到中央仓库【最新版】

准备 注册一个邮箱gitee或者github账号,以gitee为例去https://central.sonatype.com/这里注册一个账号添加namespace 访问 https://central.sonatype.com/publishing/namespaces 点击 “Verify Namespace” 在gitee上创建项目 gpg 去这里 https://gnupg.org/download/i…

Android 系统的启动过程

Android 系统的启动流程&#xff1a; RomBoot&#xff08;只读存储器引导程序&#xff09;&#xff1a;这是设备上电时运行的初始软件。RomBoot执行基本的硬件初始化&#xff0c;确保硬件处于可以运行后续启动阶段的状态。这一阶段非常重要&#xff0c;因为它为整个启动过程奠定…

提升物流效率,快递平台实战总结与分享

随着电商行业的蓬勃发展&#xff0c;物流配送服务变得愈发重要。快递平台作为连接电商企业和消费者的桥梁&#xff0c;扮演着至关重要的角色。本篇博客将分享快递平台实战经验&#xff0c;总结关键要点&#xff0c;帮助物流从业者提升物流效率、优化服务质量。 ### 快递平台实…

日期与时间(Java)

文章目录 日期与时间&#xff08;Java&#xff09;一、JDK8之前的1.1 Date1.2 SimpleDateFormat1.3 Calendar 二、 JDK8之后的2.1 LocalDate、LocalTime和LocalDateTime2.2 ZoneId和ZonedDateTime2.3 Instant2.4 DateTimeFormatter2.4 Period和 Duration &#x1f389;写在最后…

第二十四天-数据可视化Matplotlib

目录 1.介绍 2.使用 1. 安装&#xff1a; 2.创建简单图表 3.图表类型 1.一共分为7类 2.变化 1.折线图 3.分布 ​编辑 1.直方图 2.箱型图 4.关联 1. 散点图&#xff1a; 2.热力图&#xff1a; 5.组成 1.饼图 2.条形图 6.分组 1.簇型散点图 2.分组条形图 3.分…

【人工智能】英文学习材料(每日一句)

#学习笔记# 目录 1.Natural Language Processing&#xff0c;NLP&#xff08;自然语言处理&#xff09; 2.Machine Learing&#xff0c;ML&#xff08;机器学习&#xff09; 3.Neural Networks&#xff08;神经网络&#xff09; 4.Deep Learing&#xff08;深度学习&#…

基于CNN多阶段图像超分+去噪(超级简单版)

这是之前的一项工作&#xff0c;非常简单&#xff0c;简单的复现了两个算法&#xff0c;然后把它们串起来了。 可执行的程序链接&#xff1a;CSDN; Github 我们分成两部分进行讲解&#xff1a; 1. 图像去噪 1.1 基本思路 图像的去噪工作基于很普通的CNN去噪&#xff0c;效…

前端学习之css选择器--基本选择器、关系选择器、属性选择器、复合选择器、伪类选择器

目录 基本选择器 结果 关系选择器 结果 父子关系 祖先后代关系 相邻兄弟关系 兄弟关系 ​编辑 属性选择器 结果 复合选择器 结果 伪类选择器 结果 伪类选择器-操作标签 结果 未访问 访问后 悬停 基本选择器 <!DOCTYPE html> <html lang"en"…

flowable快速开始

目录 创建用户并分配权限画流程图发布应用程序运行流程文档资料 创建用户并分配权限 创建两个用户 zhangsan和lisi 用于工作流的审批&#xff0c;流程如图 创建用户 分配权限&#xff0c;用于审批工作流 画流程图 点击“创建流程” 开始画图 给人事审批分配 zhangsan…

C++之类和对象(3)

目录 1. 再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit 2. static成员 2.1 概念 3. 友元 3.1 友元函数 3.2 友元类 4. 内部类 5. 匿名对象 6. 拷贝对象时编译器做出的优化 1. 再谈构造函数 1.1 构造函数体赋值 class Date { public:Date(int year2024…

Linux第78步_使用原子整型操作来实现“互斥访问”共享资源

使用原子操作来实现“互斥访问”LED灯设备&#xff0c;目的是每次只允许一个应用程序使用LED灯。 1、创建MyAtomicLED目录 输入“cd /home/zgq/linux/Linux_Drivers/回车” 切换到“/home/zgq/linux/Linux_Drivers/”目录 输入“mkdir MyAtomicLED回车”&#xff0c;创建MyA…

Android分区存储到底是怎么回事

文章目录 一、Android存储结构二、什么是分区存储&#xff1f;三、私有目录和公有目录三、存储权限和分区存储有什么关系&#xff1f;四、我们应该该怎么做适配&#xff1f;4.1、利用File进行操作4.2、使用MediaStore操作数据库 一、Android存储结构 Android存储分为内部存储和…

C语言 1000内完数、素数判断

一、一个数如果恰好等于它的因子之和&#xff0c;这个数就称为“完数”。例如&#xff0c;6旳因子为1&#xff0c;2&#xff0c;3&#xff0c;而6123&#xff0c;因此6是“完数”。编程序找出1000以内的所有“完数”&#xff0c;并按照下面格式输出其因子&#xff1a;6 its fac…

java组合模式揭秘:如何构建可扩展的树形结构

组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将对象组合成树形结构以表示整体/部分层次结构。组合模式使得客户端可以统一对待单个对象和组合对象&#xff0c;从而使得客户端可以处理更复杂的结构。 组合模式的主要组成部分包括&…