锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

#芯片# SHT21温湿度传感器的使用

时间:2023-05-30 00:37:00 cnt传感器湿度传感器ic芯片温度湿度传感器iic16加速传感器sht20数字式温湿度传感器sht3x传感器

1. 背景

工作中,需要使用到SHT21温湿度传感器。相关手册:SHT21

由于焊接问题,一些芯片存在通信异常初始化失败的问题。因此,代码中采用了极端的异常处理。(不断复位初始化)

1.1 简单的芯片数据

SHT21
湿度和温度传感器IC
包含:
(1)电容相对湿度传感器
(2)带间隙温度传感器
-------------------------
包括,放大器,AD转换器,OTP存储器和数字处理单元

解析度,12位 0.04
8位 0.7

建议传感器在正常范围内工作,长期暴露在正常条件下,特别是湿度超过80%RH在可能暂时抵消的环境中RH加速老化的信号。

对光不敏感,但长期暴露在阳光或强紫外线辐射下可能会使传感器老化。

注意:
如果SCL和SDA并行走线,超过10条cm可能导致串扰和通信中断。
通过信号之间的路由VDD 和/或 VSS 和/或 用屏蔽电缆解决。
此外 降低SCL信号可能会改善频率。
电源引脚(VDD和VSS)必须使用100nf去耦电容。

为避免信号竞争,MCU需要仅将SDA、SCL驱动为低电平。需要外部上拉电阻(10K)。

1.2 关于使用

第一步是将传感器上电至 VDD(2.1V~3.6V)
上电后,传感器在SCL高电平时最多需要15ms进入空闲状态,即准备接收自主机MCU的命令

1.3 IIC通信


(1)每次通信传输 需要以 起始条件 开始,以 结束条件 结束。
(2)发送起始条件后,需要发送 设备地址(0x81/0x80 读写)
(3)温度为 1110 0011 相对湿度为 1110 0101 。
(4)等待测量完成

基本命令:
触发温度测量(hold master) 1110 0011 0xe3
触发相对湿度测量(hold master) 1110 0101 0xe5

触发温度测量(no hold master) 1111 0011 0xf3
触发相对湿度测量(no hold master) 1111 0101 0xf5

写用户寄存器
读取用户寄存器
软件复位


1.4 保持主机模式和主机模式


保持:
不保持:


1.5 注意事项

转换时间:
测量持续时间 为ms级(默认)
相对湿度为12位,22位~29ms
14位温度测量,66~85ms

2. 代码实现

2.1 函数的初始化和测量

测量时,启动测量,等待转换完成,读取数据,停止测量。

SHT21_Measurement函数,每10ms进一次。第九次进入(90次ms),第12次经过(120-90=30ms)

