19-ESP32-S3外设IIC

ESP32-S3的IIC

引言

ESP32-S3是一款集成了Wi-Fi和蓝牙功能的低成本、多功能微控制器。在这篇博客中,我们将详细介绍ESP32-S3的IIC(Inter-Integrated Circuit)接口,也被称为I2C。

IIC简介

IIC是一种串行、同步、多设备、半双工通信协议,允许同一总线上存在多个主设备和从设备。IIC使用两个双向开漏线:串行数据线(SDA)和串行时钟线(SCL),由电阻上拉。ESP32-S3有2个IIC控制器(也称为端口),负责处理I2C总线上的通信。每个控制器都可以设置为主机或从机。
IIC 总线有如下特点

  1. 总线由数据线 SDA 和时钟线 SCL 构成的串行总线,数据线用来传输数据,时钟线用来同步数据收发。
  2. 总线上每一个器件都有一个唯一的地址识别,所以我们只需要知道器件的地址,根据时
    序就可以实现微控制器与器件之间的通信。
  3. 数据线 SDA 和时钟线 SCL 都是双向线路,都通过一个电流源或上拉电阻连接到正的电
    压,所以当总线空闲的时候,这两条线路都是高电平。
  4. 总线上数据的传输速率在标准模式下可达 100kbit/s,在快速模式下可达 400kbit/s,在高
    速模式下可达 3.4Mbit/s。
  5. 总线支持设备连接。在使用 IIC 通信总线时,可以有多个具备 IIC 通信能力的设备挂载
    在上面,同时支持多个主机和多个从机,连接到总线的接口数量只由总线电容 400pF 的限制决
    定。IIC 总线挂载多个器件的示意图如下👇
    在这里插入图片描述

IIC 控制器介绍

ESP32-S3 有两个 IIC 总线接口,根据用户的配置,总线接口可以用作 IIC 主机或从机模式。
IIC 接口特点:

  • 可支持标准模式(100Kbit/s)、快速模式(400Kbit/s),速度最高可达 800Kbit/s,但受限于SCL 和 SDA 上拉强度。
  • 可支持 7 位寻址模式和 10 位寻址模式
  • 可支持双地址(从机地址和从机寄存器地址)寻址模式

驱动程序的功能
I2C 驱动程序管理在 I2C 总线上设备的通信,该驱动程序具备以下功能:

  • 在主机模式下读写字节
  • 支持从机模式
  • 读取并写入寄存器,然后由主机读取/写入

IIC 的基本的读写通讯过程

✨写操作通讯过程图
在这里插入图片描述
主机首先在IIC 总线上发送起始信号,那么这时总线上的从机都会等待接收由主机发出的数据。主机接着发送从机地址+0(写操作)组成的8bit 数据,所有从机接收到该 8bit 数据后,自行检验是否是自己的设备的地址,假如是自己的设备地址,那么从机就会发出应答信号。主机在总线上接收到有应答信号后,才能继续向从机发送数据。注意:IIC 总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。

✨读操作通讯过程图
在这里插入图片描述
主机向从机读取数据的操作,一开始的操作与写操作有点相似,观察两个图也可以发现,都是由主机发出起始信号,接着发送从机地址+1(读操作)组成的8bit 数据,从机接收到数据验证是否是自身的地址。 那么在验证是自己的设备地址后,从机就会发出应答信号,并向主机返回8bit 数据,发送完之后从机就会等待主机的应答信号。假如主机一直返回应答信号,那么从机可以一直发送数据,也就是图中的(n byte + 应答信号)情况,直到主机发出非应答信号,从机才会停止发送数据。

使用IIC驱动程序

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

使用i2c_config_t 结构体,用于配置 I2C 参数

  • 设置 I2C 工作模式 - 从 i2c_mode_t 中选择主机模式或从机模式
  • 设置 通信管脚
    1️⃣指定 SDA 和 SCL 信号使用的 GPIO 管脚
    2️⃣是否启用 ESP32-S3 的内部上拉电阻
  • (仅限主机模式)设置 I2C 时钟速度
  • (仅限从机模式)设置以下内容:
    1️⃣是否应启用 10 位寻址模式
    2️⃣定义 从机地址

