找回密码
 立即注册

QQ登录

只需一步,快速开始

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

DHT11制作的温湿度计程序有错误,希望高手指教一下

[复制链接]
ID:701046 发表于 2020-4-3 20:41 | 显示全部楼层 |阅读模式
/*P0口段输出,P2口位控制,前两位数码管显示湿度,后三位显示温度,温度值为-19.9度至99.9度之间,显示负温度时要在前面加负号,小数点随温度变化要改变他的位置。下面程序数码管不显示,请高手指教!*/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define TEMP_MEASURE 0x03   //000 00011 测试温度命令
#define HUMI_MEASURE 0x05   //000 00101 测试温度命令

sbit DHT_DATA=P1^6;
sbit DHT_SCK=P1^7;

uchar code SEGMENT_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40,0x46,0x79,0x38,0x76};//0,1,2,3,4,5,6,7,8,9,熄灭,-,-1,E,L,H

uchar code BIT_CODE[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,0x3f,0xc7,0x00};

uchar wen,a,shan,tt,sec_point,shift,shi_12,shi_a,sec_point_flag,DHT_TIME,TEMP_LOW,TEMP_HIGH;

uchar k_d_s;

uchar  tab1[9];

uchar  tab2[9];

uchar DHT_L,DHT_H,DHT_ACK,DHT_ERROR;

unsigned  int  VALUE_TEMP,VALUE_HUMI,DIS_TEMP,DIS_HUMI;//湿度显示值

uchar TEMP_SIGNS;

uchar TEMP_L_BYTE,TEMP_H_BYTE,TEMP_DECIMAL;

/*************************************************
                 延时程序
**************************************************/
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=60;y>0;y--);
}

/*************************************************

         DHT61读高低两个字节,返回应答信号

**************************************************/

void DHT61_READ_TWO_BYTE()
{
  unsigned char i,val=0;
  DHT_L=0;
  DHT_H=0;
  DHT_DATA=1;                           //释放数据总线
  for (i=0x80;i>0;i/=2)             //位移8位
     { DHT_SCK=1;                          //上升沿读入
       if (DHT_DATA) val=(val | i);        //确定值  
       DHT_SCK=0;                                          
     }
  DHT_DATA=0;                        //读应答信号,有应答为1,无应答为0 通过CPU下拉为应答
  DHT_SCK=1;                            //第9个脉冲
   _nop_(); _nop_(); _nop_();          //pulswith approx. 5 us
  DHT_SCK=0;                                                   
  DHT_DATA=1;                           //释放数据总线
  DHT_H=val;
  val=0;

////低8位/////////////////////////////

  DHT_DATA=1;                           //释放数据总线
  for (i=0x80;i>0;i/=2)             //位移8位
     { DHT_SCK=1;                          //上升沿读入
       if (DHT_DATA) val=(val | i);        //确定值  
       DHT_SCK=0;                                          
     }
  DHT_DATA=1;//0;                        //不需要应答 通过CPU下拉为应答
  DHT_SCK=1;                            //第9个脉冲
   _nop_(); _nop_(); _nop_();          //pulswith approx. 5 us
  DHT_SCK=0;                                                   
  DHT_DATA=1;                           //释放数据总线
  DHT_L=val;

}

/**************************************************

           向DHT61写一个字节 返回应答信号

*****************************************************/
char WRITE_DHT61_BYTE(unsigned char value)
{
  unsigned char i ;
   DHT_ACK=0;  
  for (i=0x80;i>0;i/=2)             //释放数据总线
  { if (i & value) DHT_DATA=1;          //写入值
    else DHT_DATA=0;                        
    DHT_SCK=1;                          //上升沿写入
     _nop_(); _nop_(); _nop_();        //延时        
    DHT_SCK=0;
  }
  DHT_DATA=1;                           //释放数据总线
  DHT_SCK=1;                            //第9个脉冲
  if  (DHT_DATA==1) DHT_ACK=1;
                         //读应答信号
  DHT_SCK=0;        
  return DHT_ACK;                     //error=1 表示没有应答
}

/**************************

函数功能:DHT61启动时序

***************************/
void DHT_START(void)
{  
   DHT_DATA=1; DHT_SCK=0;                   //数据为1,SCK=0
    _nop_();
   DHT_SCK=1;                          //第一个脉冲
    _nop_();
   DHT_DATA=0;                         //数据跌落
    _nop_ ();
   DHT_SCK=0;                         //完成一个脉冲
    _nop_(); _nop_(); _nop_();
   DHT_SCK=1;                         //再一个脉冲
    _nop_();
   DHT_DATA=1;                        //数据变为1                  
    _nop_();
   DHT_SCK=0;                         //完成该脉冲                  
}

/**************************

       DHT61复位时序

***************************/
void DHT_RESET(void)

