找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5529|回复: 6
收起左侧

51单片机,使用DHT11模块,程序卡死的问题

[复制链接]
ID:332895 发表于 2019-11-13 23:02 | 显示全部楼层 |阅读模式
20黑币

楼主大四,在做一个基于 51 的智能晾衣架,其中分别使用了 DS18B20、DHT11 检测温、湿度,温度检测正常,在 dht11 的程序里,通过调试发现程序卡死了,在主函数里读不出数据,也无法执行后面的程序,单片机型号是 STC 90C52RC ,晶振 11.0592M Hz ,延时函数使用烧录软件生成,之前参考了这篇文章 http://www.51hei.com/bbs/dpj-162117-1.htmldht11和ds18b20温湿度控制 单片机程序。 烧录在大二购买的51学习模块【巫妖王】12 MHz 可以正常运行,但是烧录在自己焊接的板子上就出问题了,一度怀疑自己焊接有问题,调了几天,累了,遂寻求帮助 。



1、原理图及PCB

原理图.png

PCB.png



2、DHT11代码
"dht11.h"

  • #ifndef __DHT11_H_  
  • #define __DHT11_H_  

  • #include <reg52.h>
  • #include"wifi.h"
  • #include<delay.h>

  • #ifndef uchar
  • #define uchar unsigned char
  • #endif

  • #ifndef uint
  • #define uint unsigned int
  • #endif

  • sbit DATA=P3^6; //温湿度传感器DHT11数据接入端

  • extern uchar dht11_data[5];         //存储湿度数组

  • void DHT11_receive();

  • #endif  



"dht11.c"
  • #include"dht11.h"

  • uchar dht11_data[5];         //存储湿度数组

  • //1-检测到响应信号 0-未检测到
  • uchar DHT11RstAndCheck()
  • {
  •         uchar timer = 0;
  •         
  •         EA = 0;
  •         DATA = 0;
  •         delay20ms();
  •         DATA = 1;
  •         delay30us();
  •         while(!DATA)
  •         {
  •                   timer++;
  •                         _nop_();
  •         }
  •         if(timer>100 || timer<20)
  •         {
  •                  EA = 1;
  •                  return 0;
  •         }
  •         timer = 0;
  •         while(DATA)
  •         {
  •                         timer++;
  •                         _nop_();
  •         }
  •         EA = 1;
  •         if(timer>100 || timer<20)
  •         {
  •                 return 0;
  •         }
  •         return 1;
  • }

  • /*********************************************************************************************
  • 函数名:DHT11读数据函数
  • 调  用:? = DHT11_rec_byte();
  • 参  数:无
  • 返回值:
  • 结  果:读DHT11数据并保存到dat
  • 备  注:
  • **********************************************************************************************/
  • uchar DHT11_rec_byte()      //接收一个字节
  • {
  •    uchar i,dat=0;
  •          EA = 0;
  •          for(i=0;i<8;i++)    //从高到低依次接收8位数据
  •    {         
  •                   while(DATA);
  •       while(!DATA);   ////等待50us低电平过去
  •                                         delay40us();
  •       dat<<=1;           //左移位使正确接收8位数据,数据为0时直接移位
  •       if(DATA)    //数据为1时,使dat加1来接收数据1
  •                         {
  •          dat |= 0x01;
  •                         }
  •       while(DATA);  //等待数据线拉低   
  •     }  
  •           EA = 1;
  •     return dat;
  • }

  • /*********************************************************************************************
  • 函数名:接收DHT11的40位的数据并校验
  • 调  用:? = DHT11_receive();
  • 参  数:无
  • 返回值:无
  • 结  果:结果保存到strx
  • 备  注:
  • **********************************************************************************************/
  • void DHT11_receive()                 
  • {
  •           uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
  •           EA=0;
  •     DATA=1;                                 // 主线空闲状态
  •                         delay10us();
  •     DATA=0;                                 // 主机发送开始工作信号
  •                         delay20ms();   //延时18ms以上
  •     DATA=1;                                 // 拉高并延时等待DHT11响应
  •                         delay30us();
  •           DATA = 1;
  •     if(DHT11RstAndCheck())
  •     {        
  •                                         delay80us();             //拉高后延时80us
  •                                 R_H = DHT11_rec_byte();  //接收湿度高八位
  •                                 R_L = DHT11_rec_byte();  //接收湿度低八位
  •                                 T_H = DHT11_rec_byte();  //接收温度高八位
  •                                 T_L = DHT11_rec_byte();  //接收温度低八位
  •                     revise = DHT11_rec_byte();     //接收校正位
  •                           
  •                           DATA = 0;
  •                     delay40us();    //结束
  •                     DATA = 1;
  •                                 if((R_H+R_L+T_H+T_L)==revise)           //数据校验
  •                                 {
  •                                                 RH=R_H;
  •             RL=R_L;
  •             TH=T_H;
  •             TL=T_L;
  •                                 }
  •                  
  •         /*数据处理,方便显示*/
  •         dht11_data[0]='0'+(RH/10);
  •         dht11_data[1]='0'+(RH%10);
  •         dht11_data[2]='0'+(TH/10);
  •         dht11_data[3]='0'+(TH%10);
  •                                 dht11_data[4]=RH;        
  •                                 send_table[20]=dht11_data[0];
  •                                 send_table[21]=dht11_data[1];
  •                 }
  • }   