然后,初始化给定 I2C 端口的配置,使用端口号和 i2c_config_t 作为函数调用参数来调用 i2c_param_config() 函数。

🔮配置示例(主机):

int i2c_master_port = 0;  // 定义 I2C 主设备的端口号i2c_config_t conf = {.mode = I2C_MODE_MASTER,  // 设置 I2C 模式为主设备模式.sda_io_num = I2C_MASTER_SDA_IO,  // 设置 I2C 主设备的数据线(SDA)的 GPIO 号码.sda_pullup_en = GPIO_PULLUP_ENABLE,  // 启用 I2C 主设备的数据线(SDA)的上拉电阻.scl_io_num = I2C_MASTER_SCL_IO,  // 设置 I2C 主设备的时钟线(SCL)的 GPIO 号码.scl_pullup_en = GPIO_PULLUP_ENABLE,  // 启用 I2C 主设备的时钟线(SCL)的上拉电阻.master.clk_speed = I2C_MASTER_FREQ_HZ,  // 设置 I2C 主设备的时钟频率.clk_flags = 0,  // 可选项,可以使用 I2C_SCLK_SRC_FLAG_* 标志来选择 I2C 源时钟
};

🔮配置示例(从机):

int i2c_slave_port = I2C_SLAVE_NUM;  // 定义 I2C 从设备的端口号i2c_config_t conf_slave = {.sda_io_num = I2C_SLAVE_SDA_IO,  // 设置 I2C 从设备的数据线(SDA)的 GPIO 号码.sda_pullup_en = GPIO_PULLUP_ENABLE,  // 启用 I2C 从设备的数据线(SDA)的上拉电阻.scl_io_num = I2C_SLAVE_SCL_IO,  // 设置 I2C 从设备的时钟线(SCL)的 GPIO 号码.scl_pullup_en = GPIO_PULLUP_ENABLE,  // 启用 I2C 从设备的时钟线(SCL)的上拉电阻.mode = I2C_MODE_SLAVE,  // 设置 I2C 模式为从设备模式.slave.addr_10bit_en = 0,  // 设置 I2C 从设备的地址模式为 7 位模式.slave.slave_addr = ESP_SLAVE_ADDR,  // 设置 I2C 从设备的地址.slave.maximum_speed = I2C_SLAVE_MAX_SPEED,  // 设置 I2C 从设备的最大时钟速度.clk_flags = 0,  // 可选项,可以使用 I2C_SCLK_SRC_FLAG_* 标志来选择 I2C 源时钟
};

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

i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0);

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

安装 I2C 驱动程序后, ESP32-S3 即可与其他 I2C 设备通信。

ESP32-S3 的 I2C 控制器在主机模式下负责与 I2C 从机设备建立通信,并发送命令让从机响应,如进行测量并将结果发给主机。

为优化通信流程,驱动程序提供一个名为 命令链接的容器,该容器应填充一系列命令,然后传递给 I2C 控制器执行。

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

下面的示例展示如何为 I2C 主机构建命令链接,从而向从机发送 n 个字节。建议对照上方👆IIC 的基本的读写通讯过程来理解
请添加图片描述
下面介绍如何为 “主机写入数据” 设置命令链接及其内部内容
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 命令链
i2c_cmd_handle_t cmd = i2c_cmd_link_create();// 添加开始信号到 I2C 命令链
i2c_master_start(cmd);// 添加从设备地址和写入方向到 I2C 命令链
i2c_master_write_byte(cmd, ( slave_address << 1 ) | WRITE_BIT, ACK_CHECK_EN);// 添加数据到 I2C 命令链
i2c_master_write_byte(cmd, data, ACK_CHECK_EN);// 添加停止信号到 I2C 命令链
i2c_master_stop(cmd);// 开始执行 I2C 命令链
esp_err_t ret = i2c_master_cmd_begin(i2c_master_port, cmd, 1000 / portTICK_RATE_MS);// 删除 I2C 命令链
i2c_cmd_link_delete(cmd);
if (ret == ESP_OK) {// 通信成功
} else {// 通信失败,处理错误
}

