DHT11温湿度传感器 & STM32f103zet6

DHT11简介:

DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。

DHT11与DS1B8B20的时序有相似之处,但相对来说简单许多。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先发。 DHT11 的数据格式为: 8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数部分+8bit 校验和。其中校验和数据为前面四个字节相加。DHT11 和 MCU 的一次通信最大为 34ms 左右,建议主机连续读取时间间隔不要小于 2s。

工作时序:

首先主机发送开始信号,从机发出响应信号。然后开始数据传输,数据传输包括:湿度、温度、校验位。

起始信号以及响应信号:
 主机拉低总线,保持低电平时间20ms,然后释放总线,保持时间10-35us,DHT11拉低数据线78-88us,然后拉高数据线,延时87us,开始传输数据。

 读时序:

 读0和读1的区别在与高电平延长的时间不同。

代码:

DHT11.h

#define DHT11_GPIO_PORT         GPIOB
#define DHT11_GPIO_PIN          GPIO_PIN_13
#define DHT11_CLK_ENABLE()      do{__HAL_RCC_GPIOB_CLK_ENABLE();}while(0)

#define DHT11_OUT(x)            do{x?\
                                    HAL_GPIO_WritePin(DHT11_GPIO_PORT,DHT11_GPIO_PIN,GPIO_PIN_SET):\
                                    HAL_GPIO_WritePin(DHT11_GPIO_PORT,DHT11_GPIO_PIN,GPIO_PIN_RESET);\
                                    }while (0)
                  
 #define DHT11_Read             HAL_GPIO_ReadPin(DHT11_GPIO_PORT,DHT11_GPIO_PIN)                                   
DHT11.c

/**
 * @brief       初始化DHT11相关IO口, 并使能时钟
 * @param       无
 * @retval      无
 */
void DHT11_init()
{
    GPIO_InitTypeDef gpio_init_struct;
    DHT11_CLK_ENABLE();
    gpio_init_struct.Pin = DHT11_GPIO_PIN;                
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;            
    gpio_init_struct.Pull = GPIO_PULLUP;                   
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;      
    HAL_GPIO_Init(DHT11_GPIO_PORT, &gpio_init_struct);      
}

/**
 * @brief       主机发送开始信号
 * @param       无
 * @retval      无
 */
void DHT11_Start()
{
    DHT11_OUT(0);
    delay_ms(20);
    DHT11_OUT(1);
    delay_us(13);
}

/**
 * @brief       检测DHT11是否发生响应
 * @param       无
 * @retval      0:表示成功相应,1:表示相应失败
 */
uint8_t DHT11_Check()
{
    uint8_t retry,rval=0;
    while(DHT11_Read && retry<100)  /*判断DHT11没有把总线拉低*/
    {
        retry++;
        delay_us(1);
    }
    if (retry>=100)
    {
        rval=1;
    }
    else
    {
        retry=0;
        while(!DHT11_Read && retry<100)     /*判断DHT11没有把总线拉高*/
        {
            retry++;
            delay_us(1);
        }
        if (retry>=100) rval=1;
    }
    return rval;
}
/**
 * @brief       从DHT11读取一个位
 * @param       无
 * @retval      0:表示成功相应,1:表示相应失败
 */
uint8_t DHT11_Read_bit()
{
    uint8_t retry=0;
    while(DHT11_Read && retry<100)  
    {
        retry++;
        delay_us(1);
    }
    retry=0;
    while(!DHT11_Read && retry<100)     
    {
        retry++;
        delay_us(1);
    } 
     /*数字0还是1,延长的时间大于数字0的时间小于数字1的时间*/
    delay_us(40);
    if (DHT11_Read) 
    {
        return 1;
    }
    else{
        return 0;
    }
}
/**
 * @brief       从DHT11读取一个字节
 * @param       无
 * @retval      读到的数据data
 */
uint8_t DHT11_Read_Byte()
{
    uint8_t i,data=0;
    for (i=0;i<8;i++)
    {
        data<<=1;   /*变量data向左移1位,结果仍保存在data中*/
        data|=DHT11_Read_bit();
    }
    return data;
}
/**
 * @brief       从DHT11读取一次数据
 * @param       temp:温度值(-20~60)
 * @param       hum:湿度值:(5%~95%)
 * @retval      0:表示成功相应,1:表示相应失败
 */
uint8_t DHT11_Read_data()
{
    uint8_t buf[5]={0}; /*将获得数据储存到数组中*/
    uint8_t i;
    uint8_t temp=0;
    uint8_t hum=0;
    DHT11_Start();
    if (DHT11_Check() == 0)
    {
        for ( i = 0; i < 5; i++)
        {
            buf[i]=DHT11_Read_Byte();
        }
        /*校验监测数据是否正确*/
        if (buf[0]+buf[1]+buf[2]+buf[3]==buf[4])
        {
            hum=buf[0];
            temp=buf[2];
        }
        /*通过串口输出*/
        printf("T:%d H:%d\r\n",temp,hum);
    }
    else{
        return 1;
    }
    return 0;
}


 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值