STM32学习—DHT11温湿度传感器采样驱动并用cjson格式上报

一,DHT11传感器介绍

1.1简介

DHT11温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。

1.2工作原理

DHT11 器件采用简化的单总线通信。单总线即只有一根数据线,系统中的数据交换、控制均由单总线完成。单总线通常要求外接一个约 5.1kQ的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。
DHT11原理图

二,硬件连接

DHT11采用的是一线协议,所以我采用的小熊座单片机中的PA5作为主机和从机的接口。
硬件连接

三,时序代码

3.1 数据总时序以及定义的一些宏

typedef struct w1_gpio_s
{
	GPIO_TypeDef      *group;
	uint16_t           pin;
}w1_gpio_t;

static w1_gpio_t W1Dat =          /*PA5 connect*/
{
		.group =GPIOA,
		.pin =GPIO_PIN_5,
};

#define W1DQ_Input()    \
{        \
    GPIO_InitTypeDef GPIO_InitStruct = {0}; \
    GPIO_InitStruct.Pin = W1Dat.pin; \
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT; \
    GPIO_InitStruct.Pull = GPIO_PULLUP; \
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; \
    HAL_GPIO_Init(W1Dat.group,&GPIO_InitStruct); \
}

#define W1DQ_Output()    \
{        \
    GPIO_InitTypeDef GPIO_InitStruct = {0}; \
    GPIO_InitStruct.Pin = W1Dat.pin; \
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; \
    GPIO_InitStruct.Pull = GPIO_NOPULL; \
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; \
    HAL_GPIO_Init(W1Dat.group,&GPIO_InitStruct); \
}

#define W1DQ_Write(x)  HAL_GPIO_WritePin(W1Dat.group,W1Dat.pin, \
		                                (x==1)?GPIO_PIN_SET:GPIO_PIN_RESET)

#define W1DQ_Read(x)  HAL_GPIO_ReadPin(W1Dat.group,W1Dat.pin)

在这里插入图片描述

3.2主机发送起始信号

在这里插入图片描述

static void DHT11_StartSignal(void)
{
    W1DQ_Output();
    /* 主机拉低 >=18ms*/
    W1DQ_Write(0);
    HAL_Delay(20);
    /*主机拉高 >=20~4Bus*/
    W1DQ_Write(1);
    delay_us(30);
    W1DQ_Input();
}

3.3从机发送应答信号

在这里插入图片描述

uint8_t DHT11_RespondSignal(void)
{
    uint8_t retry =0;

    /*总线变为低电平说明从设备发送了响应信号:80us*/
    while( W1DQ_Read() && retry < 100)
    {
        retry++;
        delay_us(1);
    }
    //delay_us(80);

    /*超时没有收到响应信号*/
    if(retry >= 100)
    {
        return 1;
    }
    /*从设备再把总线拉高表示从设备要发送数据了:80us*/
    retry = 0;
    while( !W1DQ_Read() && retry <100)
    {
        retry++;
        delay_us(1);
    }

    /*超时没有收到数据开始信号*/
    if(retry >= 100)
    {
        return 1;
    }
    //delay_us(80);

    return 0;
}

3.3读取数据

在这里插入图片描述

uint8_t DHT11_ReadBit(void) //读取一个位
{
    uint8_t retry = 0;

    /*从设备回复的每个位数据以低电平标置开始:50us*/
    while( W1DQ_Read() && retry<100)
    {
        retry++;
        delay_us(1);
    }
    //delay_us(50);

    /*数据位都用高电平表示,但高电平的长短决定了数据是1 or 0*/
    retry = 0;
    while( !W1DQ_Read() && retry< 100)
    {
        retry++;
        delay_us(1);
    }

    /*判断数据位是 1(70us) or 0(26~28us)*/
    delay_us(40);
    if( W1DQ_Read())
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

uint8_t DHT11_ReadByte(void) //读取一个字节返回值位采集值
{
	uint8_t    i,dat;

    dat = 0;
    for(i=0;i<8; i++)
    {
        dat <<= 1;
        dat |= DHT11_ReadBit(); //每速取到一个位放到最后一位
    }

    return dat;
}

3.5采样函数

int DHT11_SampleData(float *temperature, float *humidity)
{
    uint8_t    humi_H8bit;
    uint8_t    humi_L8bit;
    uint8_t    temp_H8bit;
    uint8_t    temp_L8bit;
    uint8_t    check_sum;

  if( !temperature || !humidity)
  {
       return -1;
  }
    /*主机发起起始信号并等到从设备的响应信号*/
    DHT11_StartSignal();
    if( 0 != DHT11_RespondSignal() )
    {
        return -2;
    }
    humi_H8bit = DHT11_ReadByte();
    humi_L8bit= DHT11_ReadByte();
    temp_H8bit = DHT11_ReadByte();
    temp_L8bit = DHT11_ReadByte();
    check_sum = DHT11_ReadByte();
    /*
    printf("humi_H8bit:[%d]\r\n",humi_H8bit);
    printf("humi_L8bit:[%d]\r\n",humi_L8bit);
    printf("temp_H8bit:[%d]\r\n",temp_H8bit);
    printf("temp_L8bit:[%d]\r\n",temp_L8bit);
    printf("CHECK:[%d]\r\n",check_sum);
    */
    if( (humi_H8bit+humi_L8bit+temp_H8bit+temp_L8bit) != check_sum )
    {
        return -3;
    }
    printf("[5]\r\n");
    *humidity =(humi_H8bit*100 + humi_L8bit) / 100.00;
    *temperature =(temp_H8bit*100 + temp_L8bit) / 100.00;
    return 0;
}

四,cjson打包数据

int report_dht11_json(void)
{
	char   buf[128];
	float  temperature,humidity;

	if( DHT11_SampleData(&temperature,&humidity)<0 )
    {
	    printf("ERROR: DHT11 Sample Data failure\r\n");
	    return -1;
	}

	memset(buf,0,sizeof(buf));
	snprintf(buf,sizeof(buf),"{\"Temperature\":\"%.2f\",\"Humidity\":\"%.2f\"}",temperature,humidity);

	HAL_UART_Transmit(&huart1,(uint8_t *)buf,strlen(buf),0xFFFF);

	return 0;
}

五,结果

在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值