主机读取数据
下面的示例展示如何为 I2C 主机构建命令链接,以便从从机读取 n 个字节。

请添加图片描述

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

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

在 ESP32-S3 作为 I2C 的从设备时,它会响应主设备的消息。以下是从设备模式下通信的基本步骤及其对应的 ESP-IDF API:

  1. 监听开始信号和地址:从设备监听 I2C 总线,等待主设备发出开始信号和它的地址。这个过程是自动的,你不需要编写任何代码来实现。

  2. 发送应答:如果从设备检测到了它的地址,它会在 SDA 线上产生一个低电平,表示它已经准备好接收或发送数据。这个过程也是自动的。

  3. 接收/发送数据:从设备可以接收来自主设备的数据,或者发送数据到主设备。每接收/发送一个字节后,从设备都会发送一个应答。你可以使用 i2c_slave_read_buffer 函数来从 I2C 总线读取数据,或者使用 i2c_slave_write_buffer 函数来向 I2C 总线写入数据。

// 读取数据
uint8_t data[DATA_LENGTH];
int size = i2c_slave_read_buffer(I2C_SLAVE_NUM, data, DATA_LENGTH, 1000 / portTICK_RATE_MS);// 写入数据
uint8_t data[DATA_LENGTH] = {0x01, 0x02, 0x03, 0x04, 0x05};
int size = i2c_slave_write_buffer(I2C_SLAVE_NUM, data, DATA_LENGTH, 1000 / portTICK_RATE_MS);
  1. 监听停止信号:从设备监听 I2C 总线,等待主设备发出停止信号。这个过程是自动的,你不需要编写任何代码来实现。

✨大多数 I2C 驱动程序的函数在成功完成时会返回 ESP_OK ,或在失败时会返回特定的错误代码。

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

当使用 i2c_driver_install() 建立 I2C 通信,一段时间后不再需要 I2C 通信时,可以通过调用 i2c_driver_delete() 来移除驱动程序以释放分配的资源。

#include "driver/i2c.h"// 定义 I2C 主设备的配置参数
#define I2C_MASTER_SCL_IO 26        // GPIO号码用于I2C主设备的时钟
#define I2C_MASTER_SDA_IO 25        // GPIO号码用于I2C主设备的数据
#define I2C_MASTER_NUM I2C_NUM_0    // I2C端口号码用于主设备
#define I2C_MASTER_FREQ_HZ 100000   // I2C主设备的时钟频率
#define WRITE_BIT I2C_MASTER_WRITE  // I2C主设备写入
#define READ_BIT I2C_MASTER_READ    // I2C主设备读取
#define ACK_CHECK_EN 0x1            // I2C主设备将检查从设备的应答// 初始化 I2C 主设备
void i2c_master_init()
{int i2c_master_port = I2C_MASTER_NUM;  // 定义 I2C 主设备的端口号i2c_config_t conf;  // 定义 I2C 配置结构体conf.mode = I2C_MODE_MASTER;  // 设置 I2C 模式为主设备模式conf.sda_io_num = I2C_MASTER_SDA_IO;  // 设置 I2C 主设备的数据线 GPIO 号码conf.sda_pullup_en = GPIO_PULLUP_ENABLE;  // 启用 I2C 主设备的数据线上拉电阻conf.scl_io_num = I2C_MASTER_SCL_IO;  // 设置 I2C 主设备的时钟线 GPIO 号码conf.scl_pullup_en = GPIO_PULLUP_ENABLE;  // 启用 I2C 主设备的时钟线上拉电阻conf.master.clk_speed = I2C_MASTER_FREQ_HZ;  // 设置 I2C 主设备的时钟频率i2c_param_config(i2c_master_port, &conf);  // 配置 I2C 主设备的参数i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0);  // 安装 I2C 主设备的驱动程序
}// 主程序
void app_main()
{i2c_master_init();  // 初始化 I2C 主设备// 在这里添加你的I2C通信代码
}

