资讯详情

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

文章目录

    • 一,DHT11传感器介绍
    • 1.1简介
    • 1.2工作原理
    • 二、硬件连接
    • 三、时序代码
    • 3.1 一些宏的数据总时序和定义
    • 3.2主机发送起始信号
    • 3.3从机发送响应信号
    • 3.3读取数据
    • 3.5采样函数
    • 四,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;
}

五,结果

标签: 然后外接传感器等一些器件stm8外接传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台