zoukankan      html  css  js  c++  java
  • SHTC3温湿度传感器的使用

    1、SHTC3简单说明  

      SHTC3是一个检测温度、湿度的传感器,可以检测-40℃~125℃的温度范围和0%~100%的湿度范围。

      SHTC3的工作电压范围为:1.62V~3.6V。

      SHTC3使用的通讯方式是I2C,通讯速率可以达到400KHz。

      SHTC3的管脚图如下:

      从图中可以看到,SHTC3只有4个引脚,电源和地、2个I2C通讯引脚。

      关于SHTC3更多说明,可以查看它的规格资料。

    2、SHTC3的设备地址和命令

      在SHTC3的规格资料内,SHTC3的I2C设备地址为0x70,如下:

      在实际的使用过程中,SHTC3的设备地址需要与读写数据/命令方向位组成一个字节同时发送,字节的最低位为读写数据/命令方向位,高7位是SHTC3的设备地址。

      如果要通过I2C写数据或命令给SHTC3,在I2C起始信号之后,需要发送“1110 0000”,即0xE0给SHTC3,除了通过高7位“1110 000”的设备地址寻址还通过最低位“0”通知SHTC3接下来是写数据或命令操作。

      如果要通过I2C读取SHTC3中的数据,在I2C起始信号之后,需要发送“1110 0001”,即0xE1给SHTC3,除了通过高7位“1110 000”的设备地址寻址还通过最低位“0”通知SHTC3接下来是读取数据的操作。

      SHTC3的命令由2个字节组成,在发送命令时,主机需要通过I2C发送2个字节命令给SHTC3。SHTC3有如下命令:

     1 //SHTC3地址
     2 #define SHTC3_ADDRESS                   0x70
     3 
     4 //SHTC3 命令
     5 #define SHTC3_WIRTE_CMD                 ((SHTC3_ADDRESS<<1)&0xFE)
     6 #define SHTC3_READ_CMD                  ((SHTC3_ADDRESS<<1)|0x01)
     7 
     8 #define SHTC3_SOFT_RESET_CMD            0x805D//软件复位命令
     9 #define SHTC3_READ_ID_CMD               0xEFC8//读取SHTC3 ID命令
    10 #define SHTC3_WAKE_UP_CMD               0x3517//将芯片从睡眠模式唤醒命令
    11 #define SHTC3_SLEEP_CMD                 0xB098//使芯片进入休眠命令
    12 
    13 //Normal Mode Clock Stretching Enable Measurement Command
    14 #define SHTC3_NOR_READ_TEMP_FIR_EN_CMD  0x7CA2//
    15 #define SHTC3_NOR_READ_HUM_FIR_EN_CMD   0x5C24//
    16 
    17 //Normal Mode Clock Stretching Disable Measurement Command
    18 #define SHTC3_NOR_READ_TEMP_FIR_DIS_CMD 0x7866//
    19 #define SHTC3_NOR_READ_HUM_FIR_DIS_CMD  0x58E0//
    20 
    21 //Low Power Mode Clock Stretching Enable Measurement Command
    22 #define SHTC3_LOW_READ_TEMP_FIR_EN_CMD  0x6458//
    23 #define SHTC3_LOW_READ_HUM_FIR_EN_CMD   0x44DE//
    24 
    25 //Low Power Mode Clock Stretching Disable Measurement Command
    26 #define SHTC3_LOW_READ_TEMP_FIR_DIS_CMD 0x609C//
    27 #define SHTC3_LOW_READ_HUM_FIR_DIS_CMD  0x401A//

      主机发送2个字节命令给SHTC3的代码如下:

     1 void SHTC3_WRITE_CMD(uint16_t cmd)
     2 {    
     3     I2C_START();
     4     SHTC3_ERR = I2C_WRITE_BYTE(SHTC3_WIRTE_CMD);
     5     if(SHTC3_ERR != 0)
     6     {
     7         SHTC3_ERR = I2C_WRITE_BYTE((cmd>>8) & 0xFF);
     8         if(SHTC3_ERR != 0)
     9         {    
    10             SHTC3_ERR = I2C_WRITE_BYTE(cmd & 0xFF);    
    11             if(SHTC3_ERR != 0)
    12             {         
    13                I2C_STOP();
    14             }
    15         }
    16     }
    17 }

      SHTC3_ERR变量的作用主要是检测是否能收到SHTC3的应答信号,如果没有收到应答信号就不再进行后面的操作。

      SHTC3_SOFT_RESET_CMD是SHTC3的软件复位命令,主机通过发送该命令来复位SHTC3。一般在上电初始化时,主机通过发送该命令来复位一下SHTC3。通过调用SHTC3_WRITE_CMD(SHTC3_SOFT_RESET_CMD)函数来软件复位SHTC3。

      SHTC3有一个16bit的ID寄存器,主机可以通过读取该寄存器的值来判断与SHTC3的通讯是否正常。该ID寄存器内保存的值如下:

       上图中的"x"表示无效值,将ID寄存器的值读取回来之后,只需要去比较bit11位和bit5~bit0位的值就好,将其它位屏蔽掉之后的值为0x0807。主机读取SHTC3 ID寄存器的值的代码如下:

     1 void SHTC3_READ_ID(uint16_t cmd)
     2 {
     3     SHTC3_ID = 0;
     4            
     5     SHTC3_WRITE_CMD(SHTC3_READ_ID_CMD);             
     6     if(SHTC3_ERR != 0)
     7     {
     8         I2C_START();    
     9         SHTC3_ERR = I2C_WRITE_BYTE(SHTC3_READ_CMD);    
    10         if(SHTC3_ERR != 0)
    11         {
    12             SHTC3_ID = I2C_READ_BYTE(1);
    13             SHTC3_ID <<= 8;
    14             SHTC3_ID |= I2C_READ_BYTE(0);
    15             I2C_STOP();     
    16             
    17             SHTC3_ID &= 0x083F;       
    18         }
    19     }
    20 }

      从SHTC3的ID寄存器读取回来的数据再与上0x083F,去除掉不需要用到的部分bit。

      SHTC3_WAKE_UP_CMD和SHTC3_SLEEP_CMD是SHTC3的休眠唤醒和进入休眠命令,在使用的过程中,为了减少功耗,在不需要测量数据的时候,一般让SHTC3处于休眠状态。在需要测量温湿度的时候,再通过发送SHTC3_WAKE_UP_CMD命令来唤醒SHTC3,但是需要注意的是,SHTC3在唤醒之后需要一段稳定的时候,只有在SHC3稳定之后主机才能发送测量命令给SHTC3。SHTC3的休眠唤醒和进入休眠的代码如下:

     1 void SHTC3_WAKE_UP(void)
     2 {
     3     SHTC3_WRITE_CMD(SHTC3_WAKE_UP_CMD);     
     4     
     5     if(SHTC3_ERR != 0)//没有收到响应信号,直接退出
     6     {
     7         I2C_STOP(); 
     8         //正常休眠唤醒之后需要等待一段稳定的时间发送命令,SHTC3才能响应主机
     9         I2C_DELAY(5000);//大约1ms            
    10     }
    11 }
    12 
    13 void SHTC3_INTO_SLEEP(void)
    14 {
    15     SHTC3_WRITE_CMD(SHTC3_SLEEP_CMD);
    16     I2C_STOP();      
    17 }

      上面的SHTC3_WAKE_UP函数在发送完SHTC3_WAKE_UP_CMD命令之后,如果收到SHTC3的应答信号,说明命令发送成功了,在发送完结束信号之后,会通过一个软件延时等待SHTC3稳定。

      在使用SHTC3时,需要注意的是,如果SHTC3处于休眠的状态,那么SHTC3只能响应唤醒命令,如果主机在SHTC3休眠的状态下发送其它命令,那么SHTC3是不会反馈应答信号给主机的。

      SHTC3上电初始化代码如下:

     1 void SHTC3_Init(void)
     2 {   
     3     I2C_Init();
     4 
     5     SHTC3_WAKE_UP();//为了防止仿真的时候SHTC3再SLEEP状态下复位运行时造成SHTC3无法响应主机发送的命令,由于在仿真的时候SHTC3芯片没有断电,还是处于休眠状态,SHTC3在休眠是无法响应除了唤醒命令的其它操作的
     6     
     7     SHTC3_WRITE_CMD(SHTC3_SOFT_RESET_CMD);//发送软件复位命令
     8     HAL_Delay(10);//延时等待复位稳定
     9 
    10     SHTC3_READ_ID(SHTC3_READ_ID_CMD);
    11     
    12     printf("SHTC3的ID值为:0x%04x
    ",SHTC3_ID); 
    13 }

      首先调用I2C_Init()函数配置I2C的引脚。然后通过调用SHTC3_WAKE_UP()函数唤醒SHTC3,这一步不是必须的,这只是为了防止在仿真的时候复位运行时,HTC3处于休眠的状态从而导致无法响应主机发送的复位命令。

      发送完唤醒命令之后,主机接着发送复位命令给SHTC3,让SHTC3软复位,SHTC3复位后需要一段稳定的时间,所以使用延时等待一下。最后读取SHTC3的ID值并通过USART打印出来,用来检验读取到的ID值是否正确。

    3、SHTC3测量温度湿度命令和步骤

      SHTC3有多个测量温度湿度的命令,如下:

      在这里使用的是Normal Mode中的命令来测量数据,Low Power Mode不知道有什么区别。

      从上面的命令表中可以看到,测量命令除了读取回来的数据先后顺序有区别,还有一个Clock Stretching Enabled和Clock Stretching Disabled的区别。

      Clock Stretching是时钟拉伸的意思。如果使用Clock Stretching Enable命令的话,那么发送完测量命令之后,在SHTC3测量温度湿度数据的过程中,SHTC3会拉低I2C的时钟线SCL,通过这样来禁止主机发送命令给SHTC3,只有当SHTC3完成温度湿度数据测量时,SHTC3才会释放时钟线SCL。

      如果使用Clock Stretching Disable命令的话,在SHTC3测量数据的过程中,SHTC3并不会拉低I2C的时钟线SCL,只是如果主机在SHTC3测量数据的过程中发送命令或数据的时候,SHTC3是不会响应主机的,主机可以通过SHTC3是否有响应信号来判断SHTC3是否完成数据的测量。

      在SHTC3数据手册中有说道,每一个测量周期包含4个命令部分,如下:

      1、发送唤醒命令。

      2、发送测量命令

      3、读取测量完成之后的数据。

      4、发送休眠命令。

    SHTC3测量示例如下图所示:

      主机首先发送休眠唤醒命令使SHTC3从休眠的状态唤醒,发送完休眠唤醒命令之后,需要等待SHTC3唤醒并且稳定。

      接着发送测量命令,SHTC3在接收到测量命令之后就开始测量数据了。

      上面的图中出现了Clock Stretching enabled和Clock Stretching disabled两个分支,这是根据发送的测量命令的不同而导致的。

      如果使用的是Clock Stretching enabled测量命令,那么在SHTC3在测量数据的过程中,当主机发送设备地址和读位给SHTC3后,SHTC3在应答一个信号之后就会将SCL时钟线拉低,主机在这个时候就无法与SHTC3通讯,只有在SHTC3测量完数据释放SCL后,主机才读取到SHTC3测量完的数据。

      如果使用的是Clock Stretching disabled测量命令,么在SHTC3在测量数据的过程中,当主机发送设备地址和读位给SHTC3,SHTC3不会产生应答信号(NACK)给主机,主机可以通过不断发送命令然后查询是否收到ACK信号来判断SHTC3是否完成测量。

      当SHTC3完成数据的测量,主机就可以读取SHTC3中的温度和湿度的数据了,温度数据包含2个字节的数据和1个字节的CRC校验数据,通用湿度的数据也包含2个字节的数据和1个字节的CRC校验数据。

      在完成数据的读取操作之后,主机发送休眠命令给SHTC3,使SHTC3在不工作的时候休眠从而降低功耗。

      读取到的温度和湿度数据是带有CRC校验的,可以通过CRC校验检验数据是否正确。SHTC3的CRC校验如下:

       SHTC3的CRC校验代码如下:

     1 uint8_t SHTC3_CRC_CHECK(uint16_t DAT,uint8_t CRC_DAT)
     2 {
     3     uint8_t i,t,temp;
     4     uint8_t CRC_BYTE;
     5    
     6     CRC_BYTE = 0xFF;  
     7     temp = (DAT>>8) & 0xFF; 
     8        
     9     for(t = 0;t < 2;t ++)
    10     {
    11         CRC_BYTE ^= temp;
    12         for(i = 0;i < 8;i ++)
    13         {
    14             if(CRC_BYTE & 0x80)
    15             {
    16                 CRC_BYTE <<= 1;
    17                 
    18                 CRC_BYTE ^= 0x31;    
    19             }    
    20             else
    21             {
    22                 CRC_BYTE <<= 1;    
    23             }
    24         }
    25         
    26         if(t == 0)
    27         {
    28             temp = DAT & 0xFF; 
    29         }
    30     }
    31     
    32     if(CRC_BYTE == CRC_DAT)
    33     {
    34         temp = 0;    
    35     }    
    36     else
    37     {
    38         temp = 1;    
    39     }
    40     
    41     return temp;
    42 }

      在SHTC3资料中已经给出了计算温度和湿度的公式,如下:

      SRH和ST是从SHTC3采集回来的数据。

      SHTC3完成一次测量的代码如下:

     1 void SHTC3_MEASUREMENT_TEMP_HUM(void)
     2 { 
     3     uint8_t Cnt; 
     4     uint8_t Temp_Check_Num;
     5     uint8_t Hum_Check_Num;
     6     
     7     uint16_t TEMP_MEASUREMENT;
     8     uint16_t HUM_MEASUREMENT; 
     9 
    10     uint32_t result;
    11 
    12     SHTC3_WAKE_UP();
    13     
    14     if(SHTC3_ERR != 0)
    15     {   
    16         SHTC3_WRITE_CMD(SHTC3_NOR_READ_TEMP_FIR_DIS_CMD);//SHTC3大约11ms~20ms检测一次温度    
    17         
    18         if(SHTC3_ERR != 0)
    19         {
    20             Cnt = 0;
    21             do//等待SHTC3检测完成,    
    22             {
    23                 I2C_DELAY(5000);//大约1ms  
    24                 I2C_START();  
    25                 SHTC3_ERR = I2C_WRITE_BYTE(SHTC3_READ_CMD);
    26                 Cnt++;
    27                 if(Cnt == 25)//防止读不到响应时,程序卡死
    28                 {
    29                     break;    
    30                 } 
    31                         
    32             }while(SHTC3_ERR == 0);//正常读取到响应才退出
    33                
    34             if(SHTC3_ERR != 0)
    35             {
    36                 //SHTC3检测完成,开始读取数据,连CRC总共6个byte    
    37                 TEMP_MEASUREMENT = I2C_READ_BYTE(1);//温度数值高8位
    38                 TEMP_MEASUREMENT <<= 8;
    39                 TEMP_MEASUREMENT |= I2C_READ_BYTE(1);//温度数值低8位
    40                 Temp_Check_Num = I2C_READ_BYTE(1);//温度CRC校验
    41     
    42                 HUM_MEASUREMENT = I2C_READ_BYTE(1);
    43                 HUM_MEASUREMENT <<= 8;
    44                 HUM_MEASUREMENT |= I2C_READ_BYTE(1);
    45                 Hum_Check_Num = I2C_READ_BYTE(0); 
    46                 
    47                 I2C_STOP();    
    48                 
    49                 Cnt = SHTC3_CRC_CHECK(TEMP_MEASUREMENT,Temp_Check_Num);
    50                 if(Cnt == 0)
    51                 {
    52                     result = TEMP_MEASUREMENT*175*10;//保留一位小数点
    53                     TEMP_DATA = (uint16_t)(result >> 16);
    54                     
    55                     if(TEMP_DATA >= 450)
    56                     {
    57                         //正温度
    58                         TEMP_DATA -= 450;
    59                         Cnt = TEMP_DATA%10;
    60                         TEMP_DATA = TEMP_DATA/10;
    61                         printf("采集到的温度度值是:%d.%d
    ",TEMP_DATA,Cnt);     
    62                     }
    63                     else
    64                     {
    65                         //负温度
    66                         TEMP_DATA = 450 - TEMP_DATA;
    67                         Cnt = TEMP_DATA%10;
    68                         TEMP_DATA = TEMP_DATA/10;
    69                         printf("采集到的温度度值是:-%d.%d
    ",TEMP_DATA,Cnt);                             
    70                     }    
    71                 }
    72                 
    73                 Cnt = SHTC3_CRC_CHECK(HUM_MEASUREMENT,Hum_Check_Num);
    74                 if(Cnt == 0)
    75                 {
    76                     result = HUM_MEASUREMENT*100;
    77                     HUM_DATA = (uint8_t)(result >> 16);
    78                     
    79                     printf("采集到的湿度值是:%d%%
    ",HUM_DATA);        
    80                 }
    81                 printf("
    ");
    82             }  
    83         }
    84         
    85         SHTC3_INTO_SLEEP();
    86     } 
    87 }

      完整的工程代码可以在:https://github.com/h1019384803/STM32F103ZET6_I2C查看。

  • 相关阅读:
    python os.open()和open()
    巨坑:浏览器在短时间内对于同一个请求的处理,会先等待上一个请求完成后,再处理下一个请求,导致在测试异步时误导代码有问题。
    写在开始
    租房小记
    小聚随笔
    由游戏想。(补发)
    对于devOps的一些理解(补发)
    写在2020-01-30(补发)
    杂谈
    如何对抗无意识状态(补发)
  • 原文地址:https://www.cnblogs.com/h1019384803/p/11519072.html
Copyright © 2011-2022 走看看