这个程序首先定义了一些 I2C 的配置参数,然后在 i2c_master_init 函数中初始化了 I2C 接口。在 app_main 函数中,我们调用了 i2c_master_init 函数来初始化 I2C 接口,然后你可以在这里添加你的 I2C 通信代码。

参考资料

乐鑫官方文档I2C 驱动程序
正点原子ESP32-S3教程
微软AI Copilot

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CTF网络安全大赛详情

网络安全已成为现代社会的一个关键挑战&#xff0c;随着互联网技术的飞速发展&#xff0c;从个人隐私保护到国家安全&#xff0c;网络安全的重要性日益突显。为了应对这一挑战&#xff0c;CTF&#xff08;Capture The Flag&#xff0c;中文&#xff1a;夺旗赛&#xff09;应运而…

openEuler-22.03下载、安装

一、下载 下载地址&#xff1a;openEuler下载 | 欧拉系统ISO镜像 | openEuler社区官网 下载版本&#xff1a;openEuler-22.03-LTS-x86_64-dvd.iso 二、安装 配置完后开启虚拟机 设置完后&#xff0c;重启虚拟机 设置桥接模式的网络 cd /etc/sysconfig/network-scripts/ vi if…

LeetCode 2739. 总行驶距离

题目链接https://leetcode.cn/problems/total-distance-traveled/?envTypedaily-question&envId2024-04-25 简单题&#xff0c;看代码思考一下即可理解 class Solution {public int distanceTraveled(int mainTank, int additionalTank) {int res 0;while (mainTank >…

RK3568 学习笔记 : u-boot 千兆网络无法 ping 通PC问题的解决

前言 开发板型号&#xff1a; 【正点原子】 的 RK3568 开发板 使用 虚拟机 ubuntu 20.04 收到单独 编译 RK3568 u-boot 【问题】u-boot 千兆网络无法ping 通&#xff1f;Linux 下千兆网络正常&#xff0c;说明&#xff1a;开发板硬件正常 u-boot 下网络如果通了&#xff0c;…

【高频】基于GBDT-FM模型的level-2高频数据实证研究(二)

【高频】基于GBDT-FM模型的level-2高频数据实证研究&#xff08;二&#xff09; 原创 Yud. 2AMquant 2024-04-04 11:30 广东 上一篇中初步提及了Level2数据中常见变量指标的构建方式&#xff0c;以及其带来的价格冲击。此篇将使用GBDT-LM模型对短程价格走势进行简单预测。 ps…

Nginx下载安装,什么是nginx,什么是反向代理,Windows下、linux下安装nginx(保姆级教程)

文章目录 一、Nginx简介为什么要使用NginxNginx的特点Nginx的相关概念正向代理反向代理动静分离负载均衡 二、Nginx安装1. Windows安装2. Linux安装 一、Nginx简介 Nginx 是一个高性能的 HTTP&#xff08;静态资源服务器&#xff09; 和 反向代理 Web 服务器。 为什么要使用N…

AI-数学-高中-44导数的运算法则

原作者视频&#xff1a;【导数】【一数辞典】3导数的运算法则&#xff08;略难&#xff09;_哔哩哔哩_bilibili 三种求导表达方式一样的&#xff0c;中间的比较常用&#xff1a; 链式法则&#xff1a;从外向内&#xff1a;

如何部署Tensorrtx

因为模型跑起来太慢了&#xff0c;所以想要运用tensorrtx进行加速。但是这个是有难度的&#xff0c;且网络上的教程大多写的不是很好。我将以一个新人的视角&#xff0c;从头开始部署基于yolov5的tensorrtx加速。 知识补充&#xff1a;TensorRT和TensorRTX的区别 tensorRT是英…

统一SQL 支持Oracle cast函数转换

统一SQL介绍 https://www.light-pg.com/docs/LTSQL/current/index.html 源和目标 源数据库&#xff1a;Oracle 目标数据库&#xff1a;Postgresql&#xff0c;TDSQL-MySQL&#xff0c;达梦8&#xff0c;LightDB-Oracle 操作目标 在Oracle中&#xff0c;cast函数允许将一种…

