既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
对于ESP32-C3 I2C的介绍,乐鑫的官网的说明链接如下:
国产的芯片终于遇到个中文资料了,呵呵~
ESP32-C3 只有一个 I2C接口,可做主机也可以做从机。
本文的测试以及说明是以 ESP23-C3 作为主机来说明
1.1 I2C初始化
根据官方文档,ESP32-C3 UART使用步骤如下:
- 设置参数,使用
i2c_config_t
结构体可以统一设置:
例如示例中:
示例中,最后使用了i2c_param_config
配置好I2C的所有参数,除了自己定义的,其他的参数会被配置成 I2C 总线协议规范中定义的默认值。
和 UART 一样,I2C的这些默认值 也可以使用一些函数对某些参数单独进行设置:
- 使用
i2c_driver_install
函数进行 I2C 设备的初始化,其中包括 端口好、通讯模式,发送接收缓存区, 中断标志:
以示例中的主机初始化为例:
1.2 I2C读写
- 完成,上述步骤以后,下面就可以发起通讯,在官方文档中的说明有一张流程图:
流程说明如下:
通过示例说明一下上述流程:
最后放一张官方介绍的 I2C 工作的整体流程图:
2、 I2C 示例测试 — SHT21驱动移植
通过示例工程i2c_self_test
创建好工程,通过上面的基础介绍和分析,基本上知道了I2C通讯的步骤和方式了,因为示例代码是与 BH1750
传感器进行的 通讯,所以这里示例代码是无法测试的,直接修改 SHT21 的代码。
2.1 驱动移植修改
因为SHT21驱动函数以前在 STM32上用过,这里就相当于移植过来,先把sht21.c
和sht21.h
文件放进来,当然得注意包含关系,宏定义等一些东西:
既然增加了驱动,所以代码就放在驱这两个文件里面,对于sht21.h
文件,宏定义放在此文件中,函数在sht21.c
文件中实现(下面会放源码),在此处声明 :
在 sht21.c
中的温湿度读取函数是如何实现的呢, 先来看一张 STH21 读取的时序图,是我在另一篇博文中写好的:
上图出自:nRF52832学习记录(十一、TWI总线的应用 SHT21程序移植)
这里我就直接上源码 :
#include "sht21.h"
struct {
sint16 value;
uint16 raw;
uint8 crc;
} aTemperature, aHumidity;
esp\_err\_t i2c\_master\_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;
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,
// .clk\_flags = 0, /\*!< Optional, you can use I2C\_SCLK\_SRC\_FLAG\_\* flags to choose i2c source clock here. \*/
};
esp\_err\_t err = i2c\_param\_config(i2c_master_port, &conf);
if (err != ESP_OK) {
return err;
}
return i2c\_driver\_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}
// fT = 175.72\*u16T/65536.0 - 46.85;
// fRH = 125.0\*u16RH/65536.0 - 6.0;
// -------------------------------------------------------------------
sint16 sht21\_calcRH(uint16 u16RH)
{
sint16 humidityRH; // variable for result
u16RH &= ~0x0003; // clear bits [1..0] (status bits)
//-- calculate relative humidity [%RH] --
humidityRH = (sint16)(-600 + (12500\*(sint32)u16RH)/65536 ); // RH = -6 + 125 \* SRH/2^16
return humidityRH; // Return RH\*100
}
// -------------------------------------------------------------------
sint16 sht21\_calcTemperature(uint16 u16T)
{
sint16 temperature; // variable for result
u16T &= ~0x0003; // clear bits [1..0] (status bits)
//-- calculate temperature [癈] --
temperature= (sint16)(-4685 + (17572\*(sint32)u16T)/65536); //T = -46.85 + 175.72 \* ST/2^16
return temperature; //return T\*100
}
// i2c\_cmd\_handle\_t cmd = i2c\_cmd\_link\_create();
// i2c\_master\_start(cmd);
// i2c\_master\_write\_byte(cmd, BH1750\_SENSOR\_ADDR << 1 | WRITE\_BIT, ACK\_CHECK\_EN);
// i2c\_master\_write\_byte(cmd, BH1750\_CMD\_START, ACK\_CHECK\_EN);
// i2c\_master\_stop(cmd);
// ret = i2c\_master\_cmd\_begin(i2c\_num, cmd, 1000 / portTICK\_RATE\_MS);
// i2c\_cmd\_link\_delete(cmd);
// if (ret != ESP\_OK) {
// return ret;
// }
// vTaskDelay(30 / portTICK\_RATE\_MS);
// cmd = i2c\_cmd\_link\_create();
// i2c\_master\_start(cmd);
// i2c\_master\_write\_byte(cmd, BH1750\_SENSOR\_ADDR << 1 | READ\_BIT, ACK\_CHECK\_EN);
// i2c\_master\_read\_byte(cmd, data\_h, ACK\_VAL);
// i2c\_master\_read\_byte(cmd, data\_l, NACK\_VAL);
// i2c\_master\_stop(cmd);
// ret = i2c\_master\_cmd\_begin(i2c\_num, cmd, 1000 / portTICK\_RATE\_MS);
// i2c\_cmd\_link\_delete(cmd);
esp\_err\_t SHT2X\_THMeasure(i2c\_port\_t i2c_num){
// uint8 u8Ack;
int ret;
uint8 t_value[3];
uint8 h_value[3];
#if (SHT2X\_RESOLUTION != 0x00) // only needed if used resolution other than default
// i2c\_start(); // send start sequence (S)
// u8Ack = i2c\_write((SHT2X\_SLAVEADDRESS<<1)|I2C\_WRITE); // write to slave 0x40
// u8Ack = (u8Ack<<1)|i2c\_write(SHT2X\_CMD\_RD\_REG); // request to read from user register
// i2c\_start(); // send start sequence (S)
// u8Ack = (u8Ack<<1)|i2c\_write((SHT2X\_SLAVEADDRESS<<1)|I2C\_READ); // read from slave 0x40
// u8UserReg = i2c\_read(I2C\_NACK); // read user register
// i2c\_start(); // send start sequence (S)
// u8Ack = i2c\_write((SHT2X\_SLAVEADDRESS<<1)|I2C\_WRITE); // write to slave 0x40
// u8Ack = (u8Ack<<1)|i2c\_write(SHT2X\_CMD\_WR\_REG); // request to write user register
// u8Ack = (u8Ack<<1)|i2c\_write(SHT2X\_RESOLUTION | (u8UserReg & ~0x81)); // write new user register data
i2c\_cmd\_handle\_t cmd = i2c\_cmd\_link\_create();
i2c\_master\_start(cmd);
i2c\_master\_write\_byte(cmd, SHT2X_SLAVEADDRESS<<1 | WRITE_BIT, ACK_CHECK_EN);
i2c\_master\_write\_byte(cmd, SHT2X_CMD_WR_REG, ACK_CHECK_EN);
i2c\_master\_stop(cmd);
ret = i2c\_master\_cmd\_begin(i2c_num, cmd, 500 / portTICK_RATE_MS);
i2c\_cmd\_link\_delete(cmd);
if (ret != ESP_OK) {
return ret;
}
#endif//(SHT2X\_RESOLUTION != 0x00)
// --------------------
// measure temperature
// --------------------
// i2c\_start(); // send start sequence (S)
// u8Ack = i2c\_write((SHT2X\_SLAVEADDRESS<<1)|I2C\_WRITE);//----IIC???(8?)???7??IIC????0x80(???HT2X\_SLAVEADDRESS=0x40)???DATA???(?R:1 ,?WRITE?0) //a write to slave 0x40
// u8Ack = (u8Ack<<1)|i2c\_write(SHT2X\_CMD\_MEAS\_T); //----SHT2X\_CMD\_MEAS\_T=0xF3(??????,???)//request to measure temperature
// i2c\_stop();
i2c\_cmd\_handle\_t cmd = i2c\_cmd\_link\_create();
i2c\_master\_start(cmd);
i2c\_master\_write\_byte(cmd, SHT2X_SLAVEADDRESS<<1 | WRITE_BIT, ACK_CHECK_EN);
i2c\_master\_write\_byte(cmd, SHT2X_CMD_MEAS_T, ACK_CHECK_EN);
i2c\_master\_stop(cmd);
ret = i2c\_master\_cmd\_begin(i2c_num, cmd, 500 / portTICK_RATE_MS);
i2c\_cmd\_link\_delete(cmd);
if (ret != ESP_OK) {
return ret;
}
vTaskDelay(SHT2X_TEMP_MEAS_TIME / portTICK_RATE_MS);
// shortTermSleep(SHT2X\_TEMP\_MEAS\_TIME);
// HAL\_Delay(SHT2X\_TEMP\_MEAS\_TIME);
// time\_wait(SHT2X\_TEMP\_MEAS\_TIME);
// i2c\_start(); // send start sequence (SR)
// u8Ack = i2c\_write((SHT2X\_SLAVEADDRESS<<1)|I2C\_READ); //----IIC???(8?)???7??IIC????0x80(???HT2X\_SLAVEADDRESS=0x40)???DATA???(?R:1 ,?WRITE?0) // a read from slave 0x40
cmd = i2c\_cmd\_link\_create();
i2c\_master\_start(cmd);
i2c\_master\_write\_byte(cmd, SHT2X_SLAVEADDRESS << 1 | READ_BIT, ACK_CHECK_EN);
i2c\_master\_read\_byte(cmd, &t_value[0], ACK_VAL);
i2c\_master\_read\_byte(cmd, &t_value[1], ACK_VAL);
i2c\_master\_read\_byte(cmd, &t_value[2], NACK_VAL);
i2c\_master\_stop(cmd);
ret = i2c\_master\_cmd\_begin(i2c_num, cmd, 500 / portTICK_RATE_MS);
i2c\_cmd\_link\_delete(cmd);
// if(u8Ack==I2C\_ACK) {
// aTemperature.raw = i2c\_read(I2C\_ACK)<<8; // read hi byte
// aTemperature.raw |= i2c\_read(I2C\_ACK); // read lo byte
// aTemperature.crc = i2c\_read(I2C\_NACK); // read check sum and finish transfere
// }else {
// aTemperature.raw = 0;
// }
// i2c\_stop();
aTemperature.raw = t_value[0]<<8;
aTemperature.raw |= t_value[1];
aTemperature.crc = t_value[2];
// -------------------------
// Humidity Measure
// -------------------------
// i2c\_start(); // send start sequence (S)


**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**