|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于51单片机的dht11温湿度数码管显示proteus仿真与程序源码
+ Y. B6 T/ v7 M4 P' u+ Q4 _ D& c. T8 \5 J1 q; D& G z7 P8 s& V
! f1 g' k1 T8 f$ W. k+ {: K. ~
仿真原理图如下
1 h7 ~6 f4 V1 ]- H$ b
2 H1 j$ G7 M( f2 Y+ G& \. k; V! e% m& p' b% |( _" U' S0 H
按button1可以切换模式6 s$ B$ e) C+ W8 }8 z2 Z: ^5 w( ?
模式0 只显示温度
" f9 f- j* P. ?6 P2 b0 \$ e模式1 只显示湿度
2 H" L) g6 w5 q4 h+ N7 a模式2 动态显示温度和湿度,每5s切换一次# d- G& [) |" m9 A7 E
: X( c1 V# |* j' Y# O$ v) T Y1 Q$ I6 x L( i! r/ K
实物如下
7 f" F) E! y% R; S! G! m温度显示. S+ `! K* {& n4 d4 {
0 C) R4 H3 }3 o, g8 P5 G+ \! x! }湿度显示 小数
! K0 Y" a8 c+ Y2 ~: [ & O1 H- Y' U) S5 L
3 i/ B" e6 h# O- l& M- v+ _( s
$ `1 {$ p) K9 w9 C6 {模式选择,自动显示切换湿度和温度,只显示温度,只显示湿度。+ p! J" a# f' W3 ], B8 K
$ o& @9 h4 ^+ _
单片机源程序如下:
' {* y' e. S; k# V, Q#include<reg51.h>
8 `- H, P( c8 N6 b' _# {
# `2 X h, n' b- f7 d: ]( ?% o" ^, O8 w' P l
bit DHT_Start(); p7 K1 e( U0 T9 o; u7 c
bit DHT_ByteRead(unsigned char *dat);- T' U/ Q- ^! _. [9 p
void ConfigTimer0(unsigned int ms);
9 F1 O9 S4 M- Z8 xvoid Display_hum(unsigned char *num);
5 q3 w$ x4 h' U9 b# jvoid Display_temp(unsigned char *num);
) K- j& h8 k+ E O$ t% u1 p; z1 ]+ Q9 f. w: H# ^
/ s/ R h5 [' N' L p
! P. [/ l9 J- i+ B) ?0 v4 a. E2 O3 d, V: |1 y5 t5 l
unsigned char T0RH = 0; //T0重载值的高字节0 I: ]' ?: `" {5 c& m6 v
unsigned char T0RL = 0; //T0重载值的低字节 3 D, ]* ?: h7 W
unsigned char str=88;
; j) c$ V I9 b+ M4 b$ nunsigned char DHT[5];. |. Y) }; n: x( N
+ y' W5 n0 d2 u* ~# K
; U' [6 h3 ^: L
unsigned int tmr1s = 0;
3 R! o7 h9 g$ Y. V- dunsigned int tmr10ms = 0;2 C2 P2 z; d& Y+ F" `. U( K# k1 g$ J
unsigned char st=0;
5 n3 u: I( Q0 k( {$ zunsigned int sdd=0;
% S, S( G& y( A# W4 i9 munsigned char td=0;- G7 u" W% M5 J6 U' X2 Y
unsigned char mode=0;
+ K$ y$ ~0 a w! j; n
! v7 R% \1 Q% f; V! U% `
8 F1 Y! h' C; N" S! n k# K; tbit flag1s = 0;
# l& r0 q2 ?" N+ z2 h v$ Tbit flag10ms = 0; 7 W! H1 h) ~% D! T+ A$ b6 J
int x;
a# _5 w8 } W4 E0 `$ u7 T" | 8 Q( I! u% U% J. ~* W! @ Z
sbit button1=P0^0;
y5 L, {3 x% P' l# Tsbit dot=P1^3; //数码管小数点
( O/ l# n* a0 A; x' d& Y4 j5 r
U5 M% H) D+ ~' p; e6 Q
* i. D, B# s8 B$ m4 d) ?" j+ V) k/ m, w. A* j$ i
5 ^9 \ V) u3 L$ C9 q8 d; g; O/ F
void delay(unsigned char x) //延时ms* H R4 p( I7 t( f+ u. p& V
{
: d+ {8 s# i: \& M5 A2 S unsigned char a,b,c;
3 ~) l# S5 S9 ~( s$ n9 l for(c=x;c>0;c--)1 g& B$ B" S+ b( `8 x$ h
{' u8 d7 ~, A& _9 P4 p3 V
for(b=102;b>0;b--)3 r# t4 r9 j% W$ l* o
for(a=3;a>0;a--);1 q5 x- J3 p' ]; c3 o
}
5 G' G: j5 O4 z}
( b9 R% a$ L4 u( `2 O/ w; H4 r4 R$ X! hvoid main() 0 S, r% u/ u% F/ m( Q5 [1 m `2 \
{ ; a2 U' M9 a7 N) a+ R& R, Y* j
8 u7 D/ l9 ]3 b, q7 j. }3 r. y
6 k+ o8 E+ p! T9 f8 P0 ` bit tmp;
" w+ K4 ?$ c; j+ }- v* v4 I% Q dot=0;
6 c, V: A& `# A EA = 1; //开总中断
% I) x3 ~* {9 V0 ~3 B% h' { d4 J ConfigTimer0(10); //T0定时10ms
2 G' n( h0 R; D4 P// M1=0; M1=0;M2=0;M3=0;D1=0;D2=0;2 {, l2 u! K& w6 W _. v+ K4 n
DHT_Start();3 B) m) t' m/ ?8 ~" R
delay(5);+ `3 P8 t* ?/ h, k) S
& j P' G7 @7 F# ]
9 A, f' H5 d0 G: t0 ` V
while (1)
5 P1 _& A8 T, M& }+ d! w3 I7 K {% N0 q% k5 ^; ]# V r
4 X; M* h% Z5 ?* W" |
" B. k* r5 f8 n# [4 j7 j- B' E: d
3 B! M% F9 }3 g
if(flag10ms) //数码管刷新频率
' y' X1 k$ P0 B" I }* ^9 b {! S- `6 K ]' o. X- b |/ B4 X) j
if(st==0){" g8 V# A7 ~8 {5 R# Y9 w/ Z3 W
Display_temp(&str);
2 l; a0 P5 W4 s( N flag10ms=0; j2 p. H5 o2 s
}
' y/ X; D0 u7 S+ \ else if(st==1)3 }! ?1 P! b* O$ ~4 B0 F
{
; G# d1 n9 [( K! t( W Display_hum(&str);8 t4 N: e% ?' Y, e; j |
flag10ms=0;
# T, O. ?, u2 G Q) b" V/ b G }
* Y+ I( k% g$ Z
+ L: S p, c2 ]
% A9 q' J8 ~ I2 ?$ e8 U3 b
0 W; R5 X3 P) m" I u) [; [) f
" ]! N& i' r5 R }
" O* _. c: C! ]$ h/ _1 E' S else if (flag1s) //每秒更新一次温度、湿度8 W# f) Y u' x6 i- i$ y
{1 e/ o/ _9 t8 P! D7 z- s0 m: \
DHT_Start();- q( D V+ l/ Z. P* @
tmp=DHT_ByteRead(&DHT);9 ^+ Q. }# M6 [# U
if(tmp==1)2 _0 n# q5 z6 C0 w6 G+ `3 H
{
* ]! ?( C* C% O& F; \. y- X0 {# L( o" l' X3 w/ U. B
9 X6 E$ @4 W1 Y. H* H- L# P
if(st==0)8 k& u6 a0 _! G$ T( W
{5 o0 F" D$ a$ p8 E$ H5 n
str = DHT[2] ; //温度. T# _9 e0 p u ], ^* ~
Display_temp(&str); * |& h: W. l: I- F9 q# x$ j, v4 Z
flag1s =0; //标志位清零
3 b6 b$ U- O, s; Z }, C7 m+ u8 k, b$ K5 i; a8 t
else if(st==1){4 _; e& ?- j% z; j+ {
- q6 I g; w2 ^; d# X, \9 j
8 s9 d) V1 H3 o str = DHT[0] ; //湿度
2 V; R! t( k# x5 S9 b Display_hum(&str); 6 T, u# W$ p3 [
flag1s =0; //标志位清零' p! E6 M/ c/ \' P7 o7 ~' k1 P
} x: K0 a$ q( x4 |6 j# E( e
* o: Q$ a3 z# y9 t) y4 y* v
% v y& w/ a8 f7 R
9 i8 d$ b: w I
6 O4 |2 t& W* a3 u8 m
+ m, d9 g7 i; ]! I( Z+ P. c& U }
9 z/ v6 }1 i2 O& |2 Q }
0 L$ l" C' q6 ~; W if(button1==0)
# C. I/ i0 S; ~( U4 O" h( D: B {6 p! E/ E0 _/ {9 N7 h
delay(2);
1 z4 K+ g0 e* R' L3 Y
# X% h2 \0 A& C0 r if(button1==0)' u7 U( t# R% ]6 ? C
{
/ L9 a. x. o6 K# N2 a; j y! P$ ] . P3 S$ {4 m0 K: T
mode++;1 }8 p: ?8 e4 v
switch(mode)- a8 a: y* w/ H: t2 w
{
3 d0 k' i4 s- i5 D case 0: st=0; break;
2 X: i" I) q; h4 d3 H case 1: st=1; break;
- g1 c/ ^% w7 _ case 2: td=1; break;. l: Y5 j/ c5 Q5 T" R
default: break;8 Y/ T) X @0 v6 s2 _" Q
}3 K O& k! u7 D- ^/ P. H- w
if(mode>=3)
" T4 t" ^8 B' J) O* W5 E$ f {, E# r$ W& N9 v5 y2 [' b0 |
td=0;6 d; W8 V% D0 H# v3 M: Q6 u q' |9 z
mode=0;
5 \7 @) E! s5 ~* ]& A$ ~4 r6 N }# Y5 t# q1 g; Q
while(button1==0)
% O3 _9 X) q! _ d* x {
{0 O# R2 z, l+ L) b. @$ m2 R }* e9 `) |# J& B; L& F b
- b& I# M9 ]: n8 A; [) m8 w% b1 ?6 ]1 O+ Z0 Q. Y W
. W# E/ V& s2 a
% j+ }; ^" B, g8 p# z }0 d( K/ D9 N; e' a' g
3 m7 z/ _8 _, f6 S
" W! P: ~! P' ? }
2 ~! E- K; l4 g8 }" P
. X: {" u' _ n' q, `4 m' K! r9 w" g! k7 e q1 f
6 J: d6 B$ b9 v& b) o, J9 s5 r3 j% }( J; C' k9 z
. s- u5 r; q* v* U8 ` f
" l2 H- P( \' d }* ]3 [. U4 ^) |2 K% Q6 I" o6 \
}
/ J4 n( ]. `7 U( E7 b( P. \$ E1 X3 x% n" z8 o/ K' C
" d! B& e9 ]+ b! c1 O
4 a j; N4 E9 ^# E: h9 W6 p3 U# }
3 O5 Q2 \ S2 b8 F7 D/* 配置并启动T0,ms-T0定时时间 */# y0 s8 O7 j1 y" i! L, Z |
void ConfigTimer0(unsigned int ms)5 z$ e" I% u% r- l
{7 ` l0 ^# s5 ^8 C8 f* t% v
unsigned long tmp; //临时变量
+ l+ y% v: H* y . a, t6 o0 _& p9 I1 ^) G4 `' {
tmp = 11059200 / 12; //定时器计数频率
$ n# W0 L% _$ c! j) B$ c4 E tmp = (tmp * ms) / 1000; //计算所需的计数值+ c6 @' I4 z# s0 A& D- C" _. V6 N
tmp = 65536 - tmp; //计算定时器重载值+ H# U. e3 t4 U- e# C" U2 x9 D [' L' S
tmp = tmp + 12; //补偿中断响应延时造成的误差0 x3 d- u$ d, b r
T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
% b5 Z7 e0 y/ _" ^( f* o) j# r T0RL = (unsigned char)tmp;
* ~8 [8 i2 T2 Q! w! X: a- _, t+ [ TMOD &= 0xF0; //清零T0的控制位
) n# I/ Q5 V" { TMOD |= 0x01; //配置T0为模式1
' F3 @5 S4 [" ?: D; M TH0 = T0RH; //加载T0重载值- w" F0 J1 @ \8 h0 D5 A. S R
TL0 = T0RL;
, m% c% T. T- g6 u ET0 = 1; //使能T0中断
/ F& _( p* j2 I7 Z0 g" M* Q2 X TR0 = 1; //启动T0, s0 _' n( A1 E1 L
}
; I6 G. P# M t: I) `! r; @& O/ N4 C/* T0中断服务函数,完成1秒定时 */$ r0 q' D, A6 t" g6 t2 W* D% l
void InterruptTimer0() interrupt 1
+ G7 j7 o$ X ~" t: ]4 R8 I9 J{
7 Q5 i" [$ F+ Q" Y9 Z- L- \7 }. T. p& p ?& U! h2 U* E
& R2 ~5 W* V0 o6 s: N2 \! ` TH0 = T0RH; //重新加载重载值
& [/ V7 m9 D. U2 Z* m/ \- ^ TL0 = T0RL;
' U. q5 a; L* y8 D% f; Y: }! F tmr1s++;0 P; i2 X. N& v
sdd++;$ n1 ~- |! o5 W. ]% V3 z
tmr10ms++;/ {& f& |! G. V" j) ?! F) M9 U: R
" [1 D7 ~/ J$ c& A& \/ u& g
* n1 B( r y& d/ f if(tmr10ms>=1) // 数码管刷新频率% c6 E4 f9 \+ J9 T* c5 R* [
{# \ X) ]' `5 Z! z4 {
tmr10ms=0;
* E8 V) d0 O* O! j C flag10ms = 1;8 Z5 L0 c* A2 p
}
. C6 L, ^/ t: m( c# S0 k; |7 o if(td==1)
! ]/ @: T! r- Q+ k! ^. Y7 D {& }5 d( O% P# N K; R- a3 N9 e
if(sdd>=500) //温度显示5s 、湿度显示5s8 u; t) j2 A1 ^3 t& s3 \
{
/ |( f" ~2 \7 I% L5 e( s, Q sdd=0;6 Q4 U7 e2 K4 e( _
if(st==0)( K9 E) f4 `# X0 |
{/ ^# _8 s, g7 {5 M" g# @: X
st=1;) |0 R# e$ b! N! W
}) B+ @9 ?$ ?* i% ?
else st=0;
1 h8 P2 o1 K4 }9 A3 I. Z }; T/ C4 Z' L* |6 s8 W
}6 t( r5 ~ ~" m
if (tmr1s >= 200) //1s 数据更新频率* f+ w9 ~; j) r- h
{/ y( V A( P2 a, s
tmr1s = 0;
5 A1 }! T% l. `0 U. a flag1s = 1;( N" A9 \9 h! H; V' ^, V$ d" g
}
, }; e" m$ \: g/ w8 A
9 f, q# m9 L( s, `! Z2 b
. x( X2 z1 _9 u! {. A: T' ^ R ! G: v8 l& T* Y k8 N6 q
}3 a7 I, b! `6 y
0 K+ f4 o( E9 P% n: e
. I. i4 k: Z) M1 a! j, s6 s+ V下载:. v( R; L; ^$ k% i( l
& p( g9 G8 i4 V& x: O ?
" {" h/ C2 G8 h+ f) |
|
|