3、焊接及显示内容
焊接.jpg



显示.jpg
回复

使用道具 举报

ID:639532 发表于 2019-11-15 17:55 | 显示全部楼层
程序我就不看了,给你个思路,一般会你这现象的原因有:1,单片机的中断标志没清,导致程序一直跑中断,不运行主函数;2,中断的等级没处理好,有些函数被更高级别的中断阻塞了;3,用了一些空指针,程序跑飞了;4,内存占满了;5,某些寄存器会在某些行为(比如触发中断)后自动清0,导致你的配置被清了;6,你所使用的单片机这一方面性能不稳定(这个可能非常小这么多年就见过一次,原厂fae都解决不了)

评分

参与人数 1黑币 +5 收起 理由
Eli_ + 5 赞一个!

查看全部评分

回复

使用道具 举报

ID:245004 发表于 2019-11-15 22:47 | 显示全部楼层
84行到88行的代码不合适吧?对照数据手册看看。单片机时钟必须跟延时函数一致;延时函数尽量放在当前c文件里,不要放在其它文件里;以下代码仅供参考:
io_DHT11 = 0;                 //主机拉低 >18ms
        Delay25ms();
        io_DHT11 = 1;                //20~40us后从机应答拉低电平
        Delay60us();                 //延时大于(20~40us)
        if(io_DHT11 == 0)         //判断从机是否响应
        {
                if (DHT11_WaitLevelChange(0) == isNo) return isNo;        //规定时间内电平0是否改变?如果未改变返回isNo
                if (DHT11_WaitLevelChange(1) == isNo) return isNo;        //规定时间内电平1是否改变?如果未改变返回isNo

                i = 0;
                ucArrTemp[i++] = DHT11_ReadByte();
                ucArrTemp[i++] = DHT11_ReadByte();
                ucArrTemp[i++] = DHT11_ReadByte();
                ucArrTemp[i++] = DHT11_ReadByte();
                ucArrTemp[i]   = DHT11_ReadByte();


评分

参与人数 1黑币 +5 收起 理由
Eli_ + 5 赞一个!

查看全部评分

回复

使用道具 举报

ID:123289 发表于 2019-11-16 09:17 | 显示全部楼层
关键点:
1、不要用DEALY做延时。
2、等待硬件信号时,要做限时动作,等不到就返回,并标记异常通知主程序。

评分

参与人数 1黑币 +5 收起 理由
Eli_ + 5 赞一个!

查看全部评分

回复

使用道具 举报

ID:647620 发表于 2019-11-23 02:16 | 显示全部楼层
想知道楼主解决了吗?
。。。表示碰到了一样的问题 。。把dht11拔了 别的都正常,插上dht11就卡住了  感觉上好像是卡在某个while里面了。。。。。。。作为一个初学者毫无头绪
回复

使用道具 举报

ID:647620 发表于 2019-11-23 02:21 | 显示全部楼层
对了还有个现象 卡住以后 湿度高位不知道为什么变成了255.。。
回复

使用道具 举报

ID:647620 发表于 2019-11-23 18:57 | 显示全部楼层
楼主数据线设的P3^6 可是 没有把端口设置成开漏,可以设置一下试试 。我今天把sda换到P0口  程序不至于卡死了。。虽然取值还不对 。感觉之前卡死是因为从机没法置低导致开在while判断上了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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