{  
  unsigned char i;
  DHT_DATA=1; DHT_SCK=0;                    //数据为1 时钟为0
  for(i=0;i<9;i++)                  //9 个脉冲为 复位
  { DHT_SCK=1;
    DHT_SCK=0;
  }
  DHT_START();                   //启动
}

/***********************************************

    DHT61测量温度或者是温度,返回校验值

***********************************************/
void DHT_MEASURE(unsigned char ml)
        {
                  DHT_START();                   //启动
                  WRITE_DHT61_BYTE(ml);//写入测温度
                 if (DHT_ACK==1)
                    {
                         DHT_RESET() ;//复位
                  WRITE_DHT61_BYTE(ml);//写入测温度
             }

  }
/**************************

     DHT61温度处理

/***************************/
void PROCESS_DHT_TEMP()
{
    float aa=0,bb=0,temp_zi;
        int   abcd=0;

aa=(float)DHT_H*256+(float)DHT_L;
temp_zi=0.01*aa-40;

if  (temp_zi<0)
    {TEMP_SIGNS=1;
         temp_zi=-temp_zi*10;
        VALUE_TEMP=(int)temp_zi;
        if(VALUE_TEMP>=200) TEMP_LOW=1;
        else TEMP_LOW=0;
    }
else {TEMP_SIGNS=0;
   temp_zi=temp_zi*10;
   VALUE_TEMP=(int)temp_zi;//给显示值
   }
   }
/**************************

      DHT61湿度处理

***************************/
void PROCESS_DHT_HUMI()
{
    float aa=0,bb=0,humi_zi;
        int   abcd=0;

aa=(float)DHT_H*256+(float)DHT_L;

bb=aa*aa*2.8/1000000;
aa=0.0405*aa;
aa=aa-4-bb;
humi_zi=aa;

if  (humi_zi>99.9)
    {
          humi_zi=99.9;
    }
    humi_zi=humi_zi*10;
   VALUE_HUMI=(int)humi_zi;
   }

/*************************************************
            万年历显示子程序
**************************************************/

void display()
{      
         
           
          DIS_HUMI=VALUE_HUMI;
          P0=SEGMENT_CODE[DIS_HUMI/100];
          P2=BIT_CODE[12];
         
                                      
          DIS_HUMI=DIS_HUMI%100;
          P0=SEGMENT_CODE[DIS_HUMI/10];
    P2=BIT_CODE[12];
         
          DIS_TEMP=VALUE_TEMP;
          DIS_TEMP=DIS_TEMP%1000;

          /* 下为修正负温度显示而加 可显示-19.9~99.9温度 下  */

        if(TEMP_SIGNS==1)                                                                                                  

          {
                        if((DIS_TEMP/100)==0)
                        
                        P0=SEGMENT_CODE[11];

                        if((DIS_TEMP/100)==1)

                        P0=SEGMENT_CODE[12];

                        if((DIS_TEMP/100)>1)

                        P0=SEGMENT_CODE[13];

          }
          /*   上 为修正负温度显示而加  可显示-19.9~99.9温度 上 */

          else
                        
                P0=SEGMENT_CODE[DIS_TEMP/100];
          P2=BIT_CODE[12];
         
   /* 为修正负温度显示而加  温度低于-20摄氏度时,显示E-L */
         
                if(TEMP_LOW==1)
                        {
                                P0=SEGMENT_CODE[11];         
                          P0=SEGMENT_CODE[14];
                        }
          else
                        {
                                DIS_TEMP=DIS_TEMP%100;
                                
                P0=SEGMENT_CODE[DIS_TEMP/10]|0x80;
                                
          DIS_TEMP=DIS_TEMP%10;
                                
          P0=SEGMENT_CODE[DIS_TEMP%10];
                        
                        }
                        
     P2=BIT_CODE[12];
           P0=SEGMENT_CODE[10];
           P2=BIT_CODE[12];
                }                        
         
/*************************************************
                   主程序
**************************************************/

void main()

{
        TMOD=1;
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        EA=1;
        ET0=1;
        TR0=1;
        shan=0x00;
        DHT_DATA=1;
        DHT_SCK=1;
        while(1)
        {
        }        
     DHT_ERROR=0;
           DHT_ACK=0;
     DHT_RESET() ;//复位
           DHT_MEASURE(TEMP_MEASURE);

        while (DHT_DATA)
          {
           }
    DHT61_READ_TWO_BYTE();//读温度
        PROCESS_DHT_TEMP();
    DHT_MEASURE(HUMI_MEASURE);
    while(DHT_DATA)
          {
          }
   DHT61_READ_TWO_BYTE();//读温度
   PROCESS_DHT_HUMI();
                  
        }
