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\r\n",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\r\n",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\r\n",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%%\r\n",HUM_DATA); 80  } 81                 printf("\r\n"); 82  } 83  } 84         
85  SHTC3_INTO_SLEEP(); 86  } 87 }

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM