SHT3x是新一代的溫濕度傳感器,精度為±2%RH和±0.3℃,輸入電壓范圍從2.4V到5.5V,采用IIC總線接口,速率可達1MHz。測量溫濕度范圍分別為是-40℃ ~ 125℃和0 ~ 100%。工作電流為600uA,空閑電流在2ua。因此非常適合用在低功耗溫濕度監測項目之上。 SHT3X的獲取溫度只需要二步,一是發送溫度轉換命令,接著讀取6個字節。進行溫濕度測量,需先發送一個開始信號,然后發送一個 I2C的寫操作頭,然后再跟隨一個 16 位的溫濕度轉換命令。傳感器收到上位機發送的每個字節數據后,會通過將 SDA 總線拉到低電平給出ACK 信號。在正確的收到溫濕度轉換命令并發送 ACK 信號給微處理器之后,SHT3x 內部開始啟動溫度和濕度的轉換測量。二是在傳感器完成溫濕度測量之后,上位機可以通過發送 START信號+I2C 讀取數據頭來 讀取溫濕度數據,如果溫濕度數據已經準備好,那么芯片會向上位機發送 ACK 信號,并隨后發送 2 字節的溫度數據加 1 字節的 CRC 校驗數據,然后再發送 2 字節的濕度數據加 1 字節的 CRC 校驗數據。上位機需要對接收到的每個字節數據發送 ACK,否則芯片會停止發送數據。微處理器在收到濕度數據的CRC 字節后應該發送一個NACK 和一個 STOP 信號來結束本次數據傳輸,
下面開始CW32L083的溫度采集:
1、選取PB10、PB11為I2C通信,采取軟件I2C。初始化代碼如下:
void IIC_Init(void)
{
//配置PB10 為輸出
//使能GPIOB時鐘
CW_SYSCTRL->AHBEN_f.GPIOB = 1;
//配置PB10 為輸出
CW_GPIOB->ANALOG_f.PIN10 = 0; //設置 GPIOx_ANALOG.PINy 為 0,將端口配置為數字功能;
CW_GPIOB->DIR_f.PIN10 = 0; //設置 GPIOx_DIR.PINy 為 0,將端口配置成輸出;
CW_GPIOB->OPENDRAIN_f.PIN10 = 0; //0:推挽輸出
CW_GPIOB->ODR_f.PIN10 = 1;
CW_GPIOB->ANALOG_f.PIN11 = 0; //設置 GPIOx_ANALOG.PINy 為 0,將端口配置為數字功能;
CW_GPIOB->DIR_f.PIN11 = 0; //設置 GPIOx_DIR.PINy 為 0,將端口配置成輸出;
CW_GPIOB->OPENDRAIN_f.PIN11 = 0; //0:推挽輸出
CW_GPIOB->ODR_f.PIN11 = 1;
}
2、設置IO方向,SDA需要轉換輸出與輸入,我們采用對 GPIOx_DIR.PINy進行設置,來實現IO的數據輸入與輸出的轉換。
//IO方向設置(SDA)
/ xxxxxxxxxxxxxx ****/
void SDA_IN()
{
CW_GPIOB->DIR_f.PIN11 = 1; //設置 GPIOx_DIR.PINy 為 0,將端口配置成輸出;
}
void SDA_OUT()
{
CW_GPIOB->DIR_f.PIN11 = 0; //設置 GPIOx_DIR.PINy 為 0,將端口配置成輸出;
CW_GPIOB->OPENDRAIN_f.PIN11 = 0; //0:推挽輸出
}
3、定義讀取SDA的宏:#define READ_SDA PB11_GETVALUE() //輸入SDA
4、定義IIC的STAT、STOP、ACK、NACK等時序,代碼如下:
//產生IIC起始信號
void IIC_Start(void)
{
SDA_OUT(); //sda線輸出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//鉗住I2C總線,準備發送或接收數據
}
//產生IIC停止信號
void IIC_Stop(void)
{
SDA_OUT();//sda線輸出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//發送I2C總線結束信號
delay_us(4);
}
//等待應答信號到來
//返回值:1,接收應答失敗
// 0,接收應答成功
/ xxxx修改超時時間 ***/
uint8_t IIC_Wait_Ack(void)
{
uint8_t ucErrTime=0;
SDA_IN(); //SDA設置為輸入
IIC_SDA=1;delay_us(3);
IIC_SCL=1;delay_us(3);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
//printf("超時
");IIC_Stop();
return 1;
}
}
IIC_SCL=0;//時鐘輸出0
return 0;
}
//產生ACK應答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不產生ACK應答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
5、定義發送一個字節:
//IIC發送一個字節
//返回從機有無應答
//1,有應答
//0,無應答
void IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
SDA_OUT();
IIC_SCL=0;//拉低時鐘開始數據傳輸
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
delay_us(2); //對TEA5767這三個延時都是必須的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
6、定義讀取一個字節
//讀1個字節,ack=1時,發送ACK,ack=0,發送nACK
uint8_t IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA設置為輸入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(100);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(100);
}
if (!ack)
IIC_NAck();//發送nACK
else
IIC_Ack(); //發送ACK
return receive;
}
到這里IIC的初始化工作結束。
6、SHT3x的數據獲取,采集廠家出廠的標準DEMO。主要是發送轉換溫度的命令與讀取命令,sth30.c代碼如下:
#include "sht30.h"
#define POLYNOMIAL_CXDZ 0x31 // X^8 + X^5 + X^4 + 1
//SHT3X CRC校驗
unsigned char SHT3X_CRC(uint8_t *data, uint8_t len)
{
unsigned char bit; // bit mask
unsigned char crc = 0xFF; // calculated checksum
unsigned char byteCtr; // byte counter
// calculates 8-Bit checksum with given polynomial @GZCXDZ
for(byteCtr = 0; byteCtr < len; byteCtr++) {
crc ^= (data[byteCtr]);
for(bit = 8; bit > 0; --bit) {
if(crc & 0x80) {
crc = (crc << 1) ^ POLYNOMIAL_CXDZ;
} else {
crc = (crc << 1);
}
}
}
return crc;
}
//SHT30命令函數
//addr:表示產品的序號,因為SHT30使用IIC總線的話一條線上可以掛兩個
void SHT30_CMD(uint16_t cmd)
{
IIC_Start();
IIC_Send_Byte(SHT30_ADDR+0); //發送設備地址,寫寄存器
IIC_Wait_Ack();
IIC_Send_Byte((cmd>>8)&0xff); //MSB
IIC_Wait_Ack();
IIC_Send_Byte(cmd&0xff); //LSB
IIC_Wait_Ack();
IIC_Stop();
SysTickDelay(500);//命令發完后需要等待20ms以上才能讀寫
}
//SHT30讀取溫濕度
//temp:溫度,-400~1250,實際溫度=temp/10,分辨率0.1℃,精度±0.3℃
//humi:濕度,0~1000,實際濕度=humi/10,分辨率0.1%rh,精度±3
//返回0成功,1失敗
uint8_t SHT30_Read_Humiture(int *temp,uint16_t *humi)
{
uint8_t buff[6];
SHT30_CMD(SHT30_READ_HUMITURE);//讀溫濕度命令
IIC_Start();
IIC_Send_Byte(SHT30_ADDR+1); //發送設備地址,讀寄存器
IIC_Wait_Ack();
buff[0]=IIC_Read_Byte(1);//繼續讀,給應答
buff[1]=IIC_Read_Byte(1);//繼續讀,給應答
buff[2]=IIC_Read_Byte(1);//繼續讀,給應答
buff[3]=IIC_Read_Byte(1);//繼續讀,給應答
buff[4]=IIC_Read_Byte(1);//繼續讀,給應答
buff[5]=IIC_Read_Byte(0);//不繼續給停止應答
IIC_Stop();
//printf("buff=%d,%d,%d,%d,%d,%d
",buff[0],buff[1],buff[2],buff[3],buff[4],buff[5]);//CRC校驗
if(SHT3X_CRC(&buff[0],2)==buff[2] && SHT3X_CRC(&buff[3],2)==buff[5])
{
temp=(-45+(175.0 ((buff[0]<<8)+buff[1])/65535.0)) *10;
humi=10100* ((buff[3]<<8)+buff[4])/65535.0;
if(*temp>1250) *temp=1250;
else if(*temp<-400) *temp=-400;
return 0;
}
else return 1;
}
//SHT30初始化
void SHT30_Init()
{
IIC_Init();
}
sht30.h頭文件代碼如下:
#ifndef SHT30_H
#define SHT30_H
#include "main.h"
#define SHT30_ADDR (uint8_t)(0x44<<1) //sht30 i2c地址,ADDR管腳接低電平時為0x44,接高電平為0x45
//SHT30命令
#define SHT30_READ_HUMITURE (uint16_t)0x2c06 //讀溫濕度
//CRC多項式
#define POLYNOMIAL 0x31 // X^8 + X^5 + X^4 + 1
uint8_t SHT30_Read_Humiture(int *temp,uint16_t *humi);
void SHT30_Init(void);
#endif
8、在主程序中,我們把讀取到的數據顯示到LCD段碼屏上:
while(1)
{
SHT30_Read_Humiture(t,h);
temp = t[0];
Lcd_clear();
show_num(2, temp/100,0);
show_num(1, (temp/10)%10,1);
show_num(0, temp%10,0);
temp = h[0];
show_num(7, temp/100,0);
show_num(6, (temp/10)%10,1);
show_num(5, temp%10,0);
SysTickDelay(50000);
}
最后實現的效果如圖:
-
傳感器
+關注
關注
2550文章
51035瀏覽量
753071 -
lcd
+關注
關注
34文章
4424瀏覽量
167400
發布評論請先 登錄
相關推薦
評論