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