ESP32-C3入门教程 基础篇(四、I2C总线 — 与SHT21温湿度传感器通讯)_sht 21原理图

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  1. 设置参数,使用i2c_config_t结构体可以统一设置:
    在这里插入图片描述
    例如示例中:
    在这里插入图片描述
    示例中,最后使用了i2c_param_config配置好I2C的所有参数,除了自己定义的,其他的参数会被配置成 I2C 总线协议规范中定义的默认值。
    和 UART 一样,I2C的这些默认值 也可以使用一些函数对某些参数单独进行设置:
    在这里插入图片描述
  2. 使用i2c_driver_install函数进行 I2C 设备的初始化,其中包括 端口好、通讯模式,发送接收缓存区, 中断标志:
    在这里插入图片描述
    以示例中的主机初始化为例:
    在这里插入图片描述

1.2 I2C读写

  1. 完成,上述步骤以后,下面就可以发起通讯,在官方文档中的说明有一张流程图:
    在这里插入图片描述
    流程说明如下:
    在这里插入图片描述
    通过示例说明一下上述流程:
    在这里插入图片描述
    最后放一张官方介绍的 I2C 工作的整体流程图:
    在这里插入图片描述

2、 I2C 示例测试 — SHT21驱动移植

通过示例工程i2c_self_test创建好工程,通过上面的基础介绍和分析,基本上知道了I2C通讯的步骤和方式了,因为示例代码是与 BH1750 传感器进行的 通讯,所以这里示例代码是无法测试的,直接修改 SHT21 的代码。

2.1 驱动移植修改

因为SHT21驱动函数以前在 STM32上用过,这里就相当于移植过来,先把sht21.csht21.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)
    // u8Ack = i2c\_write((SHT2X\_SLAVEADDRESS<<1)|I2C\_WRITE); // a write to slave 0x40 1000 0000
    // u8Ack = (u8Ack<<1)|i2c\_write(SHT2X\_CMD\_MEAS\_RH); // request to measure humidity F5 1110 0101
	  // i2c\_stop();
				
		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_RH, 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;
    }
		// shortTermSleep(SHT2X\_HUMI\_MEAS\_TIME);
    // HAL\_Delay(SHT2X\_HUMI\_MEAS\_TIME);
    vTaskDelay(SHT2X_HUMI_MEAS_TIME / portTICK_RATE_MS);

    	
    // i2c\_start(); // send start sequence (SR)
    // u8Ack = i2c\_write((SHT2X\_SLAVEADDRESS<<1)|I2C\_READ); // read from slave 0x40 1000 0001

    cmd = i2c\_cmd\_link\_create();


![img](https://img-blog.csdnimg.cn/img_convert/a5c46d48e7a76ede4a8be7406ff8540f.png)
![img](https://img-blog.csdnimg.cn/img_convert/c9933baa27a0260698c415412fb9d493.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**



**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值