ESP32 之 ESP-IDF 教学(六)——硬件I2C总线外设(I²C)

本文详细介绍了如何在ESP-IDF框架下利用ESP32进行I2C通信,包括配置I2C驱动、安装驱动、主机模式下读写数据的步骤,以及代码示例。通过实例展示了如何创建I2C命令对象,添加数据帧并发送数据。同时提到了自定义时序和I2C中断等进阶话题。
摘要由CSDN通过智能技术生成

本文章 来自原创专栏《ESP32教学专栏 (基于ESP-IDF)》,讲解如何使用 ESP-IDF 构建 ESP32 程序,发布文章并会持续为已发布文章添加新内容! 每篇文章都经过了精打细磨!

↓↓↓通过下方对话框进入专栏目录页↓↓↓
CSDN 请求进入目录       _ O x

是否进入ESP32教学导航(基于ESP-IDF)?

       确定


一、I2C 简介

I2C是一种通过两条双向IO线:SDA(串行数据线)和SCL(串行时钟线)进行数据通信的一种通信协议

二、I2C 数据帧

由于 ESP-IDF 对于I2C通信协议的封装较为完善,开发者写程序并不需要完全了解 I2C 通信时序,只需要理解I2C通信的数据帧即可。
在这里插入图片描述

Start Slave Address R/W Ack Slave Address Ack Slave Address Ack Ack Stop
起始 从机地址 读/写 应答 8位数据 应答 8位数据 应答 应答 终止
  1. 起始信号
  2. 发送从机地址
  3. 发送读写标志:0为写,1为读取
  4. 应答位(可设置为忽略应答位)
  5. 发送8位数据
  6. loop循环执行4、5。直至发送完所有数据
  7. 终止

接下来我们将离不开I2C数据帧的格式。

三、在 ESP-IDF 中 使用 I2C API (仅介绍主机模式)

ESP-IDF 封装的 I2C API 中体现了面向对象的思想。它将 I2C 发送的数据帧当作了一个装有数据的容器。具体使用逻辑如下:

  1. 创建一个空的 I2C 命令 对象。
  2. 添加各种子数据帧,例如起始信号,从机地址,读写位,数据,终止信号等。

接下来我将用例程来展示在 ESP-IDF 中 使用 I2C API。在此之前,我总结一下使用 I2C 的步骤。

1、使用步骤(主机)

注意:
步骤①和步骤②可以颠倒!

① 配置驱动程序i2c_param_config()
【1】参数配置

我们需要传递一个 i2c_config_t 结构体指针,该结构体包含了配置i2c主机模式的参数。

int i2c_master_port = 0;
i2c_config_t conf = {
   
// 选择工作模式,I2C_MODE_MASTER 为本文介绍的主机模式
    .mode 			  = I2C_MODE_MASTER,
// 选择SDA管脚的GPIO编号
    .sda_io_num 	  = I2C_MASTER_SDA_IO,
// 允许上拉
    .sda_pullup_en 	  = GPIO_PULLUP_ENABLE,
// 选择SCL管脚的GPIO编号
    .scl_io_num 	  = I2C_MASTER_SCL_IO,
// 允许上拉
    .scl_pullup_en 	  = GPIO_PULLUP_ENABLE, 
// 选择一个合适的时钟频率(比如100,000)
    .master.clk_speed = I2C_MASTER_FREQ_HZ, 
/* 选择时钟源头,你可以填入I2C_SCLK_SRC_FLAG_* 来选择合适的时钟源 */
    .clk_flags = 0,//此句可以注释掉
};
【2】源时钟配置

对于.clk_flags元素:

名称 含义
I2C_SCLK_SRC_FLAG_FOR_NOMA 0 仅根据所需频率进行自动选择时钟。(不支持特殊功能,如 APB 等)
I2C_SCLK_SRC_FLAG_AWARE_DFS 1 当 APB 时钟改变时,时钟的波特率不会改变。
I2C_SCLK_SRC_FLAG_LIGHT_SLEEP 2 用于轻度睡眠模式

之后调用i2c_param_config()配置 I2C:

i2c_param_config(I2C_NUM_0, &conf);
  • 参数一:欲配置的I2C通道(I2C_NUM_0I2C_NUM_1
  • 参数二:配置参数结构体的指针
② 安装 I2C 驱动

方法是调用函数 i2c_driver_install()

函数 i2c_driver_install() 简介:
 
1、参数(手机端可能得不到完全展示,手机端可以滑动来查看右边一列)

参数名 含义 类型
"i2c_num" 【I2C 端口编号】
01,或者I2C_NUM_0I2C_NUM_1
[i2c_port_t]
"mode" 总线工作模式
主机(I2C_MODE_MASTER)还是从机(I2C_MODE_SLAVE
[i2c_mode_t]
"slv_rx_buf_len&
ESP32-IDF开发环境下进行I2C总线设备地址扫描的实例,我们可以使用ESP-IDF提供的API函数来实现。 首先,我们需要在代码中包含头文件"driver/i2c.h"来获取I2C相关函数的声明。 接下来,我们需要初始化I2C总线。可以使用函数"i2c_config_t"来定义I2C总线的配置参数,包括总线号、SCL引脚、SDA引脚、时钟频率等。然后,我们可以调用函数"i2c_param_config"进行参数配置,并通过函数"i2c_driver_install"来安装I2C驱动程序。 一旦I2C总线初始化完成,我们就可以开始扫描I2C设备的地址了。我们可以使用函数"i2c_scan"来实现扫描。该函数接受一个包含所有扫描地址的数组作为参数。 下面是一个示例代码: ``` #include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/i2c.h" #define I2C_MASTER_NUM I2C_NUM_0 // I2C总线号 #define I2C_MASTER_SCL_IO 19 // SCL引脚 #define I2C_MASTER_SDA_IO 18 // SDA引脚 #define I2C_MASTER_FREQ_HZ 100000 // I2C总线时钟频率 void i2c_scan_task(void *arg) { i2c_config_t conf; conf.mode = I2C_MODE_MASTER; conf.sda_io_num = I2C_MASTER_SDA_IO; conf.sda_pullup_en = GPIO_PULLUP_ENABLE; conf.scl_io_num = I2C_MASTER_SCL_IO; conf.scl_pullup_en = GPIO_PULLUP_ENABLE; conf.master.clk_speed = I2C_MASTER_FREQ_HZ; i2c_param_config(I2C_MASTER_NUM, &conf); i2c_driver_install(I2C_MASTER_NUM, I2C_MODE_MASTER, 0, 0, 0); uint8_t scan_addr[128]; i2c_scan(I2C_MASTER_NUM, scan_addr); printf("I2C devices found:\n"); for (int i = 0; i < 128; i++) { if (scan_addr[i] != 0) { printf("- Address: 0x%.2X\n", scan_addr[i]); } } vTaskDelete(NULL); } void app_main() { xTaskCreate(i2c_scan_task, "i2c_scan_task", 2048, NULL, 10, NULL); } ``` 以上代码实现了一个名为"i2c_scan_task"的任务,它首先配置了I2C总线的参数,然后安装I2C驱动程序。接着,它创建了一个包含128个元素的数组,用于存储扫描到的I2C设备地址。最后,它遍历该数组并打印出非零的地址,即已扫描到的I2C设备地址。 通过运行以上代码,我们就可以在终端看到已连接到I2C总线上的设备地址列表。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Augtons正(单片机)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值