|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于51单片机的dht11温湿度数码管显示proteus仿真与程序源码
& c* _6 O/ T: |; s. s! W; r8 i7 l
0 P( H8 J, ^1 E' m" g) `# X3 w0 J; ]! V! t
仿真原理图如下* b7 J$ Z2 A% Y k3 B
6 [7 ^/ J2 B' s4 l4 t4 c) G3 b' K( R* G
按button1可以切换模式/ I- `* B* }* j' ~ q5 Z4 O+ Q5 I
模式0 只显示温度; p5 k& S: f: b3 v8 B% N C
模式1 只显示湿度( g9 a* t, m: D' b" D3 k, S1 T
模式2 动态显示温度和湿度,每5s切换一次
: x# w! e# H# D8 k d/ M8 O
9 Q$ a1 N$ A: X" }9 \ K% A! v+ D4 L7 N9 o7 }# O
实物如下
5 _- c0 l" _0 M! e; u温度显示; z* p% E5 I0 U/ E7 |
( R; Q' h- y3 M( U' U3 V湿度显示 小数5 ?0 x& A( Y3 ^5 k* K$ O/ }
( q. G) d8 ^) T- e1 F6 H
3 f' R) u% I9 n" P/ L. I- r1 _9 V3 k: L 7 e" n3 l; A& k3 v9 `1 i b
模式选择,自动显示切换湿度和温度,只显示温度,只显示湿度。
# B! A8 _: m& N3 o$ f9 O. x
" c9 u6 W9 o0 k5 I单片机源程序如下:$ z3 F7 j6 G. }/ r6 F
#include<reg51.h>
6 e! c, D* _* T, @* M+ a% F4 ?. @! w) |
3 @# K& g3 i' \1 nbit DHT_Start();
& l' _3 T7 U& ibit DHT_ByteRead(unsigned char *dat);
! v) H; v" Z4 Z7 N. J! xvoid ConfigTimer0(unsigned int ms);
. r, S. x& H1 }# E# L( ]4 A; y) X1 Zvoid Display_hum(unsigned char *num);( Z: ~* y$ d( q7 v. a
void Display_temp(unsigned char *num);
1 K( x# c4 ^- r! k5 }) ?/ C
}, y N- S; c: e
3 [+ P( M7 ?2 T( k5 S, p
) a& |( |+ h, o* v% z
/ p' e. Q ?% C- J0 x. Aunsigned char T0RH = 0; //T0重载值的高字节
; R V) q/ {+ t% r: ?( tunsigned char T0RL = 0; //T0重载值的低字节 , `/ U( a5 z# u
unsigned char str=88;% m# L9 j l! f# W& L" M
unsigned char DHT[5];
9 a) |* j" ?! ?, K4 K- X. \; c
; T! J# R2 O+ i& x) _, R8 v. r! r. D, Q6 p7 J0 _6 G) ]; V5 U
unsigned int tmr1s = 0;
6 L; e( x' E+ _) _2 P. Xunsigned int tmr10ms = 0;, B# d+ e4 X; t& H8 Z6 P+ [7 _0 |9 j1 S
unsigned char st=0;
! s$ q' }2 ^+ w9 J& Dunsigned int sdd=0;( A0 c: K; F; V0 W
unsigned char td=0;
3 V0 W8 H# p: [" L& j2 cunsigned char mode=0;7 d/ R7 r# l! m: H* |: N: i0 k. P
: l0 s# q9 X K( w# ~
$ P$ e' L7 r k! e7 r+ r) Jbit flag1s = 0;
* i5 m# r/ |& \8 |; _: v, Lbit flag10ms = 0; - L' |+ p* P N) P. @
int x;
: M* G# L( D. z# f ) l3 o. I' T6 s, M: Y9 \
sbit button1=P0^0;% n' ?3 {$ p0 Z- P0 ~0 k. F
sbit dot=P1^3; //数码管小数点! x/ X7 Z: }% a. p
S, ]! q: R1 l- h
4 m/ O. S. x+ d* n/ F# m$ c& a% s" `" U! f' [- B! v( Y
5 R/ F% b' P1 x$ O8 [
void delay(unsigned char x) //延时ms4 m1 W6 ]2 r1 H- ]' g( B
{
( |- w E/ L7 n8 C unsigned char a,b,c;
; |- F( C' \: z* c for(c=x;c>0;c--)
8 X3 c7 l( }2 a1 c {
3 n5 u( N# I7 X* n2 E0 q for(b=102;b>0;b--)9 f& M3 b/ U/ W9 H
for(a=3;a>0;a--);+ ]# k$ W, @/ R* o2 K/ b
}$ }/ } e; a; a9 B j! J) `- [
}1 u0 X( ?9 f5 `9 g4 Z" l
void main()
4 Q3 n/ ^# |: K/ x t{
0 A; a" a2 g) u$ q8 E2 G. \# m; \/ ?
! g( R6 m, G$ t- o5 }
bit tmp;
- X8 {7 t- O& V0 |' k dot=0;
! L0 n% j4 O0 s, ~; ~5 e EA = 1; //开总中断0 y* ?+ o- P3 r- _8 R* Q4 {
ConfigTimer0(10); //T0定时10ms' F8 j0 L0 d( \
// M1=0; M1=0;M2=0;M3=0;D1=0;D2=0;- S& z* e' D4 S; G
DHT_Start();
( G9 ~1 j. y9 }+ ^$ b. j# e+ _ delay(5);; {8 b! x2 ]: n- A; [
4 N F- U% z) q
# g3 X- ?7 z' G0 r
while (1)5 b: b. w9 T" E8 x
{! X+ R3 W1 g, j( ?* ~
% g( g. {) G+ G# `, a( l* f, x, s- F
# j$ l! y! h$ b) [. I5 ^: s7 z B! j" `
0 n- n: I8 e0 D if(flag10ms) //数码管刷新频率
$ f$ [+ e1 Y6 a$ l( _& F5 U {9 f) m) B! A! D% S# n
if(st==0){6 c) t8 l5 y' }) \) d
Display_temp(&str);
4 T, s+ x! y6 g flag10ms=0;
0 z3 ~1 w. [ o/ z }. Z! A. N1 F# L9 G- v! p! }
else if(st==1)
, G k- J* u5 j( a6 _+ b) Z {
. K+ ^0 o1 x& p- B' H Display_hum(&str);
4 b6 f4 s6 Q' s* ? flag10ms=0;2 y" ` e+ i0 J/ T3 M) |3 N
}8 }: i3 u2 A" L/ D1 _" \6 y% v
4 g# l: B3 k3 g% @
: B9 E& u2 ?; M$ ^! ^
: n% ^9 M! v. Q/ V/ z # X( N9 A3 i; ^8 q) ^/ \6 b8 H
}
1 d$ w6 u; \$ v* L6 q3 O. B0 T else if (flag1s) //每秒更新一次温度、湿度
- o2 k4 U Q K7 \) j {
4 V' R4 \% m! {8 R" _ DHT_Start();
8 v0 w+ k7 F- O% k2 r/ ? tmp=DHT_ByteRead(&DHT);* v) {8 ~: ^6 t" {" z
if(tmp==1)# G. m# N2 k0 k: c" \5 [
{
8 Y* d/ X2 A( q/ a3 V: H4 `% U- w/ N$ b2 ]! N4 c/ G9 W
6 T# V3 {1 a) @4 b n5 r if(st==0)
b7 L- F- ` X! ~3 G/ i% h {
$ m! d& d" ?! G. D6 {9 O str = DHT[2] ; //温度
- R1 _4 k5 g+ B' d+ _ Display_temp(&str);
}3 ^6 k, L- \. J7 V* }; `- { flag1s =0; //标志位清零
+ }) [( }( }; c2 T8 P }
* v* x( _- G% h else if(st==1){5 v. u& `. r% X6 H |" m1 a
: ]7 |/ }! T$ m, f
, n- r, A. W6 Q- }6 \' W
str = DHT[0] ; //湿度
0 W7 w; N6 _! d Display_hum(&str);
7 B5 u f9 E, b k flag1s =0; //标志位清零
& U: q' |0 P2 M; ~) z }1 v5 S: x; O( P) g& A' o @$ A
$ {1 @) y) n' S/ O4 I0 J# Y4 {3 r, u) i/ X; V) v. U% U
; O# h$ X! g, {$ R0 ]/ Q4 _
& J% n0 f9 t$ O" Z' U
E' L' q1 H( x3 t }( R; I" P) I4 m% m) [+ V: L" P& r- ~
}1 X$ y9 ]& ~) e! k5 o% k! m% W
if(button1==0)% y' n, r6 r$ A6 v) w5 ?- P1 i! y
{+ u2 `! w: i& u' b( {: Y
delay(2);
5 E/ ]! N+ Y6 L, k2 C 7 { u. O! N* h, c
if(button1==0)
( W* y4 {% D$ s5 | {( B7 H8 {: D" B" ?1 t* y
, r% |5 x9 @5 `5 w v" O7 q
mode++;
1 Q2 H- @9 X9 l# ~- O' y switch(mode)
s/ |) b+ N t& e: x7 p2 M; N {
2 r+ i. j# X) l5 n7 l+ h case 0: st=0; break;0 g% _# r! f& j* O7 r e, y
case 1: st=1; break;
. P2 `+ `7 s+ H! L& N6 o case 2: td=1; break;
1 {, D) H( [; Q; R6 m default: break;
! N/ f9 J( M- |. `# p) B }6 z& \7 ]7 r$ K S; s; F
if(mode>=3)" R7 c8 T! f0 z: |/ L1 J
{% ^; i; @# T- D! {
td=0;
9 l0 p; J% D: u8 E l* [ mode=0;! S8 I8 D$ [$ c0 G7 R$ l- h; Q
}
, [1 @6 S3 z( ]0 j" r while(button1==0)
6 \. A9 D) I! S: g7 V {; o7 d9 c; u: w
}
9 v6 W& |0 n0 B5 C }3 X: j M5 I, `. V6 S9 B# ]
7 K9 o- F2 g% [ U @, F) N4 N$ N
+ W, H' ?$ r3 V m% k
- X, {% ~, K, R8 | }
1 R9 r- ?& n/ F6 |- z9 h, X/ C' n& B$ P4 b7 R
: l3 \5 `- ]9 ^3 \. R t- c
}
, |2 P+ O9 k) f
4 c0 C7 L3 \7 L0 e' _4 ]0 N# s8 S; N# I$ y5 D
. I2 d7 H) y" s" Y3 U* b3 V1 U' _ r& b' `1 W% o* N
0 ~: a1 F; `# }1 p3 \0 Q9 l5 |+ t# l
. `* l7 c3 F _8 y& f% h }+ u5 { b- T# G* n, B2 [) Q
}6 F2 K( u! n9 A( e4 T) A
! j7 o1 m/ ~8 f8 D& k4 }5 _
4 ]+ O' }* J+ O, v8 O* m5 H+ U
. @+ i+ m& W- V6 s9 x) I! w, u; T' b5 R- X. E
/* 配置并启动T0,ms-T0定时时间 */' C* X4 g) C) Y' T' W0 l4 y1 p+ F
void ConfigTimer0(unsigned int ms): A) F, e0 c N9 l9 B
{
7 g% S. @! h3 t+ i6 Y$ _! L unsigned long tmp; //临时变量
+ ]0 z- y8 C! Z
0 V1 g- W9 n# F tmp = 11059200 / 12; //定时器计数频率( ?! v6 @8 [6 ^) z3 E w
tmp = (tmp * ms) / 1000; //计算所需的计数值
! U4 ?; ?- y0 o/ U: @6 r- O tmp = 65536 - tmp; //计算定时器重载值
# m2 y; s% P& f3 ]- u tmp = tmp + 12; //补偿中断响应延时造成的误差! w$ ~+ J6 T3 V: _# ^- I* M
T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节5 L. d3 I( _) O1 b
T0RL = (unsigned char)tmp;+ L5 _9 b4 p- |4 F* y
TMOD &= 0xF0; //清零T0的控制位
, i3 h1 w# M5 ?! ? TMOD |= 0x01; //配置T0为模式1
. e+ Q; q; o- `2 E5 x7 p' i TH0 = T0RH; //加载T0重载值 G1 ?( w4 T; g
TL0 = T0RL;
" @3 r7 B2 M8 P) m: A1 S0 G ET0 = 1; //使能T0中断
2 c* r# z. a1 T2 K) Z TR0 = 1; //启动T01 U, K) J2 i% @
}
; |5 X/ v& O3 J8 e2 n/* T0中断服务函数,完成1秒定时 */
2 a2 p4 J' I( C& S) K, z, Nvoid InterruptTimer0() interrupt 1& ~ f% p8 S4 ]9 z) ~. H
{. g& q. Q i0 o$ G1 Y3 L: j# o
3 {4 i2 A) q4 V; {
/ X. d; }! w. B TH0 = T0RH; //重新加载重载值5 C- f; a* y- O' K
TL0 = T0RL;
" x! y4 o2 x7 o' [* U3 | tmr1s++;
/ k1 s" A9 x- Q* D( p/ O sdd++;
) }7 y% {- q8 F- ^7 ^7 g tmr10ms++;# x* \. H6 T- u2 \9 k
& P+ l( u$ g; x/ L e7 r
) h$ `' e- s! q( f) X if(tmr10ms>=1) // 数码管刷新频率2 t1 f- J; c/ i0 [/ U0 J) A
{2 U: L$ V: `8 o8 P8 ?$ d6 E
tmr10ms=0;9 e4 y4 G+ \" }6 n& @; A
flag10ms = 1;( k/ Y4 v& l, D9 ^9 i
}: k0 q5 \* v4 N+ E" o
if(td==1), {6 K* ^/ t* x( k' f4 Q
{, M+ i2 I# S) w: c
if(sdd>=500) //温度显示5s 、湿度显示5s
/ M p0 {5 }1 s0 }4 i, Y! M6 w* a5 d {
' ]2 Y$ ] e7 y8 H3 q2 k sdd=0;
! L7 f5 {, U$ U1 I, N if(st==0)
1 K; y' d' a6 O+ m* ^3 n {
$ ]" C9 M; m2 r0 O1 |+ L+ e st=1;
; l3 R- [" g" W, G7 \8 ? }% D0 A3 X+ z, i: _5 Z
else st=0;; a; O2 h; m" e$ I; I& g
}
; d- |9 `# B6 M4 e }
6 `6 x0 R! w3 U6 O# u, f. c% v$ [ if (tmr1s >= 200) //1s 数据更新频率6 T9 E" X, \& _
{
& m1 @: j/ I/ y b4 K( I# b tmr1s = 0;- z7 o) U: E% R
flag1s = 1;' W! E8 D: S7 B/ ?; ?
}0 t8 O' P+ y# T" R
" x/ R$ B1 [- R( D6 ~
4 o C7 p# O1 w& {& @
6 H- O8 }# u" [: h# M( k V
}% R8 U3 T7 p1 x
8 u& i W- X9 e2 |( }+ t& P' x
* D S7 d: F# s% g$ Z0 y, H下载:- D4 }7 V; T; S# d
9 `3 j& X$ m5 j: I/ z: e- l3 s2 { [2 {' S& P+ a
|
|