yolov8 区域声光报警+计数

yolov8 区域报警计数 1. 基础2. 报警功能2. 1声音报警代码2. 2画面显示报警代码 3. 完整代码4. 源码 1. 基础 本项目是在 yolov8 区域多类别计数 的基础上实现的&#xff0c;具体区域计数原理可见上边文章 2. 报警功能 设置一个区域region_points&#xff0c;当行人这一类别…

链栈的基本操作(c语言实现)

栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 栈的结构 定义栈…

JVM虚拟机监控及性能调优实战

目录 jvisualvm介绍 1. jvisualvm是JDK自带的可以远程监控内存&#xff0c;跟踪垃圾回收&#xff0c;执行时内存&#xff0c;CPU/线程分析&#xff0c;生成堆快照等的工具。 2. jvisualvm是从JDK1.6开始被继承到JDK中的。jvisualvm使用 jvisualvm监控远程服务器 开启远程监控…

智能家居—ESP32开发环境搭建

相关文章 毕业设计——基于ESP32的智能家居系统(语音识别、APP控制) 智能家居—ESP32开发环境搭建 一、下载安装二、验证三、资料获取 一、下载安装 下载安装 vscode 安装插件 创建工程 二、验证 写一个简单的函数来验证一下功能 void setup() {// put your setup c…

SpringMVC笔记——SpringMVC基础Tomcat环境配置

Tomcat安装配置 下载Apache Tomcat 进入官网https://tomcat.apache.org/&#xff0c;选择tomcat 9 这边使用idea开发&#xff0c;建议直接下载压缩包 无法访问下载的可以直接用我的下载链接&#xff1a;https://cloudreve.zxbdwy.online/s/6nSA 提取码&#xff1a;w1pwk3将压…

【Java并发知识总结 | 第七篇】Java并发相关概念总结(程序/进程/线程、并行/并发、同步/异步、死锁/避免、线程安全/三大特性)

文章目录 7.并发相关概念总结&#xff08;程序/进程/线程、并行/并发、同步/异步、死锁/避免、线程安全/三大特性&#xff09;7.1程序、进程与线程7.2并行和并发7.3同步和异步7.4什么是死锁&#xff1f;如何避免&#xff1f;7.5何为线程安全&#xff1f;以及三大特性 7.并发相关…

java多线程-并发和并行

进程 并发 进程中的线程是由CPU进行调度的&#xff0c;但是CPU能够处理的进程数量有限为了保证所有的线程都在运行&#xff0c;CPU会快速切换&#xff0c;给外界的感觉就是所有的线程都在运行&#xff0c;这就是并发。 并行

C语言入门课程学习记录4

C语言入门课程学习记录4 第18课 - signed 与 unsigned第19课 - 再论数据类型第20课 - 经典问题剖析第21课 - 程序中的辅助语句&#xff08;上&#xff09;第22课 - 程序中的辅助语句&#xff08;下&#xff09; 本文学习自狄泰软件学院 唐佐林老师的 C语言入门课程&#xff0c;…

pytest教程-30-测试数据管理插件-pytest-datadir

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest重复执行用例插件pytest-repeat&#xff0c;本小节我们讲解一下测试数据管理插件-pytest-datadir。 在软件测试中&#xff0c;有效管理测试数据对于编写全面的测试用例至关重要。Pytest…

vue基础教程(7)——构建项目级首页

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、页面结构二、侧边栏三、主体部分总结 前言 前面我们学习了vue的路由和登录页搭建&#xff0c;本文将和大家共同学习首页的搭建。 首页示例如图&#xff1a; 很多项目经验比较少的同学&#xff0c;一般都是对某些语…

浅谈操作系统中的重要概念——进程

文章目录 一、什么是程序&#xff1f;二、什么是进程&#xff1f;三、进程与程序有什么区别&#xff1f;四、OS是如何管理进程的4.1、使用 结构体 进行描述进程4.2 、使用数据结构组织众多进程4.3、PCB4.3.1、PCB 里有哪些属性4.3.1.1 pid4.3.1.2 内存指针4.3.1.3 文件描述符表…