/*************************************************
            定时中断子程序
**************************************************/

        void time0() interrupt 1
{
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        display();
        tt++;
        sec_point++;
        if(tt==50)                        //设置闪烁
        {tt=0;
         shan=~shan;
         }
        if(sec_point==100)        //秒点闪烁
        {        sec_point=0;
                sec_point_flag=~sec_point_flag;
        }
}


截图00.png
回复

使用道具 举报

ID:701046 发表于 2020-4-7 15:19 | 显示全部楼层
自己顶一下!高手帮忙啊!
回复

使用道具 举报

ID:97249 发表于 2020-4-10 22:32 | 显示全部楼层
for (i=0x80;i>0;i/=2)             //释放数据总线  0x80十进制=128
{ DHT_SCK=1;                          //上升沿读入
       if (DHT_DATA) val=(val | i);        //确定值  
        DHT_SCK=0;                                          
      }
   DHT_DATA=0;                        //读应答信号,有应答为1,无应答为0 通过CPU下拉为应答
  DHT_SCK=1;                            //第9个脉冲
   _nop_(); _nop_(); _nop_();          //pulswith approx. 5 us
   DHT_SCK=0;                                                   
   DHT_DATA=1;                           //释放数据总线
  DHT_H=val;
   val=0;
表示看不懂你的代码
回复

使用道具 举报

ID:1064915 发表于 2024-2-23 17:36 | 显示全部楼层
c8ea15ce36d3d539b600177a2eccfe50352ac65c1a7d.webp.jpg d50735fae6cd7b892f8a3c200f2442a7d8330eaa.webp.jpg

