找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5627|回复: 3
收起左侧

DHT11温湿度传感器测得的温湿度都是00?求解答

[复制链接]
ID:685767 发表于 2020-4-19 20:24 | 显示全部楼层 |阅读模式
2黑币
显示出来是这样的
JQ5~MWOZQ7PP[$RJYQ8YD6G.png


这是主函数:
  1. #include <reg52.h>
  2. #include "LCD1602.h"
  3. #include "stdio.h"

  4. unsigned char str1[2],str2[2];

  5. bit flag1s = 0;          //1s定时标志
  6. unsigned char T0RH = 0;  //T0重载值的高字节
  7. unsigned char T0RL = 0;  //T0重载值的低字节

  8. void ConfigTimer0(unsigned int ms);

  9. extern void UartDriver();
  10. extern void ConfigUART(unsigned int baud);
  11. extern void UartRxMonitor(unsigned char ms);
  12. extern void UartWrite(unsigned char *buf, unsigned char len);
  13. extern unsigned char RH_data,TH_data;

  14. void main ()
  15. {
  16.     EA = 1;            //开总中断
  17.     ConfigTimer0(1);   //配置T0定时1ms
  18.     ConfigUART(9600);  //配置波特率为9600
  19.     InitLcd1602();     //初始化液晶

  20.     DHT11_start();
  21.     LcdShowStr(0,0,"Humi:");
  22.     LcdShowStr(0,1,"Temp:");
  23.     while (1)
  24.     {
  25.         UartDriver();  //调用串口驱动

  26.         if(flag1s)
  27.         {
  28.             flag1s=0;
  29.             DHT11_receive();
  30.             str1[0]=(char)(0x30+RH_data/10); //湿度整数部分
  31.             str1[1]=(char)(0x30+RH_data%10);                                
  32.             str2[0]=(char)(0x30+TH_data/10); //温度整数部分
  33.             str2[1]=(char)(0x30+TH_data%10);     
  34.             LCD_Write_Char(6,0,str1[0]);
  35.             LCD_Write_Char(7,0,str1[1]);
  36.             LcdShowStr(9,0,"%");

  37.             LCD_Write_Char(6,1,str1[0]);
  38.             LCD_Write_Char(7,1,str1[1]);
  39.             LcdShowStr(9,1,"C");
  40.         }

  41.     }
  42. }

  43. /* 串口动作函数,根据接收到的命令帧执行响应的动作
  44.    buf-接收到的命令帧指针,len-命令帧长度 */
  45. void UartAction(unsigned char *buf, unsigned char len)
  46. {
  47.   //  buf[len++] = '\r';  //有效命令被执行后,在原命令帧之后添加
  48.   //  buf[len++] = '\n';  //回车换行符后返回给上位机,表示已执行
  49. //   UartWrite(buf, len);
  50. //UartWrite(buf, len);
  51. }

  52. /* 配置并启动T0,ms-T0定时时间 */
  53. void ConfigTimer0(unsigned int ms)
  54. {
  55.     unsigned long tmp;  //临时变量
  56.    
  57.     tmp = 11059200 / 12;      //定时器计数频率
  58.     tmp = (tmp * ms) / 1000;  //计算所需的计数值
  59.     tmp = 65536 - tmp;        //计算定时器重载值
  60.     tmp = tmp + 32;           //补偿中断响应延时造成的误差
  61.     T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
  62.     T0RL = (unsigned char)tmp;
  63.     TMOD &= 0xF0;   //清零T0的控制位
  64.     TMOD |= 0x01;   //配置T0为模式1
  65.     TH0 = T0RH;     //加载T0重载值
  66.     TL0 = T0RL;
  67.     ET0 = 1;        //使能T0中断
  68.     TR0 = 1;        //启动T0
  69. }
  70. /* T0中断服务函数,执行串口接收监控和蜂鸣器驱动 */
  71. void InterruptTimer0() interrupt 1
  72. {
  73.     static unsigned char tmr1s = 0;
  74.     TH0 = T0RH;  //重新加载重载值
  75.     TL0 = T0RL;
  76.     UartRxMonitor(1);  //串口接收监控
  77.     tmr1s++;
  78.     if (tmr1s >= 100)  //定时1s
  79.     {
  80.         tmr1s = 0;
  81.         flag1s = 1;
  82.     }
  83. }

  84. 这是DHT11程序:

  85. #include "DHT11.h"

  86. //sbit Temp_data=P2^1;

  87. unsigned char RH_data,TH_data;

  88. unsigned int rec_dat[4];
  89. //DHT11起始信号

  90. void DHT11_delay_us(unsigned char n)
  91. {
  92.     while(--n);
  93. }

  94. //延时ms
  95. void DHT11_delay_ms(unsigned int z)
  96. {
  97.    unsigned int i,j;
  98.    for(i=z;i>0;i--)
  99.       for(j=110;j>0;j--);
  100. }

  101. void DHT11_start()   
  102. {
  103.     Temp_data=1;
  104.     DHT11_delay_us(2);
  105.     Temp_data=0;
  106.     DHT11_delay_ms(20);
  107.     Temp_data=1;   
  108.     DHT11_delay_us(13);
  109.    
  110. }

  111. //接收一个字节
  112. unsigned char DHT11_rec_byte()
  113. {   
  114.     unsigned char i,dat;
  115.     for(i=0;i<8;i++)
  116.     {
  117.             while(!Temp_data);
  118.           DHT11_delay_us(8);
  119.             dat<<=1;
  120.             if(Temp_data==1)
  121.             {
  122.                 dat+=1;
  123.             }
  124.             while(Temp_data);
  125.     }
  126.     return dat;
  127. }

  128. //接收温湿度数据
  129. void DHT11_receive()
  130. {
  131.     unsigned int R_H,R_L,T_H,T_L;
  132.     unsigned char RH,RL,TH,TL,revise;
  133.    
  134.     DHT11_start();
  135.     Temp_data=1;
  136.     if(Temp_data==0)
  137.     {
  138.         while(Temp_data==0);   //等待拉高     
  139.         DHT11_delay_us(40);  //拉高后延时80us
  140.         
  141.         R_H=DHT11_rec_byte();    //接收湿度高八位  
  142.         R_L=DHT11_rec_byte();    //接收湿度低八位  
  143.         T_H=DHT11_rec_byte();    //接收温度高八位  
  144.         T_L=DHT11_rec_byte();    //接收温度低八位
  145.         revise=DHT11_rec_byte(); //接收校正位

  146.         DHT11_delay_us(25);    //结束

  147.         if((R_H+R_L+T_H+T_L)==revise)      //校正
  148.         {
  149.             RH=R_H;
  150.             RL=R_L;
  151.             TH=T_H;
  152.             TL=T_L;
  153.    
  154.         }
  155.         /*数据处理,方便显示*/
  156.      /*   rec_dat[0]=RH;
  157.         rec_dat[1]=RL;
  158.         rec_dat[2]=TH;
  159.         rec_dat[3]=TL;*/

  160.         RH_data=RH;
  161.         TH_data=TH;
  162.     }
  163. }
  164. 这是Uart.c程序:

  165. #include <reg52.h>

  166. bit flagFrame = 0;  //帧接收完成标志,即接收到一帧新数据
  167. bit flagTxd = 0;    //单字节发送完成标志,用来替代TXD中断标志位
  168. unsigned char cntRxd = 0;   //接收字节计数器
  169. unsigned char pdata bufRxd[64];  //接收字节缓冲区

  170. extern void UartAction(unsigned char *buf, unsigned char len);

  171. /* 串口配置函数,baud-通信波特率 */
  172. void ConfigUART(unsigned int baud)
  173. {
  174.     SCON  = 0x50;  //配置串口为模式1
  175.     TMOD &= 0x0F;  //清零T1的控制位
  176.     TMOD |= 0x20;  //配置T1为模式2
  177.     TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
  178.     TL1 = TH1;     //初值等于重载值
  179.     ET1 = 0;       //禁止T1中断
  180.     ES  = 1;       //使能串口中断
  181.     TR1 = 1;       //启动T1
  182. }
  183. /* 串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度 */
  184. void UartWrite(unsigned char *buf, unsigned char len)
  185. {
  186.     while (len--)  //循环发送所有字节
  187.     {
  188.         flagTxd = 0;      //清零发送标志
  189.         SBUF = *buf++;    //发送一个字节数据
  190.         while (!flagTxd); //等待该字节发送完成
  191.     }
  192. }
  193. /* 串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度 */
  194. unsigned char UartRead(unsigned char *buf, unsigned char len)
  195. {
  196.     unsigned char i;
  197.    
  198.     if (len > cntRxd)  //指定读取长度大于实际接收到的数据长度时,
  199.     {                  //读取长度设置为实际接收到的数据长度
  200.         len = cntRxd;
  201.     }
  202.     for (i=0; i<len; i++)  //拷贝接收到的数据到接收指针上
  203.     {
  204.         *buf++ = bufRxd[i];
  205.     }
  206.     cntRxd = 0;  //接收计数器清零
  207.    
  208.     return len;  //返回实际读取长度
  209. }
  210. /* 串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔 */
  211. void UartRxMonitor(unsigned char ms)
  212. {
  213.     static unsigned char cntbkp = 0;
  214.     static unsigned char idletmr = 0;

  215.     if (cntRxd > 0)  //接收计数器大于零时,监控总线空闲时间
  216.     {
  217.         if (cntbkp != cntRxd)  //接收计数器改变,即刚接收到数据时,清零空闲计时
  218.         {
  219.             cntbkp = cntRxd;
  220.             idletmr = 0;
  221.         }
  222.         else                   //接收计数器未改变,即总线空闲时,累积空闲时间
  223.         {
  224.             if (idletmr < 30)  //空闲计时小于30ms时,持续累加
  225.             {
  226.                 idletmr += ms;
  227.                 if (idletmr >= 30)  //空闲时间达到30ms时,即判定为一帧接收完毕
  228.                 {
  229.                     flagFrame = 1;  //设置帧接收完成标志
  230.                 }
  231.             }
  232.         }
  233.     }
  234.     else
  235.     {
  236.         cntbkp = 0;
  237.     }
  238. }
  239. /* 串口驱动函数,监测数据帧的接收,调度功能函数,需在主循环中调用 */
  240. void UartDriver()
  241. {
  242.     unsigned char len;
  243.     unsigned char pdata buf[40];

  244.     if (flagFrame) //有命令到达时,读取处理该命令
  245.     {
  246.         flagFrame = 0;
  247.         len = UartRead(buf, sizeof(buf));  //将接收到的命令读取到缓冲区中
  248.         UartAction(buf, len);  //传递数据帧,调用动作执行函数
  249.     }
  250. }
  251. /* 串口中断服务函数 */
  252. void InterruptUART() interrupt 4
  253. {
  254.     if (RI)  //接收到新字节
  255.     {
  256.         RI = 0;  //清零接收中断标志位
  257.         if (cntRxd < sizeof(bufRxd)) //接收缓冲区尚未用完时,
  258.         {                            //保存接收字节,并递增计数器
  259.             bufRxd[cntRxd++] = SBUF;
  260.         }
  261.     }
  262.     if (TI)  //字节发送完毕
  263.     {
  264.         TI = 0;   //清零发送中断标志位
  265.         flagTxd = 1;  //设置字节发送完成标志
  266.     }
  267. }

复制代码

回复

使用道具 举报

ID:584814 发表于 2020-4-20 11:23 | 显示全部楼层
理论上讲,程序抄来抄去不应该有问题,查器件或连线试试。
回复

使用道具 举报

ID:393699 发表于 2020-4-22 15:47 | 显示全部楼层
重点抓下延时函数有没有问题,有条件的上个示波器或逻辑分析仪看下时序就知道了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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