我看那么多人问DHT11源码,这个校验不对,那个数据不对,干脆发出来了。与STM32 PB15对接,觉得好请打赏,节省你2天时间啊!
#include "dht11.h"
#include "bsl.h"
static void pin_config(int is_out)
{
int set=0;
static int status=0;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 ;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
if(is_out){
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
}else{
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
}
/* pb15=temperature sensor */
if( is_out && status!=1){
set = 1;
status = 1;
}
else if(!is_out && status!=2){
status = 2;
set = 1;
}
if(set)
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
static void write_pin(int is_high)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_15,is_high?Bit_SET: Bit_RESET);
}
static uint8_t read_pin(void)
{
return (!!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15));
}
/* DHT11输出0、1信号的低电平时间相同,而高电平的时间不同,输出
* 0信号时高电平约26-28us,而当输出1信号时高电平约为70us。
*/
static uint8_t dht_read_byte(void)
{
uint8_t i,temp=0;
uint16_t tick,time_out;
for(i=0;i<8;i++)
{
/* 等待变起始低电平50us */
SET_TICKUS(tick);
//SET_TICKUS(time_out);
while( read_pin() == 1){
//if(GET_DIFF_TICKUS(time_out) > 90)
//return 0;
}
/* 等待变高电平出真正数据 */
SET_TICKUS(time_out);
while( read_pin() == 0){
//if(GET_DIFF_TICKUS(time_out) > 60)
//return 0;
}
delay_xus(40);
/* 此时再判断高电平,仍然为高就是1.仍然为高的话,留给下一次等待判断变低(50us开始) */
temp <<= 1;
if(read_pin() == 1){
temp |= 1;
}
}
return temp;
}
/*
* @temp:高字节为温度整数,低字节为小数。
* @shidu:高字节为湿度整数,低字节为小数。
*/
int dht_read_data(uint16_t *temp,uint16_t *shidu)
{
uint16_t count,sum,temp_int,temp_dec,shi_int,shi_dec;
if(temp==NULL || shidu==NULL)
return -250;
/* 主机设为输出模式 */
pin_config(1);
/* 主机拉低,至少拉低18ms */
write_pin(0);
delay_xms(20);
/* 主机拉高 20-40us,dht检测变低后就开始送数据 */
write_pin(1);
delay_xus(30);
/* 主机设置为输入模式,此时dht11变低 */
pin_config(0);
while(read_pin()== 1){} /* 等待拉低80us */
//if(read_pin()== 0)
//{
SET_TICKUS(count);
/* 等待DHT11拉高80us */
while(read_pin()== 0){
if(GET_DIFF_TICKUS(count) > 100)
return -1;
}
/* 此时dht11开始拉高80us,然后拉低50us出数据了 */
/* 等待DHT11置高80us
SET_TICKUS(count);
while(read_pin()== 1){
if(GET_DIFF_TICKUS(count) > 100)
return -2;
}*/
/* DHT11以低电平应答主机,然后拉高总线准备输出。
* 数据格式:8bit湿度整数数据+8bit湿度小数数据(目前保留=0)
* +8bit温度整数数据+8bit温度小数数据(目前保留=0)
* +8bit校验和
*/
shi_int = dht_read_byte();
shi_dec = dht_read_byte();
temp_int = dht_read_byte();
temp_dec = dht_read_byte();
sum = dht_read_byte();
/*读取结束,将主机设为输出模式*/
pin_config(1);
write_pin(1);
/*检查读取的数据是否正确*/
if(sum==(temp_int+temp_dec+shi_int+shi_dec)){
*temp = (temp_int<<8) | temp_dec;
*shidu = (shi_int<<8) | shi_dec;
return 0;
}
else
return -3;
//}
//else
//return -4;
}关键就是读字节那里,先|=1跟后|=1是差1倍的问题,还有各种各样的问题,大家要注意了!