#include "main.h"  #define CNT_NUM 50 /*----------------------------------------------------------------------------*/  extern void SHT2x_SoftReset(void); extern void SHT2x_SetResolution(SHT2x_Resolution res);  extern uint8_t SHT2x_ReadUserReg(void);  extern uint16_t SHT2x_GetRaw_Rx(void); extern void     SHT2x_GetRaw_Tx(uint8_t cmd);  extern uint16_t config_read(uint16_t readAddr); extern void config_write(uint16_t writeAddr,uint16_t writeData); extern int modbus_ReportResetCnt(void); void init_SHT21(void) {     SHT2x_SoftReset();     HAL_Delay(20);  //SHT2x_SetResolution(RES_14_12);     SHT2x_GetRaw_Tx(SHT2x_READ_TEMP_NOHOLD);          //读取复位次数     g_RebootCnt = config_read(REG_ADDR_REBOOT_CNT);     if(g_RebootCnt>CNT_NUM)     {         uint16_t data = SHT2x_GetRaw_Rx();                  if(data!=0||g_RebootCnt==0xFFFF)///阅读成功或首次运行需要清除计数标志         {             g_RebootCnt = 0;             config_write(REG_ADDR_REBOOT_CNT,g_RebootCnt);             SHT2x_GetRaw_Tx(SHT2x_READ_TEMP_NOHOLD);         }     }     ////阅读主动复位总数     g_RebootCntTotal = config_read(REG_ADDR_REBOOT_CNT_TOTAL);     if(g_RebootCntTotal==0xFFFF)//首次运行,未清零     {         g_RebootCntTotal=0;         config_write(REG_ADDR_REBOOT_CNT_TOTAL,g_RebootCntTotal);     }     //报复位数到PLC     modbus_ReportResetCnt(); }   //相对湿度 每30ms 读一次 //温度     每90ms 读一次 void SHT21_Measurement(void) {     static uint8_t cnt=0;     if(g_RebootCnt>CNT_NUM)return;     cnt  ;     if(cnt==9) //读取温度     {         uint16_t data=0;         data= SHT2x_GetRaw_Rx();         if(data==0)///阅读失败         {             g_RebootCnt  ;             //记录复位次数到eeprom中             config_write(REG_ADDR_REBOOT_CNT,g_RebootCnt);                          ///自动复位自救             RX1_LED_GPIO_Port->BSRR = (uint32_t)RX1_LED_Pin << 16u;             RX2_LED_GPIO_Port->BSRR = (uint32_t)RX2_LED_Pin << 16u;             RX3_LED_GPIO_Port->BSRR = (uint32_t)RX3_LED_Pin << 16u;             TX1_LED_GPIO_Port->BSRR = (uint32_t)TX1_LED_Pin << 16u;             TX2_LED_GPIO_Port->BSRR = (uint32_t)TX2_LED_Pin << 16u;             TX3_LED_GPIO_Port->BSRR = (uint32_t)TX3_LED_Pin << 16u;                          while(1);               }          shtValue.T = -4685   17572 * (data/ 65536.0);         SHTx_GetRaw_Tx(SHT2x_READ_RH_NOHOLD);
    }
    if(cnt>=12)//读取湿度
    {
        uint16_t data=0;
        data= SHT2x_GetRaw_Rx()&0xfffc;
        if(data==0||data>55574)//读取失败 
        {
            g_RebootCnt++;
            //记录复位次数到eeprom中
            config_write(REG_ADDR_REBOOT_CNT,g_RebootCnt);
            HAL_Delay(3);
            //记录总复位次数
            g_RebootCntTotal++;
            config_write(REG_ADDR_REBOOT_CNT_TOTAL,g_RebootCntTotal);
            //通过自动复位来自救
            RX1_LED_GPIO_Port->BSRR = (uint32_t)RX1_LED_Pin << 16u;
            RX2_LED_GPIO_Port->BSRR = (uint32_t)RX2_LED_Pin << 16u;
            RX3_LED_GPIO_Port->BSRR = (uint32_t)RX3_LED_Pin << 16u;
            TX1_LED_GPIO_Port->BSRR = (uint32_t)TX1_LED_Pin << 16u;
            TX2_LED_GPIO_Port->BSRR = (uint32_t)TX2_LED_Pin << 16u;
            TX3_LED_GPIO_Port->BSRR = (uint32_t)TX3_LED_Pin << 16u;
            while(1);
        }
        
        shtValue.RH = -600 + 12500 * (data /65536.0);
        SHT2x_GetRaw_Tx(SHT2x_READ_TEMP_NOHOLD);
        cnt=0;
    }
}    



 2.2 IIC通信相关的函数

/* SHT21湿度温度传感器 设备地址默认0x80*/
#include "Define.h"
#include "TypeDef.h"

/**
 *  @brief Performs a soft reset.
 */
void SHT2x_SoftReset(void){
	uint8_t cmd = SHT2x_SOFT_RESET;
	HAL_I2C_Master_Transmit(&hi2c2, SHT2x_I2C_ADDR << 1, &cmd, 1, SHT2x_TIMEOUT);
}

/**
 * @brief Gets the value stored in user register.
 * @return 8-bit value stored in user register, 0 to 255.
 */
uint8_t SHT2x_ReadUserReg(void) {
	uint8_t val;
	uint8_t cmd = SHT2x_READ_REG;
	HAL_I2C_Master_Transmit(&hi2c2, SHT2x_I2C_ADDR << 1, &cmd, 1, SHT2x_TIMEOUT);
	HAL_I2C_Master_Receive(&hi2c2, SHT2x_I2C_ADDR << 1, &val, 1, SHT2x_TIMEOUT);
	return val;
}

void     SHT2x_GetRaw_Tx(uint8_t cmd) {
	HAL_I2C_Master_Transmit(&hi2c2, SHT2x_I2C_ADDR << 1, &cmd, 1, SHT2x_TIMEOUT);
}

uint16_t SHT2x_GetRaw_Rx(void) {
    uint8_t val[3] = { 0 };
    HAL_I2C_Master_Receive(&hi2c2, SHT2x_I2C_ADDR << 1, val, 3, SHT2x_TIMEOUT);
    return (val[0] << 8 | val[1]);
}

/**
 * @brief Sets the measurement resolution.
 * @param res Enum resolution.
 * @note Available resolutions: RES_14_12, RES_12_8, RES_13_10, RES_11_11.
 * @note RES_14_12 = 14-bit temperature and 12-bit RH resolution, etc.
 */
void SHT2x_SetResolution(SHT2x_Resolution res) {
	uint8_t val = SHT2x_ReadUserReg();
	val = (val & 0x7e) | res;
	uint8_t temp[2] = { SHT2x_WRITE_REG, val };
	HAL_I2C_Master_Transmit(&hi2c2, SHT2x_I2C_ADDR << 1, temp, 2, SHT2x_TIMEOUT);
}

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章