140711 发表于 2023-3-27 17:20:19

DHT11, 一线制温湿度传感器参考程序


DHT11, 一线制温湿度传感器,读不出数据

#include <STC32G.H>
#include <intrins.H>
#include "LED8.h"
#define uchar unsigned char
#define uint unsigned int
      
sbit DATA=P1^3;
      
uchar DHT11_Data,Humanity,Temperature;
      
void DHT11_Start();
uchar Receive_Byte();
void DHT11_ReadData();
void delay_us(uchar xus);
void delay_ms(uint xms);

void main()
{
      P1M0 = 0x00; P1M1 = 0x00;
      delay_ms(1000);
      while(1)
      {
                DHT11_ReadData();
                Humanity=DHT11_Data*10+DHT11_Data;
                Temperature=DHT11_Data*10+DHT11_Data;
      
                LED8(3,Humanity/10);
                delay_ms(1);
                LED8(4,Humanity%10);
                delay_ms(1);
                LED8(7,Temperature/10);
                delay_ms(1);
                LED8(8,Temperature%10);
                delay_ms(1);
      }
}


void delay_ms(uint xms)      //@11.0592MHz
{
      uint i,j;
      for(i=xms;i>0;i--)
                for(j=110;j>0;j--);
}

void delay_us(uchar xus)                //@11.0592MHz
{
      while (--xus);
}

void DHT11_Start()
{
      DATA=1;                        //空闲状态为高电平
      delay_us(2);
      DATA=0;                        //主机发出开始信号,将总线拉低至少18ms
      delay_ms(20);
      DATA=1;                        //拉高总线并延时等待20--40us
      delay_us(30);
}

uchar Receive_Byte()      //读取一个字节数据
{
      uchar i,dat;
      for(i=0;i<8;i++)
      {
                while(DATA==0);      //等待数据低电平部分过去
                delay_us(8);      //延时50us,若DATA还为高电平则为数据1,否则为数据0
                dat<<=1;
                if(DATA==1)
                {
                        dat|=0x01;
                }
                while(DATA==1);      //等待此帧数据高电平完全过去
      }
      return dat;
}

void DHT11_ReadData()
{
      uchar H1,H2,T1,T2,check,Humanity_H,Humanity_L,Temperature_H,Temperature_L;
      DHT11_Start();                //主机发出开始信号
      if(DATA==0)                        //DHT11响应信号
      {
                while(DATA==0);      //DHT11响应信号,80us
                delay_us(40);      //DHT11响应信号,拉高延时80us,准备输出
                H1=Receive_Byte();
                H2=Receive_Byte();
                T1=Receive_Byte();
                T2=Receive_Byte();
                check=Receive_Byte();
                delay_us(25);      //当一次数据传输完成后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
                if((H1+H2+T1+T2)==check)      //数据检验
                {
                        Humanity_H=H1;
                        Humanity_L=H2;
                        Temperature_H=T1;
                        Temperature_L=T2;
                }
                DHT11_Data=Humanity_H/10;
                DHT11_Data=Humanity_H%10;
                DHT11_Data=Humanity_L/10;
                DHT11_Data=Humanity_L%10;
                DHT11_Data=Temperature_H/10;
                DHT11_Data=Temperature_H%10;
                DHT11_Data=Temperature_L/10;
                DHT11_Data=Temperature_L%10;
      }
}

//这是主函数,从C52那里改的

140711 发表于 2023-3-27 17:20:55

#ifndef__LED8_H__
#define __LED8_H__
#define uchar unsigned char
#define uint    unsigned int
       
void LED8(uchar i,j);

#endif
//LED8.h

140711 发表于 2023-3-27 17:21:24

#include <STC32G.H>
#define uchar unsigned char
#define uint    unsigned int
sbit P2_4=P2^4;
sbit P2_3=P2^3;
sbit P2_2=P2^2;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void LED8(uchar i,j)
{
        switch(i)       
        {
                case 1:P2_4=1;P2_3=1;P2_2=1;break;
                case 2:P2_4=1;P2_3=1;P2_2=0;break;
                case 3:P2_4=1;P2_3=0;P2_2=1;break;
                case 4:P2_4=1;P2_3=0;P2_2=0;break;
                case 5:P2_4=0;P2_3=1;P2_2=1;break;
                case 6:P2_4=0;P2_3=1;P2_2=0;break;
                case 7:P2_4=0;P2_3=0;P2_2=1;break;
                case 8:P2_4=0;P2_3=0;P2_2=0;break;
        }
        P0=table;
}
//LED8.c

140711 发表于 2023-3-27 17:22:45

能通过编译,但是没有数据,不知道问题在哪

电子DIY小家 发表于 2023-3-27 20:06:02

延时时间不对,STC32G的速度比89c52快了几十倍,延时的时间也要相应修改。

这俩函数用ISP软件从新生成一下,先自己动手试试,要实在不会我明天写个给你好了。

神农鼎 发表于 2023-3-27 20:20:09

冲哥是天山上的来客,高风亮节,路见不平,拔刀相助了:)




DHT11_百度百科 (baidu.com)

这是STC89C52RC的代码,即使是对的,软件模拟通信也要加延时



神农鼎 发表于 2023-3-27 20:23:41








神农鼎 发表于 2023-3-27 20:29:32

下面这个是网上看到的STC15的参考程序,也是要加延时啊 :
#include<STC15.H>
#include "intrins.h"//用于提供_nop_();函数
#include "OLED_Contrul_Hygrothermograph.c"//OLED控制函数

