【esp32 idf入门】快速使用i2c发送和接收数据
@TOC
前言
ESP32 是一款集成了 Wi-Fi 和 Bluetooth 的高性能低功耗系统级芯片(SoC),广泛应用于物联网 (IoT) 领域。ESP32 支持多种通信协议,其中 I2C(Inter-Integrated Circuit)是一种常用的串行通信协议,用于连接微控制器与外围设备。本文将介绍如何快速在 ESP32 上使用 I2C 协议发送和接收数据,帮助初学者快速上手 ESP-IDF(Espressif IoT Development Framework)。
观前须知
上篇I2C文章I2C他的代码也是OK没有问题的,那为什么有这篇文章呢?
原因就是上篇文章的操作方法太过复杂了,还需要什么开始命令这些,非常恶心,idf提供了类似于STM32的Mem模式,使用一个函数即可发送指令读取指定位置的数据
函数介绍
i2c_master_write_read_device
函数原型
esp_err_t i2c_master_write_read_device(
i2c_port_t i2c_num,
uint8_t device_address,
const uint8_t *write_buffer,
size_t write_size,
uint8_t *read_buffer,
size_t read_size,
TickType_t ticks_to_wait
);
函数作用
该函数用于在 I2C 主设备上执行写操作和读操作,通常用于先发送命令或地址,然后读取从设备的响应数据。它将写入和读取操作结合在一次传输中,减少了通信开销。
参数介绍
i2c_port_t i2c_num
: I2C 端口号,取值为I2C_NUM_0
或I2C_NUM_1
,表示使用的 I2C 控制器。uint8_t device_address
: I2C 从设备的 7 位地址。const uint8_t *write_buffer
: 指向要写入的数据缓冲区的指针。size_t write_size
: 要写入的数据字节数。uint8_t *read_buffer
: 指向用于存储读取数据的缓冲区的指针。size_t read_size
: 要读取的数据字节数。TickType_t ticks_to_wait
: 等待完成操作的最大时间,单位是系统时钟节拍数。
返回值
ESP_OK
: 操作成功。- 其他
esp_err_t
错误代码: 操作失败,具体错误码可以帮助诊断问题。
i2c_master_write_to_device
函数原型
esp_err_t i2c_master_write_to_device(
i2c_port_t i2c_num,
uint8_t device_address,
const uint8_t *write_buffer,
size_t write_size,
TickType_t ticks_to_wait
);
函数作用
该函数用于在 I2C 主设备上执行写操作,将指定的数据发送到 I2C 从设备。通常用于发送命令、寄存器地址或数据给从设备。
参数介绍
i2c_port_t i2c_num
: I2C 端口号,取值为I2C_NUM_0
或I2C_NUM_1
,表示使用的 I2C 控制器。uint8_t device_address
: I2C 从设备的 7 位地址。const uint8_t *write_buffer
: 指向要写入的数据缓冲区的指针。size_t write_size
: 要写入的数据字节数。TickType_t ticks_to_wait
: 等待完成操作的最大时间,单位是系统时钟节拍数。
返回值
ESP_OK
: 操作成功。- 其他
esp_err_t
错误代码: 操作失败,具体错误码可以帮助诊断问题。
示例
如果想要更多的示例,请找到你的idf安装目录,找到framework,找到esp-idf-v5.2.2
,然后找到examples
即可
使用 i2c_master_write_read_device
的示例
假设我们要从 I2C 从设备读取数据前,先发送一个命令:
#include <stdio.h>
#include "driver/i2c.h"
#define I2C_MASTER_SCL_IO 22 // I2C master clock pin
#define I2C_MASTER_SDA_IO 21 // I2C master data pin
#define I2C_MASTER_NUM I2C_NUM_0 // I2C port number
#define I2C_MASTER_FREQ_HZ 100000 // I2C master clock frequency
#define I2C_MASTER_TX_BUF_DISABLE 0 // I2C master doesn't need buffer
#define I2C_MASTER_RX_BUF_DISABLE 0 // I2C master doesn't need buffer
#define I2C_MASTER_TIMEOUT_MS 1000
#define DEVICE_ADDRESS 0x28 // I2C device address
#define WRITE_CMD 0x01 // Command to be sent to the device
void app_main(void) {
// Initialize I2C master
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_MASTER_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_param_config(I2C_MASTER_NUM, &conf);
i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
uint8_t write_buffer = WRITE_CMD;
uint8_t read_buffer[10]; // Buffer to store the read data
esp_err_t ret = i2c_master_write_read_device(
I2C_MASTER_NUM,
DEVICE_ADDRESS,
&write_buffer,
sizeof(write_buffer),
read_buffer,
sizeof(read_buffer),
pdMS_TO_TICKS(I2C_MASTER_TIMEOUT_MS)
);
if (ret == ESP_OK) {
printf("Data read from device: ");
for (int i = 0; i < sizeof(read_buffer); i++) {
printf("%02x ", read_buffer[i]);
}
printf("\n");
} else {
printf("I2C read failed\n");
}
// Clean up
i2c_driver_delete(I2C_MASTER_NUM);
}
使用 i2c_master_write_to_device
的示例
假设我们要将一些数据发送到 I2C 从设备:
#include <stdio.h>
#include "driver/i2c.h"
#define I2C_MASTER_SCL_IO 22 // I2C master clock pin
#define I2C_MASTER_SDA_IO 21 // I2C master data pin
#define I2C_MASTER_NUM I2C_NUM_0 // I2C port number
#define I2C_MASTER_FREQ_HZ 100000 // I2C master clock frequency
#define I2C_MASTER_TX_BUF_DISABLE 0 // I2C master doesn't need buffer
#define I2C_MASTER_RX_BUF_DISABLE 0 // I2C master doesn't need buffer
#define I2C_MASTER_TIMEOUT_MS 1000
#define DEVICE_ADDRESS 0x28 // I2C device address
void app_main(void) {
// Initialize I2C master
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_MASTER_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_param_config(I2C_MASTER_NUM, &conf);
i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
uint8_t write_buffer[] = {0x01, 0x02, 0x03, 0x04}; // Data to be sent to the device
esp_err_t ret = i2c_master_write_to_device(
I2C_MASTER_NUM,
DEVICE_ADDRESS,
write_buffer,
sizeof(write_buffer),
pdMS_TO_TICKS(I2C_MASTER_TIMEOUT_MS)
);
if (ret == ESP_OK) {
printf("Data written to device successfully\n");
} else {
printf("I2C write failed\n");
}
// Clean up
i2c_driver_delete(I2C_MASTER_NUM);
}
总结
通过本文的介绍,我们了解了如何在 ESP32 上使用 ESP-IDF 进行 I2C 通信,包括设置 I2C 配置、初始化 I2C 驱动程序、发送数据和接收数据。I2C 协议的简洁性和高效性,使其成为与传感器、显示屏等外设通信的理想选择。掌握了这些基础操作后,您可以根据实际需求扩展和应用 I2C 通信,为各种 IoT 项目开发奠定坚实的基础。
- 点赞
- 收藏
- 关注作者
评论(0)