我在试着用DSTH01测量湿度和温度。但是我不能得到正确的数值,我得到的湿度是-24,温度是-50。我不知道我在哪里失踪了。请引导我解决我的问题。最初,如果我得到了有助于解决问题的设备ID。我正在使用PIC18f2520和10兆赫晶体。
我已完成以下连接:
PIN1-GND
PIN2-Pull Up to 3.3 V with 10k- Microcontroller PIN_C3
PIN3 - Pull Up to 3.3 V with 10k-Microcontroller PIN_C4
PIN4 - Microcontroller PIN_A2
PIN5 - 3.3 V
这是我的源代码:
#define DSTH01_SCK PIN_C3
#define DSTH01_SDA PIN_C4
#define DSTH01_CSB PIN_A2
#define SDA_H output_high(DSTH01_SDA)
#define SDA_L output_low(DSTH01_SDA)
#define SCK_H output_high(DSTH01_SCK)
#define SCK_L output_low(DSTH01_SCK)
#define CS_H output_high(DSTH01_CSB)
#define CS_L output_low(DSTH01_CSB)
#define SlaveAddress 0x40
#define RegisterAddress0 0x00
#define RegisterAddress1 0x01
#define RegisterAddress2 0x02
#define RegisterAddress3 0x03
#define RegisterAddress11 0x11
void small_delay(void);
void I2C_START(void);
void I2C_STOP(void);
void I2C_WRITE(unsigned int8 Data);
int8 I2C_READ(void);
void I2C_ACK(unsigned int8 a);
int8 I2C_SEND(unsigned int8 SlaveAdd,unsigned int8 RegisterAdd,unsigned int8 *s);
int8 I2C_RECEIVE(unsigned int8 SlaveAdd,unsigned int8 RegisterAdd,unsigned int8 *s);
void Temperature_READ(unsigned int8 *s);
void RelativeHumidity_READ(unsigned int8 *s);
int1 Check_SDA(void);
unsigned int8 Ack;
unsigned int8 id;
unsigned int8 RelativeHumidity =0;
unsigned int8 Temperature =0;
unsigned int8 Start1=0x01;
unsigned int8 Start2=0x11;
void main(void)
{
set_tris_c(0x80);
delay_ms(100);delay_ms(100);
output_low(PIN_C3);
output_high(PIN_C4);
output_low(PIN_A2);
enable_interrupts(int_rda);
enable_interrupts(global);
delay_ms(100);delay_ms(100);
delay_ms(100);delay_ms(100);
delay_ms(100);delay_ms(100);
CS_L;
I2C_RECEIVE(SlaveAddress,RegisterAddress11,&id);
while (1)
{
RelativeHumidity_READ(&RelativeHumidity);
Temperature_READ(&Temperature);
delay_ms(100);delay_ms(100);
delay_ms(100);delay_ms(100);
delay_ms(100);delay_ms(100);
printf("\r\nRelativeHumidity:%d",RelativeHumidity);
printf("\tTemperature:%d",Temperature);
}
}
void I2C_START()
{
SDA_H;small_delay();
SCK_H;small_delay();
SDA_L;small_delay();
SCK_L;small_delay();
}
void I2C_STOP()
{
SDA_L;small_delay();
SCK_H;small_delay();
SDA_H;small_delay();
}
void I2C_WRITE(unsigned int8 Data)
{
unsigned int8 i;
for(i=0;i<8;i++)
{
if(Data&0x80)
{SDA_H;small_delay();}
else
SDA_L;small_delay();
SCK_H;small_delay();
SCK_L;small_delay();
Data<<=1;
}
SDA_H;small_delay();
SCK_H;small_delay();
//if(SDA==1)
if(Check_SDA()==1)
Ack=0;
else
Ack=1;
SCK_L;small_delay();
}
unsigned int8 I2C_READ()
{
unsigned int8 Data=0;
unsigned int8 i;
SDA_H;
for(i=0;i<8;i++)
{
SCK_L;small_delay();
SCK_H;small_delay();
Data<<=1;
//if(SDA==1)
if(Check_SDA()==1)
Data=Data+1;
}
SCK_L;small_delay();
return Data;
}
void I2C_ACK(unsigned int8 a)
{
if(a==0)
{SDA_L;small_delay();}
else
SDA_H;small_delay();
SCK_H;small_delay();
SCK_L;small_delay();
}
unsigned int8 I2C_SEND(unsigned int8 SlaveAdd,unsigned int8 RegisterAdd,unsigned int8 *s)
{
SlaveAdd=SlaveAdd<<1;
I2C_START();
I2C_WRITE(SlaveAdd);
if(Ack==0)
return 0;
I2C_WRITE(RegisterAdd);
if(Ack==0)
return 0;
I2C_WRITE(*s);
if(Ack==0)
return 0;
I2C_STOP();
return 1;
}
unsigned int8 I2C_RECEIVE(unsigned int8 SlaveAdd,unsigned int8 RegisterAdd,unsigned int8 *s)
{
SlaveAdd = SlaveAdd<<1;
I2C_START();
I2C_WRITE(SlaveAdd);
if(Ack==0)
return 0;
I2C_WRITE(RegisterAdd);
if(Ack==0)
return 0;
I2C_START();
I2C_WRITE(SlaveAdd+1);
if(Ack==0)
return 0;
*s=I2C_READ();
I2C_ACK(1);
I2C_STOP();
return 1;
}
void RelativeHumidity_READ(unsigned int8 *s)
{
unsigned int8 Status=1;
unsigned int8 RelativeHumidityH;
unsigned int8 RelativeHumidityL;
unsigned int16 RelHum;
I2C_SEND(SlaveAddress,RegisterAddress3,&Start1);
while(Status==1)
{
I2C_RECEIVE(SlaveAddress,RegisterAddress0,&Status);
}
I2C_RECEIVE(SlaveAddress,RegisterAddress1,&RelativeHumidityH);
I2C_RECEIVE(SlaveAddress,RegisterAddress2,&RelativeHumidityL);
RelHum=RelativeHumidityH;
RelHum=RelHum<<8;
RelHum+=RelativeHumidityL;
RelHum=RelHum>>4;
*s=RelHum/16-24;
}
void Temperature_READ(unsigned int8 *s)
{
unsigned int8 Status=1;
unsigned int8 TemperatureH;
unsigned int8 TemperatureL;
unsigned int16 Temp;
I2C_SEND(SlaveAddress,RegisterAddress3,&Start2);
while(Status==1)
{
I2C_RECEIVE(SlaveAddress,RegisterAddress0,&Status);
}
I2C_RECEIVE(SlaveAddress,RegisterAddress1,&TemperatureH);
I2C_RECEIVE(SlaveAddress,RegisterAddress2,&TemperatureL);
Temp=TemperatureH;
Temp<<=8;
Temp+=TemperatureL;
Temp>>=2;
*s=Temp/32-50;
}
int1 Check_SDA(void)
{
int1 a;
set_tris_c(0x90);//10010000,RX,0,0,SDA,0,0,0,0
small_delay();
if(input(DSTH01_SDA)){a =1; }
else{a = 0;}
set_tris_c(0x80);//10000000
small_delay();
return a;
}
void small_delay(void)
{
char a;
for(a = 0;a < 10;a++);
}
最佳答案
更新之前我删除了这个答案,因为我认为它是错误的和无用的,但也许这里有一些东西,为操作毕竟。。。
如何从unsigned
变量中获取负值?
查看DSTH01 data sheet,%相对湿度由(RH/16)-24
计算,这表明您的代码有一个不必要的行
RelHum=RelHum>>4; // remove this line
*s=RelHum/16-24;
接下来,数据表显示温度是由
(TEMP/32)-50
计算得出的,这表明您的代码还有一行不必要的代码Temp>>=2; // remove this line
*s=Temp/32-50;
假设您已正确读取I2C数据。
数据表在表6中有一个错误,显示湿度为11位。它在表8中也有一个错误,该错误不是显示温度,而是重复与表6中湿度相同的表。
我想你是在做额外的除法,因为数据表上说结果分别是12位和14位,但推断是数据是左对齐的,这就是为什么除法(实际上是移位)是必需的,但只有一次!我建议您按照数据表中的说明进行转换:使用
DATAh
&DATAl
,这些是右边的零填充。所以代码最好是RelHum = (RelHum >> 4) - 24; // div 16
*s = (unsigned int8)RelHum; // now cast to 8-bit
和
Temp = (Temp >> 5) - 50; // div 32
*s = (unsigned int8)Temp; // now cast to 8-bit
关于c - 如何获取DSTH01 I2C通信的设备ID?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29865514/