|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于51单片机的dht11温湿度数码管显示proteus仿真与程序源码
6 I' P; f! \& M5 P) z# u' r0 M8 ?8 ]# n. g0 q
0 {' _' C! Q7 `% ?: t% {; t, [
仿真原理图如下6 a/ N/ s5 P/ i( n9 c
8 p( A$ G9 o0 L
/ O+ P3 G5 H, K3 `' l! B按button1可以切换模式/ f; c1 E+ K. `0 C( a1 i, V, x, l7 W9 C
模式0 只显示温度9 a: z1 d# Y2 s) ?; w2 |
模式1 只显示湿度% V0 {% N/ Q' ?% z
模式2 动态显示温度和湿度,每5s切换一次
5 R1 \$ j( e/ [( }! M0 m7 o: X$ U" S
" |) ~8 D) f8 _2 F* F
实物如下
, d) k# _1 r4 z$ d温度显示
' ?! x; ?! t' D o3 r0 ], f
/ U. X( f. h* {& H湿度显示 小数6 N/ a8 V$ ]0 q j1 k0 }
( A2 @+ o' V7 A* X- X/ B3 h. m& q0 v/ h. [3 f$ }+ m
5 [# L Y, z% V
模式选择,自动显示切换湿度和温度,只显示温度,只显示湿度。
: \+ v- g5 v5 K& t b' C# ~, J. h
单片机源程序如下:
2 v2 Y* S: [( W9 v#include<reg51.h>1 `8 M M# f9 f, `. m/ i* g" J
4 q' X9 J9 E a, a
# ^8 F8 W# H Z C
bit DHT_Start();
0 I+ b( w# [1 [bit DHT_ByteRead(unsigned char *dat);6 L1 N5 r( t, l* L% n" [+ m
void ConfigTimer0(unsigned int ms);+ X0 d o0 l6 c7 N' W0 A
void Display_hum(unsigned char *num);. N; L8 {- d8 }6 |) ]/ s7 }
void Display_temp(unsigned char *num);# Y9 V9 _& w# B* H/ e2 L7 U# q
( x+ B! J2 S5 K G* G
/ a* X9 Y; N& m7 L) W1 {# f6 W+ w
7 J# }9 C: g5 d6 z+ u( s
- A! o3 u1 D3 p; bunsigned char T0RH = 0; //T0重载值的高字节
+ W2 l8 m) ?* ~ k; kunsigned char T0RL = 0; //T0重载值的低字节 ! r. k2 _4 X4 ~' W- C
unsigned char str=88;
9 C6 E: x, S9 ?+ h5 V M4 H! bunsigned char DHT[5];4 o4 M/ ~: Z0 q
# J( x9 n0 t9 L6 z7 B, a* x, n0 }5 }' M0 r X1 g
unsigned int tmr1s = 0;
, E$ [+ C! B7 Hunsigned int tmr10ms = 0;$ {! p$ N6 a( J; k
unsigned char st=0;' G0 V# C+ _ k& V) o
unsigned int sdd=0;
' @( U$ @, {) h2 Z, r, ?unsigned char td=0;
9 W9 d1 t) I6 P7 O$ Y# Zunsigned char mode=0;
% ^* R$ ]/ e4 ~4 `: n4 c# W9 t; |/ G6 g' g
% o/ R Q( h' k" x. h# D/ jbit flag1s = 0;$ g2 ^3 X8 x( I: G& m
bit flag10ms = 0; , }4 J. t. \6 `* C/ E2 U
int x;
& [( J$ N- q4 [& X
% g) o$ M! T% T' m% E3 t5 Fsbit button1=P0^0;
e3 f) ^+ a! c6 q8 o" W& ksbit dot=P1^3; //数码管小数点
! r& c1 k* k* \% ~& s' E5 G' E" p5 f3 I5 D5 A
0 S4 E* H8 Y2 ^2 x5 g S8 Y
' ]; J4 q& E% X; W0 H- J* ^& e9 y
5 s" U2 X& ?) ~4 _
void delay(unsigned char x) //延时ms
; Y0 m6 t) q( }6 L5 Y0 T/ _{1 n9 n* B7 M, W
unsigned char a,b,c;7 H. k7 i1 h0 N& `3 H7 T
for(c=x;c>0;c--)
% x2 |" A r5 N {
' s. r6 m3 V" x% h' O) q, B5 N for(b=102;b>0;b--)+ U$ E; O# T" W; }6 ?8 g K% m
for(a=3;a>0;a--);1 L" v% ~, p0 [! T+ \5 X
}
: g$ ?% |: q# B$ F' U3 Q9 m}9 A9 i; J( d' }3 k$ t* t7 h
void main() - e/ ^) b% T3 o5 R, _
{ 3 [' @. i% Y" I7 C- c- U, o
* T# w5 u/ J# s- X% p" o4 m# y) Q* _( c* O
bit tmp;
: ~2 B& F5 I7 n. C/ |- _3 Y" z dot=0;3 ~2 j) r1 P, z" S V2 b# g
EA = 1; //开总中断. j9 ], y. J1 u6 o( ~
ConfigTimer0(10); //T0定时10ms
" d) C% ?' ?. w; _$ r// M1=0; M1=0;M2=0;M3=0;D1=0;D2=0;7 D( X7 c* ?1 V% K, H
DHT_Start();+ K: V2 m5 i7 B. l( h3 h
delay(5);5 v4 E' O3 N! E, d$ f7 m2 D
: g" S+ J$ t' X8 n5 q9 z' S
1 J7 o* V# B4 L6 J# Q7 q0 g
while (1)
* Q/ l& U+ X7 m$ g {' r4 K* h; n+ [2 u* f# P( N
# `+ O2 V9 _# Z5 @ {; l
* R# F- _! E: N+ F, J7 w
+ B: U9 |! r* U9 }* O3 q* w
4 `% C. v5 s3 n8 D+ h! I, h if(flag10ms) //数码管刷新频率
2 \ s& ?; \* D9 l# c {/ r2 B5 [; j( D3 [2 N
if(st==0){, {, H5 o# e" e& L, a, ?4 `/ I
Display_temp(&str); D$ j4 q! b }; F
flag10ms=0;5 Q, b2 U: i3 _, ]9 U( p1 b- E
}" {- a) D8 S+ [8 E' v% x, C+ u5 G
else if(st==1)+ n& m& |% T# z7 u, r$ T) i
{
3 ]8 |' ^+ W3 C0 P Display_hum(&str);
4 S* a: n# T# _, T# u flag10ms=0;
) n: {( C+ B+ A! F6 O6 l* A5 Q j }
/ p: {+ w+ p z! m, Q. b
# |7 R9 m$ B0 P C, |
: _- ?5 h3 n# T# e% {
# ~9 H `. d4 H, o; W8 d+ T
& x5 W4 W- Q: ~& E4 [ }- D- [' z5 V6 b! t0 F- x1 h
else if (flag1s) //每秒更新一次温度、湿度
# Q+ o, S- x4 \$ }4 ] {
- B7 \2 L" d+ I( D- f5 A DHT_Start();
* L/ I }- U1 G. D0 D0 m tmp=DHT_ByteRead(&DHT);1 a2 L. n q6 Y! U; n5 V
if(tmp==1)
5 F0 F/ _ ^- `9 Y% h' m {
; f J- N5 t! J2 K0 _* o. j! k, U8 |! y# ^" N9 [) H% m
5 M; L) y% ?4 W( i: p" ~0 q if(st==0)
( D# ^5 F A6 n {0 `+ h4 z& a f* L
str = DHT[2] ; //温度: A% e" @& b/ `: J3 d1 ]
Display_temp(&str); 1 p' j6 @* f% j) a( D$ r' H6 Q. E
flag1s =0; //标志位清零
- v/ p) K; F1 c0 \8 U1 l6 D4 k }
& u0 Y2 k; x T2 B, v) o! E( q3 } else if(st==1){
r' E" f! G9 L0 b2 E* M! L7 l+ `9 r0 j# i
& A2 P5 c; n! V2 i7 M str = DHT[0] ; //湿度
6 M( g* A& ] n0 t( y, j: o Display_hum(&str);
) @" `/ m ~6 Z flag1s =0; //标志位清零4 F( u; ?" ^$ Q# k: U5 c- I
}
& c( Y0 \; t' g& z& W( `7 l f M: B* B' T) I0 U: Y5 Z5 F8 B& |5 }
- Y+ j8 i: d, i- _$ U1 `0 q2 ?
1 Y; u6 Z( z! ^. `7 u! b
0 G) G) ^7 s0 o3 \
, e0 u+ p- g: @$ A
}
2 G# e. _7 D; F" C0 D# @4 W3 c }) I6 h8 {0 o8 l5 C
if(button1==0)
& L6 b. d% s$ j2 |( r" w {+ {# Q# d% X, \# m5 n" U0 O4 b
delay(2);
8 V8 Y' x; h; h [3 Z8 u% \# M9 w8 h0 Y$ |$ G
if(button1==0)
3 y& n6 c& w* M; Y1 H) Q {6 c/ _, X, n/ G# ?& P m
$ U% K# b3 i! G+ ~2 r
mode++;
. H: J5 t% ^) J9 {" o) d' f5 @ switch(mode)
1 M8 Q; L! O4 m8 f- b4 m% v7 J {
# k3 D3 j0 o( g% O+ z) v+ r# [ case 0: st=0; break; P: F8 @9 G6 G# `) q/ C- u4 V
case 1: st=1; break;5 Q" @6 |- A! x" t6 A% H! K
case 2: td=1; break;1 S4 n: j' x! a# |
default: break; c, V' ^ X4 x5 d( M% |
}
! e# ~4 X, f- J5 x# v if(mode>=3)+ H$ o' ?1 x8 I. S
{
. }; _% B( n, ]! o0 ^ td=0;( B0 z6 h4 g* B+ x
mode=0;# w+ h, ~4 v% [. _+ _5 i6 i
}2 V9 O# t9 y: U' M6 H1 n* t
while(button1==0)) q. w, L7 y% y2 Z
{
" r0 ]5 M2 z3 a9 z2 Y1 q' g }
( z& |; k9 H" O9 W' d, r* c& R! q! x/ s$ |4 v
8 G9 p. C4 U* W( @" n$ S/ M& b4 w8 ]0 B& z# o. h2 n, k
9 K' m! \- s% V0 e
} W7 R% B4 o1 M1 e" X0 V" D0 T5 F
7 D; r8 i9 h9 Q: C) A$ ^( ~7 V* Z. D/ Z3 _ f
}8 Z1 k7 f/ r6 t0 y# A2 J
1 b: o: L/ Z( i! k: L: y
5 ?0 x" I: E" _# V
: E& V# z2 ?1 o" s H
3 J& a. g# @2 s" j6 z7 }" e- l6 A
7 f1 ^# Y2 d& ?1 z' h6 H
}
1 e4 Z! O7 ~* E6 P0 }0 M}
) B/ h% J/ `1 _! `: Q0 a" m9 n- p5 o
1 v% h% {6 Y* h ]8 x( ^. V
Y, ~, i4 u. w, V
" @7 T# o- i1 T$ _$ C/* 配置并启动T0,ms-T0定时时间 */
/ a Y* B1 B7 q! w+ p; Xvoid ConfigTimer0(unsigned int ms)
2 N- }' D$ W# C{
1 x) v0 i- A2 t- P9 r unsigned long tmp; //临时变量
9 C+ a# ^0 A) y9 K
$ X1 ?8 M- }7 ^# a i: J tmp = 11059200 / 12; //定时器计数频率: O6 P8 q4 E$ `3 B
tmp = (tmp * ms) / 1000; //计算所需的计数值! }2 k7 R. W9 P+ t; ^; ]5 |
tmp = 65536 - tmp; //计算定时器重载值
/ F9 m0 g, e u' W tmp = tmp + 12; //补偿中断响应延时造成的误差
; h! l* X- p8 Y" n8 C0 m( i T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
4 ~( a! W+ p1 I T0RL = (unsigned char)tmp;6 h$ @7 A% a- U+ R. |& C |& e1 Y
TMOD &= 0xF0; //清零T0的控制位
]( Y; F- h! f. o4 E TMOD |= 0x01; //配置T0为模式1+ {/ [3 ?6 Z6 i: y# E7 _0 f! b0 Z
TH0 = T0RH; //加载T0重载值# S4 d) G- I! C3 {
TL0 = T0RL;7 z: G$ R8 r# @4 q
ET0 = 1; //使能T0中断6 Q( _7 J) [+ R5 {! B8 M
TR0 = 1; //启动T0
" y) B* r r7 r( Y# q4 {}9 V/ h, z. g/ o2 L$ X& r. J- U
/* T0中断服务函数,完成1秒定时 */
7 w$ j$ ]) m: w: Q4 n. Ivoid InterruptTimer0() interrupt 1 B) l& _) c) O, b
{
, o9 g9 p6 N1 I% S* |9 W+ r! M+ ^) ^& x
q3 j, S4 Z6 s3 x; j
TH0 = T0RH; //重新加载重载值
4 g6 `; V9 [* y8 \% r TL0 = T0RL;
/ q2 A0 F i7 M( b tmr1s++;, V' s/ m6 G0 a4 k8 l
sdd++;1 X% Z2 R) z; H7 W: Z( ^2 p' g
tmr10ms++;
6 T* i$ j' s1 R5 I
! ^1 Y: Q5 s. j# \5 Z
9 z" Q0 H- h/ z! T9 L7 E. R if(tmr10ms>=1) // 数码管刷新频率
/ {/ b$ m1 W' p8 O3 ` {
9 I1 ~3 Q# E( M4 G, y tmr10ms=0;
) c$ \6 A1 f! b/ a+ c* u: P/ ~* s flag10ms = 1;
7 e( u6 J; M9 I5 F }2 K, E' D0 `8 C3 h
if(td==1)
/ D1 {- j& O0 A {
. T/ Z0 H1 A' O- R8 J0 k if(sdd>=500) //温度显示5s 、湿度显示5s0 E7 g6 A# W+ ]9 t
{
8 O; W9 X2 [$ ~2 Q2 b sdd=0;# ]- u5 n5 K- I) h7 Q" G8 y6 o: ]7 e
if(st==0)
1 A: V5 x* [5 l {" q8 Q/ A3 ?- c5 m
st=1;
5 {1 D! ~% q& ^; H- F }
0 F) W- G4 H/ e$ w K# i else st=0;8 N" G2 Z4 A3 t, P! d
}
4 x/ r, ]3 n5 \0 Q5 a6 p }1 |; } L" |9 R( b: b# t
if (tmr1s >= 200) //1s 数据更新频率
3 V( O6 D8 ~% }5 m {
6 D* Q. p: u8 u) g1 x5 l9 T$ c. T9 ? tmr1s = 0;' I" L) L$ ^ |3 U" H$ \5 {
flag1s = 1;
: E3 l) |/ b) i2 d- Y' ]8 }+ ~ }
1 q6 X9 { O# d6 L/ i% A4 v A0 k5 F, j3 K
8 ?0 Q# i+ ?9 ?2 D% t5 M" {$ f
Q. t1 H1 U, i2 a
}- m, {( f# _. J. r
8 t$ i3 O: t5 T, B& V- N1 s) {, I
: Y9 G' F/ O# W5 e. _7 C T下载:
: F- a% ]7 q3 i# z
# W, ~: t2 B( p$ f
+ }: k& C8 l$ d% T! } |
|