sbit YLED=P3^1;
sbit RLED=P3^0;
sbit DHT=P3^5;//DHT11模块

unsigned int Temperature={1,1,1};//前两位为整数部分,后一位为小数部分
unsigned int Humidity={1,1};//传回的湿度数据只有整数部分

unsigned char Data_Receive;
/*##############################################################################################
设计名称:基于DHT11的温湿度计(Hygrothermograph)
设计者:清河

平台:STC15F104W
硬件部分
显示:采用OLED12864显示温度和湿度
测量,采用DHT11模块,模块信息如下:
ASATR
-----
NA:DHT11
OC:3.3-5.5V
U1:5-95%RH
U2:-20-60℃
U3:±5%RH±2℃
SN:A1712882A

为保证延时准确,晶振设置为12MHz

##############################################################################################*/

void Delay30us()//@12.000MHz
{
      unsigned char i;
      i=87;
      while(--i);
}

void Delay20ms()//@12.000MHz
{
      unsigned char i,j,k;
      i=1;
      j=234;
      k=113;
      do
      {
                do
                {
                        while(--k);
                }while(--j);
      }while(--i);
}

void Delay1s()//@12.000MHz
{
      unsigned char i,j,k;
      i=46;
      j=153;
      k=245;
      do
      {
                do
                {
                        while(--k);
                }while(--j);
      }while(--i);
}

void OLED_Display()//OLED显示驱动函数
{
      OLED_DataDisplay_T(56,4,Temperature);//在指定位置显示温度
      OLED_DataDisplay_H(56,6,Humidity);//在指定位置显示湿度
}

void DHT_Collect()//温度采集函数
{
      unsigned char i,j;//for循环变量
      unsigned char t;//超时判断
      unsigned char dat8=0;//一次读取的8位数据,需要读5次
      unsigned int CheckValue=0;//校验和
      
      DHT=0;//主机发起始信号
      Delay20ms();//主机拉低总线至少18ms
      DHT=1;//主机拉高总线20~40us
      Delay30us();
      
      t=80;//设置超时等待时间
      while(DHT&&t--);//等待DHT11拉低总线
      if(t==0)//超时
      {
                DHT=1;
      }
      t=250;//设置超时等待时间
      while(!DHT&&t--);//等待DHT11拉高总线
      if(t==0)//超时
      {
                DHT=1;
      }
      t=250;//设置超时等待时间
      while(DHT&&t--);//等待DHT11拉低总线
      if(t==0)//超时
      {
                DHT=1;
      }

      for(j=0;j<5;j++)//5次读取
      {
                for(i=0;i<8;i++)//1次8个位
                {
      //等待50us开始时隙
                        t=150;//设置超时等待时间
                        while(!DHT&&t--);//等待DHT11拉高总线
                        if(t==0)//超时
                        {
                              DHT=1;
                        }
                        t=0;//记录时间清零
                        while(DHT&&++t);//等待并记录高电平持续时间
                        dat8<<=1;
                        if(t>30)//高电平持续时间较长(70us)
                        dat8+=1;//传输值为1
                }
                Data_Receive=dat8;
      }
      
      Delay30us();//等待DHT11拉低50us
      Delay30us();
      DHT=1;

      for(i=0;i<4;i++)
      {
                CheckValue+=Data_Receive;//计算校验值
      }
      if((unsigned char)CheckValue==Data_Receive)//比对
      {
                Temperature=Data_Receive/10;
                Temperature=Data_Receive%10;
                Temperature=Data_Receive%10;
                Humidity=Data_Receive/10;
                Humidity=Data_Receive%10;
      }
}

void sys_init()//系统初始化函数
{
      YLED=1;
      RLED=1;
      OLED_Init(); //OLED初始化
      OLED_CLS();//清屏
      
      OLED_FormTitle(0,0);//显示标题文字Linyar Lab.
      OLED_FormName(0,2);//显示Hygrothermograph名称
      OLED_FormLine(0,3);//显示一条横线
      OLED_FormTemp(8,4);//显示温度文字
      OLED_FormHumi(16,6);//显示湿度文字
      OLED_AnyChar_16X16(96,4,TempChar);//在行4(每行高16像素),列96像素位置显示摄氏度℃字符
      OLED_AnyChar_8X16(88,6,HumiChar);//在行6(每行高16像素),列88像素位置显示百分号%字符
      OLED_AnyChar_8X16(72,4,PointChar);//在行4(每行高16像素),列72像素位置显示冒号:字符
}

void main()
{
      P3M0=0X00;
      P3M1=0X00;
      sys_init();
      
      while(1)
      {
                DHT_Collect();//DHT11数据采集
                YLED=1;RLED=0;//灯状态转换
                OLED_Display();//OLED显示函数
                RLED=1;YLED=0;//灯状态转换
                Delay1s();
                Delay1s();//注意:长时间的延时必须要有,不然会读出0
      }
}

140711 发表于 2023-3-28 10:33:40

电子DIY小家 发表于 2023-3-27 20:06
延时时间不对,STC32G的速度比89c52快了几十倍,延时的时间也要相应修改。

这俩函数用ISP软件从新生成一下 ...

感谢回复,已经写出来了

神农鼎 发表于 2023-3-28 10:49:16

帮忙将 【DHT11 + STC32G12K128】 调试通过的程序上传上来,方便后续新人学习:)
页: [1] 2 3 4 5
查看完整版本: DHT11, 一线制温湿度传感器参考程序