找回密码
 立即注册
查看: 5438|回复: 28

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

[复制链接]

该用户从未签到

3

主题

19

回帖

135

积分

注册会员

积分
135
发表于 2023-3-27 17:20:19 | 显示全部楼层 |阅读模式

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[8],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[0]*10+DHT11_Data[1];
                Temperature=DHT11_Data[4]*10+DHT11_Data[5];
        
                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[0]=Humanity_H/10;
                DHT11_Data[1]=Humanity_H%10;
                DHT11_Data[2]=Humanity_L/10;
                DHT11_Data[3]=Humanity_L%10;
                DHT11_Data[4]=Temperature_H/10;
                DHT11_Data[5]=Temperature_H%10;
                DHT11_Data[6]=Temperature_L/10;
                DHT11_Data[7]=Temperature_L%10;
        }
}

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

回复 送花

使用道具 举报

该用户从未签到

3

主题

19

回帖

135

积分

注册会员

积分
135
 楼主| 发表于 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

该用户从未签到

3

主题

19

回帖

135

积分

注册会员

积分
135
 楼主| 发表于 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[j];
}
//LED8.c

该用户从未签到

3

主题

19

回帖

135

积分

注册会员

积分
135
 楼主| 发表于 2023-3-27 17:22:45 | 显示全部楼层
能通过编译,但是没有数据,不知道问题在哪
  • TA的每日心情
    开心
    14 小时前
  • 签到天数: 90 天

    [LV.6]常住居民II

    38

    主题

    986

    回帖

    6771

    积分

    荣誉版主

    冲哥视频教程和各种开源资料QQ交流群884047237,可群

    积分
    6771
    QQ
    发表于 2023-3-27 20:06:02 | 显示全部楼层
    延时时间不对,STC32G的速度比89c52快了几十倍,延时的时间也要相应修改。
    1.png
    这俩函数用ISP软件从新生成一下,先自己动手试试,要实在不会我明天写个给你好了。
    回复 支持 1 反对 0 送花

    使用道具 举报

    该用户从未签到

    550

    主题

    9235

    回帖

    1万

    积分

    管理员

    积分
    13946
    发表于 2023-3-27 20:20:09 | 显示全部楼层
    冲哥是天山上的来客,高风亮节,路见不平,拔刀相助了:)
    1.png


    1.png
    DHT11_百度百科 (baidu.com)
    2.png
    这是STC89C52RC的代码,即使是对的,软件模拟通信也要加延时



    该用户从未签到

    550

    主题

    9235

    回帖

    1万

    积分

    管理员

    积分
    13946
    发表于 2023-3-27 20:23:41 | 显示全部楼层
    1.png

    2.png
    3.png
    4.png
    5.png
    6.png

    该用户从未签到

    550

    主题

    9235

    回帖

    1万

    积分

    管理员

    积分
    13946
    发表于 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[3]={1,1,1};//前两位为整数部分,后一位为小数部分
    unsigned int Humidity[2]={1,1};//传回的湿度数据只有整数部分

    unsigned char Data_Receive[5];
    /*##############################################################################################
    设计名称:基于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[j]=dat8;
            }
            
            Delay30us();//等待DHT11拉低50us
            Delay30us();
            DHT=1;

            for(i=0;i<4;i++)
            {
                    CheckValue+=Data_Receive;//计算校验值
            }
            if((unsigned char)CheckValue==Data_Receive[4])//比对
            {
                    Temperature[0]=Data_Receive[2]/10;
                    Temperature[1]=Data_Receive[2]%10;
                    Temperature[2]=Data_Receive[3]%10;
                    Humidity[0]=Data_Receive[0]/10;
                    Humidity[1]=Data_Receive[0]%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
            }
    }
    回复 支持 1 反对 0 送花

    使用道具 举报

    该用户从未签到

    3

    主题

    19

    回帖

    135

    积分

    注册会员

    积分
    135
     楼主| 发表于 2023-3-28 10:33:40 | 显示全部楼层
    电子DIY小家 发表于 2023-3-27 20:06
    延时时间不对,STC32G的速度比89c52快了几十倍,延时的时间也要相应修改。

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

    感谢回复,已经写出来了

    点评

    那就是调通了  详情 回复 发表于 2023-3-28 15:42

    该用户从未签到

    550

    主题

    9235

    回帖

    1万

    积分

    管理员

    积分
    13946
    发表于 2023-3-28 10:49:16 | 显示全部楼层
    帮忙将 【DHT11 + STC32G12K128】 调试通过的程序上传上来,方便后续新人学习:)
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-4-29 23:37 , Processed in 0.075299 second(s), 70 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表