我正在尝试使用DSTH01来获取湿度和温度。但我无法得到正确的值。我的湿度为-24,温度为-50。我不知道我失踪的地方。请指导我解决我的问题。最初,如果我获得有助于解决我的问题的设备ID。我使用的是带有10 MHz晶振的PIC18f2520。
我已完成以下连接:
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++);
}
答案 0 :(得分:2)
更新我之前删除了这个答案,因为我认为它是错误和无用,但毕竟可能还有OP的内容。 ..
如何从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
&amp; 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
答案 1 :(得分:1)
谢谢你们的宝贵支持和建议。我已经离开了比特敲击方法。试过硬件功能。最后我得到了结果。这是代码段: -
i2c_start();
i2c_write(0x80); // Device address
i2c_write(0x11); // Data to device
i2c_start(); // Restart
i2c_write(0x81); // to change data direction
data=i2c_read(0); // Now read from slave
printf("\n\rID:%02X",data);
i2c_stop();