|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于51单片机的dht11温湿度数码管显示proteus仿真与程序源码
7 k3 d: D5 J7 N, u0 B& [" s7 j) `% ~3 K
& ]' H- v4 Z2 b仿真原理图如下 r1 s2 g7 [' ~
) p- ]4 J0 K# ]2 \+ u, S ]9 [- V& |
按button1可以切换模式' W( F" B( b2 P6 i; p3 n% k
模式0 只显示温度
& P& b9 b7 _ ?- ?模式1 只显示湿度; S4 b1 d; z- K, a& b$ ?$ l& [8 v
模式2 动态显示温度和湿度,每5s切换一次
% @9 c. O6 g1 [! L( ]3 }) R% i" V9 x0 O: V
' n3 F# E1 ?" d% Y- }$ G4 [实物如下
" E! e9 Y7 P5 P6 @/ _. i温度显示
, O3 I, I" R" {+ f
# A. [8 D' Y. e湿度显示 小数5 i1 K3 _, x1 J6 X
( f+ S6 _+ {- x
; I, N1 f7 z. c0 F
* [9 @0 ~- l5 a1 w$ `模式选择,自动显示切换湿度和温度,只显示温度,只显示湿度。
0 r) o% Z4 @+ w( \* ^
1 r) j5 n& k8 G* P. g' D0 \单片机源程序如下:2 M, L7 c/ r9 m4 B
#include<reg51.h>
% {' z, \. b* c. z: C
) n/ C0 J! Y2 e( d% E( }) C- r% v
bit DHT_Start();# A" j6 @9 [2 ^$ }" A. e$ S
bit DHT_ByteRead(unsigned char *dat);
3 L; K# h5 s' r2 |' x) gvoid ConfigTimer0(unsigned int ms);0 a6 d. k8 m2 `( p
void Display_hum(unsigned char *num);
% ]1 t3 O8 k2 t3 Q% n; {+ {4 {void Display_temp(unsigned char *num);" L) r, L6 p9 {4 C M1 Y* ]) u
5 u( _) x- ^- M8 G- a+ V& {
! C# K9 p/ j8 p
' g/ ^# u+ T0 [/ ~) z
* r; I8 g3 s k$ j
unsigned char T0RH = 0; //T0重载值的高字节; f1 [* H% l+ N1 R9 u- ?+ K% c
unsigned char T0RL = 0; //T0重载值的低字节 * K# i, @3 e: y3 p
unsigned char str=88;
4 r2 @9 U6 w% z) w$ X. eunsigned char DHT[5];6 Y/ e/ ?' D9 ]7 ]' n D
8 n" x9 n& ^6 O4 r! e% O" D4 a( r N$ T
unsigned int tmr1s = 0;& Q- A7 Z% k; q* n
unsigned int tmr10ms = 0;! C0 F! x& `# C# v" B) N
unsigned char st=0;
0 H1 v# H# L# R. Tunsigned int sdd=0;
) V* K" I' X. |4 A" d3 [unsigned char td=0;2 A5 L5 r! B3 F( x! l
unsigned char mode=0;
; E& [% K1 V, S3 i* t
3 F* i+ G& l4 G! B" ?) l, i6 k3 i9 A1 y' k' v$ N
bit flag1s = 0;
, A2 E7 M! O$ j3 ^* @, Kbit flag10ms = 0;
; r3 S6 z' i: B9 ?6 V) p6 n! Rint x;
" R3 W7 t6 t* e( d; ~! T1 x 1 i- ]3 y/ p2 V
sbit button1=P0^0;9 F( U1 T0 P/ Z3 o# b. Y
sbit dot=P1^3; //数码管小数点$ n3 G! f$ J- d; m. \% f, `. I
) h- w ~1 z% |
0 c" Y0 [+ }: m5 q; z$ E! u5 D$ B, e
8 p6 e9 X. p& p; Z6 A
void delay(unsigned char x) //延时ms( \9 [$ h5 [7 {. L6 G
{) l1 b. r! h( G6 {' p2 T- b' o- B8 M
unsigned char a,b,c;4 E( h2 K) ^$ Y, R1 m
for(c=x;c>0;c--)
# l( n3 Q" k! s3 J6 ~: S/ f9 e {
% z9 n( {3 b6 T; X* X+ u3 T) {2 l for(b=102;b>0;b--)
3 f3 l. c0 B! w; f3 R/ r e for(a=3;a>0;a--);
5 z0 I1 z7 O7 K4 o0 j& J. f; F }
$ @5 Z; g3 R( {}
3 d4 Z9 _5 n8 A8 } W, Jvoid main()
; p! h5 ?3 g$ }( j: y2 D4 T( N{
. r. b; R7 b7 n9 \3 _7 `0 r2 G. p5 `1 n9 e# e4 m; ?4 [" z, K; l
! n9 Q1 O/ C3 E: a5 T r bit tmp;
! N" z% |3 M3 A/ [) S3 S dot=0;# U d2 Q9 v2 G' b* {: k9 W/ r
EA = 1; //开总中断
" m5 T$ Q8 j* v6 I5 F! t ConfigTimer0(10); //T0定时10ms
7 p9 l& I5 u9 t! ^( `) p8 \, h// M1=0; M1=0;M2=0;M3=0;D1=0;D2=0;
$ E) c( U( S5 h DHT_Start();& L( q/ Z9 D0 J n3 [8 ~7 c
delay(5);4 c- o( l" g' h/ B( r( M" K) ]
% l9 Y# w/ P. O
& `& n' P+ b7 [ V4 ]: `
while (1)8 f- R/ h: ^3 @+ Y1 p9 W
{
. {$ c$ b/ b! ? q7 y: z% z8 v, l
) O7 j9 D b) |3 b: t1 F
+ V5 k9 C* e& e6 I8 m" E8 w& \" H4 p% v; N
if(flag10ms) //数码管刷新频率
, o5 Q2 }0 V5 i4 S9 w' b8 } {- f6 b/ v' F; L6 J7 s! w
if(st==0){' V( L" U" P1 f: b) p* q; V
Display_temp(&str);7 k# ^4 o7 {/ _" M1 T6 j
flag10ms=0;
- G$ R+ s/ O* n8 o6 h) v }1 o! m% F+ B& G
else if(st==1)" _3 U6 A0 e1 [/ @. ~3 @( q3 X
{
7 {) w8 t( s+ B; ^2 _; D$ Z Display_hum(&str);/ v4 A6 S# C2 Z! e2 J: ]/ g
flag10ms=0;
3 I% S5 c: ~5 m. t }
# J. G& ]/ S/ Q+ `' \8 e2 ~3 T a6 @/ Q" u
" J0 I2 a: F4 ^( E
0 t$ K: N0 o* A! d, D3 b8 } 6 l/ V: {) v- W2 K2 }, {
}
% R, I! Y* z0 z7 I else if (flag1s) //每秒更新一次温度、湿度
; L1 T" u. u- W0 {: O# y {
$ Z( n0 A6 t/ \2 x K2 u DHT_Start();
. K o% [0 S# O5 z" ?! H2 h; ^ tmp=DHT_ByteRead(&DHT);
* p: K$ M! i1 t4 C u) R if(tmp==1)6 \3 l( C/ U4 ^" J- {8 n
{
, B2 e; Y* W: z% `4 N; C% b( {5 w( }
- y! x9 H& e# k0 p1 e) n
/ A# D5 P- a& o% q& Q0 | if(st==0)
" j; v) `# i% R+ x. P# B4 p; Y8 L* B {
" E; ~$ g K) p- ?7 v4 R str = DHT[2] ; //温度' n- `% M0 M4 A" K( C
Display_temp(&str);
4 z; M- W2 Y0 M" y, } flag1s =0; //标志位清零8 x; t8 X! D* ^& q! w ]
}
: A/ U! ^+ x' A/ t1 u else if(st==1){6 @5 P- a* t. |* V
- t) h; f$ \& f
0 U2 `$ M% {4 Z$ c( y str = DHT[0] ; //湿度 h4 v" j) |. ]9 a) h: q2 t6 s- b
Display_hum(&str); % T0 ]: v% ]4 \& S& S8 f- V+ E
flag1s =0; //标志位清零
$ o' B% L2 ~7 D }
# N' \. N1 J/ _) _6 o4 a
3 z" `; g: @% e: ?. P
8 Q7 E2 ^( N) J / _, f" C, t# b5 G5 I8 D
: {7 N" I" E) W. `4 z. P. y4 I$ u3 A, N x* {. z1 u, y
}% ~1 w! @. D8 N$ Q+ s) D
}1 c. E3 p# w* u8 s2 u
if(button1==0)7 D. q, a8 @# k, F) s; Z7 e
{8 P+ ]* y8 [2 g; v
delay(2);
, s0 ^% X3 |, W1 k/ A ]
4 i/ [! V2 L: w: z; K: Y if(button1==0)
$ `4 g2 X: C; M' g# d+ {7 U {
5 R; j. c5 g) N- \6 o + M) e, s# I9 I1 }! `7 E* X2 S' W( R
mode++;; J O0 i7 B$ T6 c, T; X
switch(mode)
1 Y% l4 J5 ]& ^' f! S* T1 z {. s6 d2 \6 o5 }, ]' r/ ?; ^1 n
case 0: st=0; break;6 D+ i/ ^" E. F, Q
case 1: st=1; break;, G2 t; M. P. u, P( L
case 2: td=1; break;$ |( y) j# C. l2 l. l A
default: break;7 k( _ p9 [* f: C
}. T0 j$ @2 a7 J
if(mode>=3)/ M% g! T- x& d. X0 {0 m; D* @: C$ w
{
# o' `7 _# z8 q' C: M( z td=0;
& d/ i. z. v* c: w. M Z mode=0;
" B' {2 ?1 @' R# F8 |) b }; X) ^" Q- K7 I1 D/ [
while(button1==0)
8 h9 `( r$ R" L$ R7 k {
X. z* U1 H/ Z3 ^3 ~# P# M }
A. R2 l0 `) i% _4 q1 s
1 v) o+ \) I9 F* c$ R: }& ]
: `! J1 n6 |! v
' C1 X$ _9 o+ ^$ C* x* s) z& G5 Z, o8 |0 C
}2 {! G" Q# Q! ^3 ^, }
* _: @7 d( D: v5 K5 Y
" g: N5 l( E, {: ?+ T
}
/ m' q; O6 f3 i1 I
' s, V" J" W$ A5 U
0 I. g' A+ a" ]$ P% W7 X
7 V* a; n+ o a% Z$ W$ a/ X4 y/ Q1 o1 |# H8 l/ A2 m3 S
+ F) k! {0 N$ n3 y. z6 ?' }' _, y2 t8 e
}. T! L3 Z5 \3 v n ? b
}' n+ l. h' l( z; y- O* W
: E/ Z( {3 O% P4 W4 Z; S, Z
/ U" ^. ~2 Y2 z! q+ @. T
Y$ q& s9 W9 G0 Z4 v$ n* U7 z: y5 @- b6 j
/* 配置并启动T0,ms-T0定时时间 */% Y' |5 h: ]: x8 e8 A, V
void ConfigTimer0(unsigned int ms). T9 ]9 o- y$ A- i# X, T
{
, t( ?2 e6 V$ M6 p! R7 Q unsigned long tmp; //临时变量9 d7 N- [: C6 x4 W% a" A) [* K
8 k! y, P- X9 h' V8 W$ L. L" S tmp = 11059200 / 12; //定时器计数频率
* u$ [+ G9 T! S: v' z6 y tmp = (tmp * ms) / 1000; //计算所需的计数值& B+ p! n$ N8 D% u* t4 W
tmp = 65536 - tmp; //计算定时器重载值" S% `( |/ H i2 P
tmp = tmp + 12; //补偿中断响应延时造成的误差
! L7 P9 M- @! m2 L T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
3 P+ V) ?! u$ C$ t' A T0RL = (unsigned char)tmp;! _' Y3 L& i2 Q) @# H& B
TMOD &= 0xF0; //清零T0的控制位
e T, y% ^/ ]" v* {& d# w$ y TMOD |= 0x01; //配置T0为模式1: m4 @9 }$ @ N& o) P
TH0 = T0RH; //加载T0重载值
% Y4 g6 M1 S9 c' q6 j/ U8 a. A6 X TL0 = T0RL;# `) J, u6 Y8 B+ u4 u
ET0 = 1; //使能T0中断/ t4 g u( F/ P* s" o" b
TR0 = 1; //启动T0% E, \, F0 Y( ^5 ?
}* ]; }; V$ \2 ~9 _) U6 T& E
/* T0中断服务函数,完成1秒定时 */ Q2 d. l a1 i' H4 R+ l
void InterruptTimer0() interrupt 1
8 {+ n( L$ c9 ]" J& R{8 y: l Z1 d; @8 I2 J6 [
3 G% ]9 q- z, H" F! p) b
: M' M, X* t P' ~) c
TH0 = T0RH; //重新加载重载值, V5 ]3 Z& q' k- C4 |2 [
TL0 = T0RL;
0 q* w5 X: q3 O" w tmr1s++;
3 `; R1 d9 d4 q sdd++;: w& D3 d6 ]/ D
tmr10ms++;
: l9 v% T6 K+ i' o- o5 |' {+ W5 a( c0 q) C
" }* m% E+ m: q9 d7 h6 O4 ~
if(tmr10ms>=1) // 数码管刷新频率8 g' {0 N3 g3 b- X, \. W
{& u6 d2 X/ H2 x4 t: d
tmr10ms=0;
1 X" j" F0 z1 c6 f6 _ flag10ms = 1;
# d9 o9 \7 Y# k& C! y4 K, @2 E }
. M/ A9 v+ @$ c) X. d9 m if(td==1)
/ O, Z9 \# V% y/ O4 C {
+ ]. e) O$ l r/ C4 I3 G9 M if(sdd>=500) //温度显示5s 、湿度显示5s G9 j) M+ f* A) d; [# F6 e. p
{: m' C5 u @; L0 P' P5 w
sdd=0;
8 j0 j# l8 h7 P# ?7 @. r. r+ ~ y if(st==0)# h: g' |, R y" S$ [" ^
{3 H' T9 f8 Q- v) D1 _- V
st=1;
5 J4 d) L6 Z. v4 ~: D }
& k0 t N1 r. I9 u1 W+ d; T else st=0;
5 H$ ]$ g8 Y$ q* V# a4 R0 ]; _% r1 A }" r+ i9 Q6 @0 e9 b! }- [" i
}
+ ?( b+ l7 v5 L j- u# w3 P1 A if (tmr1s >= 200) //1s 数据更新频率% ^1 M( O% i5 h, N
{
. {) p& b$ c) ?9 `/ @1 o$ _! ~- W tmr1s = 0;+ S/ f+ U# A3 Z1 E
flag1s = 1;
3 ]! T( p/ B8 e# w) |0 } }2 Y6 P) o' g0 I4 [' y2 ?. {
4 C( Y4 _3 n$ k% P
. _* ]1 b& o! v$ Z, W8 j 2 Q: [0 t) Q4 {9 J6 F' t
}! Z; `' w: D7 w! v0 P3 f* ]4 O
# N' M0 d4 [( g8 x! L; C0 n
! E. k+ }5 y; f' b# B
下载:+ T! u& ^- Q0 m6 S. ]
) i- @6 q7 _& z* e) C2 d- C4 o% K) _
$ { R# L; l2 i- n |
|