STC89C52RC 单片机读取DHT22温湿度传感器串口显示程序调试经验总结

DHT22例程获取到的途径很多,某宝商家那里,本站也可以。附件下载例程代码

例程如下:

//****************************************************************//
//       DHT21使用范例 
//单片机 AT89S52 或 STC89C52RC 
//功能   串口发送温湿度数据 晶振 11.0592M 波特率 9600 
//硬件   P2.0口为通讯口连接DHT22,DHT22的电源和地连接单片机的电源和地,单片机串口加MAX232连接电脑 
//****************************************************************//

#include <reg51.h>
#include <intrins.h> 
typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable       无符号8位整型变量  */
typedef signed   char  S8;       /* defined for signed 8-bits integer variable          有符号8位整型变量  */
typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable       无符号16位整型变量 */
typedef signed   int   S16;      /* defined for signed 16-bits integer variable       有符号16位整型变量 */
#define uchar unsigned char
#define uint unsigned int
#define   Data_0_time    4

//----------------------------------------------//
//----------------IO口定义区--------------------//
//----------------------------------------------//
sbit  P2_0  = P2^0 ;

//----------------------------------------------//
//----------------定义区--------------------//
//----------------------------------------------//
U8  U8FLAG,k;
U8  U8count,U8temp;
U8  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
U8  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
U8  U8comdata;
U8  outdata[5];  //定义发送的字节数       
U8  indata[5];
U8  count, count_r=0;
U8 str[5]={"RS232"};
U16 U16temp1,U16temp2;
SendData(U8 *a)
{
    outdata[0] = a[0]; 
    outdata[1] = a[1];
    outdata[2] = a[2];
    outdata[3] = a[3];
    outdata[4] = a[4];
    count = 1;
    SBUF=outdata[0];
}

       void Delay(U16 j)
    {      U8 i;
        for(;j>0;j--)
      {     
        for(i=0;i<27;i++);

      }
    }
      void  Delay_10us(void)
      {
        U8 i;
        i--;
        i--;
        i--;
        i--;
        i--;
        i--;

       }
    
        void  COM(void)
      {     
            U8 i;         
       for(i=0;i<8;i++)       
        {     
               U8FLAG=2;    
           while((!P2_0)&&U8FLAG++);
            Delay_10us();
            Delay_10us();                
            Delay_10us();
              U8temp=0;
         if(P2_0)U8temp=1;
            U8FLAG=2;
         while((P2_0)&&U8FLAG++);
           //超时则跳出for循环          
            if(U8FLAG==1)break;
           //判断数据位是0还是1     
              
        // 如果高电平高过预定0高电平值则数据位为 1 
            
           U8comdata<<=1;
              U8comdata|=U8temp;        //0
         }//ro       
    }

    //--------------------------------
    //-----湿度读取子程序 ------------
    //--------------------------------
    //----以下变量均为全局变量--------
    //----温度高8位== U8T_data_H------
    //----温度低8位== U8T_data_L------
    //----湿度高8位== U8RH_data_H-----
    //----湿度低8位== U8RH_data_L-----
    //----校验 8位 == U8checkdata-----
    //----调用相关子程序如下----------
    //---- Delay();, Delay_10us();,COM(); 
    //--------------------------------

    void RH(void)
    {
      //主机拉低18ms 
       P2_0=0;
       Delay(180);
       P2_0=1;
     //总线由上拉电阻拉高 主机延时20us
       Delay_10us();
       Delay_10us();
       Delay_10us();
       Delay_10us();        
     //主机设为输入 判断从机响应信号 
       P2_0=1;
     //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行      
       if(!P2_0)         //T !      
       {
       U8FLAG=2;
     //判断从机是否发出 80us 的低电平响应信号是否结束     
       while((!P2_0)&&U8FLAG++);
       U8FLAG=2;
     //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
       while((P2_0)&&U8FLAG++);
     //数据接收状态         
       COM();
       U8RH_data_H_temp=U8comdata;
       COM();
       U8RH_data_L_temp=U8comdata;
       COM();
       U8T_data_H_temp=U8comdata;
       COM();
       U8T_data_L_temp=U8comdata;
       COM();
       U8checkdata_temp=U8comdata;
       P2_0=1;
     //数据校验 
     
       U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
       if(U8temp==U8checkdata_temp)
       {
             U8RH_data_H=U8RH_data_H_temp;
             U8RH_data_L=U8RH_data_L_temp;
          U8T_data_H=U8T_data_H_temp;
             U8T_data_L=U8T_data_L_temp;
             U8checkdata=U8checkdata_temp;
       }//fi
       }//fi

  }
    
//----------------------------------------------
//main()功能描述:  AT89C51  11.0592MHz     串口发 
//送温湿度数据,波特率 9600 
//----------------------------------------------
void main()
{    
    //uchar str[6]={"RS232"};
    /* 系统初始化 */
    TMOD = 0x20;      //定时器T1使用工作方式2
    TH1 = 253;        // 设置初值
    TL1 = 253;
    TR1 = 1;          // 开始计时
    SCON = 0x50;      //工作方式1,波特率9600bps,允许接收   
    ES = 1;
    EA = 1;           // 打开所以中断   
    TI = 0;
    RI = 0;
    SendData(str) ;   //发送到串口 
    Delay(10);         //延时100US(12M晶振)
    while(1)
    {  

       //------------------------
       //调用温湿度读取子程序 
       RH();
       //串口显示程序 
       //--------------------------

       str[0]=U8RH_data_H;
       str[1]=U8RH_data_L;
       str[2]=U8T_data_H;
       str[3]=U8T_data_L;
       str[4]=U8checkdata;
       
       SendData(str) ;  //发送到串口  
       //读取模块数据周期不宜小于 2S 
       Delay(20000);
    }//elihw
    
}// main

void RSINTR() interrupt 4 using 2
{
    if(TI==1) //发送中断      
    {
        TI=0;
        if(count!=5) //发送完5位数据     
        {
            SBUF= outdata[count];
            count++;
        }
    }


}

 

这个例程看起来是一点问题都没有的,但是我把程序烧录进单片机的时候,读出数据都是为00,也就是没有读出数据

仔细分析了一下,大概的猜到可能是通讯的时序出错误,才导致读出数据不正常。

所以,利用编译软件Keil5,把晶振频率调成与实物对应,我的是11.0592Mhz

以为Delay(u8);这个函数在通信时序中是做启动信号的延时,单位是毫秒,不便仿真观察。

所以,在主函数中找到Delay(2000);这个函数,断点执行这里一下。

可以看出,执行前后延时为6秒多一点,程序中本是想延时2秒的,可以大概的推算出,延时延长了原来的三倍。

所以 将void RH(void)这个函数中    Delay(180);改为    Delay(60);

在编译,烧录,就可以读出正确的数据了。

/撒花花
 

 

 

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值