//****************************************************************//
2
// DHT11使用范例
3
//单片机 : AT89S52 或 STC89C52RC
4
// 功能 :串口发送温湿度数据 波特率 9600
5
//硬件连接: P2.0口为通讯口连接DHT11,DHT11的电源和地连接单片机的电源和地,单片机串口加MAX232连接电脑
6
#include <reg51.h>
7
#include <intrins.h>
8
//
9
typedef unsigned char U8; /* defined for unsigned 8-bits integer variable 无符号8位整型变量 */
10
typedef signed char S8; /* defined for signed 8-bits integer variable 有符号8位整型变量 */
11
typedef unsigned int U16; /* defined for unsigned 16-bits integer variable 无符号16位整型变量 */
12
typedef signed int S16; /* defined for signed 16-bits integer variable 有符号16位整型变量 */
13
typedef unsigned long U32; /* defined for unsigned 32-bits integer variable 无符号32位整型变量 */
14
typedef signed long S32; /* defined for signed 32-bits integer variable 有符号32位整型变量 */
15
typedef float F32; /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
16
typedef double F64; /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
17
//
18
#define uchar unsigned char
19
#define uint unsigned int
20
#define Data_0_time 4
21
//--------------- --------------------//
22
//----------------IO口定义区--------------------//
23
//-------------- --------------------------//
24
sbit P2_0 = P2^0 ;//DATA
25
sbit P2_1 = P2^1 ;
26
sbit P2_2 = P2^2 ;
27
sbit P2_3 = P2^3 ;
28
//--------- ------------------------------------//
29
//----------------定义区--------------------//
30
//--------------------- -----------------------//
31
U8 U8FLAG,k;
32
U8 U8count,U8temp;
33
U8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
34
U8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
35
U8 U8comdata;
36
U8 outdata[5]; //定义发送的字节数
37
U8 indata[5];
38
U8 count, count_r=0;
39
U8 str[5]={"RS232"};
40
U16 U16temp1,U16temp2;
41
42
SendData(U8 *a)
43
{
44
    outdata[0] = a[0];
45
    outdata[1] = a[1];
46
    outdata[2] = a[2];
47
    outdata[3] = a[3];
48
    outdata[4] = a[4];
49
    count = 1;
50
    SBUF=outdata[0];
51
}
52
53
void Delay(U16 j)
54
{
55
    U8 i;
56
    for(;j>0;j--)
57
    {
58
        for(i=0;i<27;i++);
59
    }
60
}
61
62
void Delay_10us(void)
63
{
64
    U8 i;
65
    i--;
66
    i--;
67
    i--;
68
    i--;
69
    i--;
70
    i--;
71
}
72
73
void COM(void)
74
{
75
    U8 i;
76
    for(i=0;i<8;i++)
77
    {
78
    U8FLAG=2;
79
    //----------------------
80
    P2_1=0 ; //T
81
    P2_1=1 ; //T
82
    //----------------------
83
    while((!P2_0)&&U8FLAG++);
84
    Delay_10us();
85
    Delay_10us();
86
    // Delay_10us();
87
    U8temp=0;
88
    if(P2_0)U8temp=1;
89
    U8FLAG=2;
90
    while((P2_0)&&U8FLAG++);
91
    //----------------------
92
    P2_1=0 ; //T
93
    P2_1=1 ; //T
94
    //----------------------
95
    //超时则跳出for循环
96
    if(U8FLAG==1)break;
97
    //判断数据位是0还是1
98
    // 如果高电平高过预定0高电平值则数据位为 1
99
    U8comdata<<=1;
100
    U8comdata|=U8temp; //0
101
    }//rof
102
}
103
104
//------------  --------------------
105
//-----湿度读取子程序 ------------
106
//----------------------  ----------
107
//----以下变量均为全局变量--------
108
//----温度高8位== U8T_data_H------
109
//----温度低8位== U8T_data_L------
110
//----湿度高8位== U8RH_data_H-----
111
//----湿度低8位== U8RH_data_L-----
112
//----校验 8位 == U8checkdata-----
113
//----调用相关子程序如下----------
114
//---- Delay();, Delay_10us();COM();
115
//---------------------    -----------
116
void RH(void)
117
{
118
    //主机拉低18ms
119
    P2_0=0;
120
    Delay(180);
121
    P2_0=1;
122
    //总线由上拉电阻拉高 主机延时20us
123
    Delay_10us();
124
    Delay_10us();
125
    Delay_10us();
126
    Delay_10us();
127
    //主机设为输入 判断从机响应信号
128
    P2_0=1;
129
    //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
130
    if(!P2_0) //T !
131
    {
132
        U8FLAG=2;
133
        //判断从机是否发出 80us 的低电平响应信号是否结束
134
        while((!P2_0)&&U8FLAG++);
135
        U8FLAG=2;
136
        //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
137
        while((P2_0)&&U8FLAG++);
138
        //数据接收状态
139
        COM();
140
        U8RH_data_H_temp=U8comdata;
141
        COM();
142
        U8RH_data_L_temp=U8comdata;
143
        COM();
144
        U8T_data_H_temp=U8comdata;
145
        COM();
146
        U8T_data_L_temp=U8comdata;
147
        COM();
148
        U8checkdata_temp=U8comdata;
149
        P2_0=1;
150
        //数据校验
151
        U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
152
        if(U8temp==U8checkdata_temp)
153
        {
154
            U8RH_data_H=U8RH_data_H_temp;
155
            U8RH_data_L=U8RH_data_L_temp;
156
            U8T_data_H=U8T_data_H_temp;
157
            U8T_data_L=U8T_data_L_temp;
158
            U8checkdata=U8checkdata_temp;
159
        }//fi
160
    }//fi
161
}
162
163
//---------------------------------------
164
//main()功能描述: AT89C51 11.0592MHz 串口发
165
//送温湿度数据,波特率 9600
166
//----------------------------------------------
167
void main()
168
{
169
    U8 i,j;
170
    //uchar str[6]={"RS232"};
171
    /* 系统初始化 */
172
    TMOD = 0x20; //定时器T1使用工作方式2
173
    TH1 = 253; // 设置初值
174
    TL1 = 253;
175
    TR1 = 1; // 开始计时
176
    SCON = 0x50; //工作方式1,波特率9600bps,允许接收
177
    ES = 1;
178
    EA = 1; // 打开所以中断
179
    TI = 0;
180
    RI = 0;
181
    SendData(str) ; //发送到串口
182
    Delay(1); //延时100US(12M晶振)
183
    while(1)
184
    {
185
        //------------------------
186
        //调用温湿度读取子程序
187
        RH();
188
        //串口显示程序
189
        //--------------------------
190
        str[0]=U8RH_data_H;
191
        str[1]=U8RH_data_L;
192
        str[2]=U8T_data_H;
193
        str[3]=U8T_data_L;
194
        str[4]=U8checkdata;
195
        SendData(str) ; //发送到串口
196
        //读取模块数据周期不易小于 2S
197
        Delay(20000);
198
    }//elihw
199
}// main
200
201
void RSINTR() interrupt 4 using 2
202
{
203
    U8 InPut3;
204
    if(TI==1) //发送中断
205
    {
206
        TI=0;
207
        if(count!=5) //发送完5位数据
208
        {
209
            SBUF= outdata[count];
210
            count++;
211
        }
212
    }
213
    if(RI==1) //接收中断
214
    {
215
        InPut3=SBUF;
216
        indata[count_r]=InPut3;
217
        count_r++;
218
        RI=0;
219
        if (count_r==5)//接收完4位数据
220
        {
221
            //数据接收完毕处理。
222
            count_r=0;
223
            str[0]=indata[0];
224
            str[1]=indata[1];
225
            str[2]=indata[2];
226
            str[3]=indata[3];
227
            str[4]=indata[4];
228
            P0=0;
229
        }
230
    }
231
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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