|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
基于51单片机的dht11温湿度数码管显示proteus仿真与程序源码9 m X. k' u+ q8 k
0 V* r( h9 T9 N/ z( O* Y7 ]2 x+ d( v- U" z& R0 n5 \" e; F
仿真原理图如下! l9 e! n! @$ a L! M' h( o$ Q
: q3 l8 G' P, s, s/ U
/ e* P# O9 E* v' n; r% [4 J
按button1可以切换模式
4 U- K+ Q3 |3 U$ B模式0 只显示温度 B" F7 s0 P- x: x( j" h% B
模式1 只显示湿度/ k/ w) w# @5 X! k8 {! y
模式2 动态显示温度和湿度,每5s切换一次! K3 @6 t9 S) `4 p& z) I' Q- J& e- k
% }; f% f9 i: V/ Z; L9 M# v
5 r" z$ Y7 G$ J% s6 S% [
实物如下
! s) Q, K/ H6 h& m温度显示
' f) u1 F* N! a. a * y/ A7 z8 D9 n9 u
湿度显示 小数
% {/ p" ~- \' l- o4 k- d& Y
# z- A/ q6 E( g/ [) L
- |2 |) `) {7 V+ L7 N& Y7 s - n: D" b7 P2 i" l6 p) ^
模式选择,自动显示切换湿度和温度,只显示温度,只显示湿度。
4 q5 A/ E# ?! u/ q' X' u, H9 q$ ~8 X4 Z
单片机源程序如下:
9 D* k1 q% G8 A8 |0 x#include<reg51.h>0 t5 @. e' d) p6 o3 D: \$ I0 ?! _
1 v1 H2 G2 n3 v4 d: m* D4 a: z5 s& F
bit DHT_Start();
( Y m% m: s7 hbit DHT_ByteRead(unsigned char *dat);6 Y3 @6 F- J5 i; u# k4 N1 {
void ConfigTimer0(unsigned int ms);4 T6 c, E5 r9 c: b: P& @2 Y/ r
void Display_hum(unsigned char *num);2 z4 C" s0 m& a `
void Display_temp(unsigned char *num);9 o q- s1 ^4 f- F$ T: B" T
3 W" k' ?7 V B- W. c0 B3 Z
) G" Q( n$ T. j) I. n6 n5 i: @, ]8 `, @9 M5 {, H' Q4 l
( S ?9 _9 s! h) lunsigned char T0RH = 0; //T0重载值的高字节) L# y' a. d5 u; u* V
unsigned char T0RL = 0; //T0重载值的低字节
. s6 J7 a4 s E9 U, z- gunsigned char str=88;
+ ?8 H+ i/ F4 S! S" l4 q1 g3 Eunsigned char DHT[5];, ~- ~7 F$ G3 C8 e& ~3 s$ I* V) b
2 L3 v# a( L. z3 H; _+ f$ I: E& V9 V7 L
unsigned int tmr1s = 0;
: z$ R; f7 w3 U v9 funsigned int tmr10ms = 0;
- {! X$ |5 U$ |, {& E6 }unsigned char st=0;
* z. V, l' k1 v7 |+ A7 E# munsigned int sdd=0;( H! b- J; h8 X( K9 q
unsigned char td=0;6 Z) g" X# q2 o/ i$ n! o( c
unsigned char mode=0;
% G7 c/ q& U* @6 n
1 o X4 r- N0 b) G, q. o. d6 F
) N3 q3 X3 f1 L! @; X; ^bit flag1s = 0;# }+ c0 F* k+ E8 v4 ~1 Q0 x
bit flag10ms = 0; % c, O! T3 ]1 T, Q6 m$ L- ?( d- N
int x;* M1 K% _3 r; X! f1 E- p
# C) I, y& B! U' O
sbit button1=P0^0;8 Q8 i( @. R4 I/ M2 T" I
sbit dot=P1^3; //数码管小数点
3 E+ |7 R4 p& ^, k7 K' v! g. F1 V9 d- k
$ u/ b0 M- ]. `" ~) d1 ~4 E; t* ]- @! W# O& r( \! t; e+ |
3 b+ l- D2 q+ E- Y
void delay(unsigned char x) //延时ms5 o) {# ~# ^! _+ F# C6 j
{! A# \: r! {9 u/ H. e: h' w) ^
unsigned char a,b,c;4 c. }6 r7 a: e5 E( Y+ {+ J
for(c=x;c>0;c--)3 p. D X! I0 n# S- e/ f
{4 p! v U* I* ^! j W
for(b=102;b>0;b--)
+ l5 j. J! z8 A. g8 I" U8 } for(a=3;a>0;a--);
* }! d) e/ G; M9 h( t( B# _$ f }8 f8 i! K% [# F9 i" o6 Y# L( d
}
9 T' e( x/ b+ r7 Y5 m" c# d% c7 D) uvoid main()
. o) h- k7 U& q{
* M8 q; `' X' m9 Z
9 \' ?9 e, m. t) p9 B
$ l) b: b4 ?+ H3 A( H W: U bit tmp;
0 p5 [/ @% u+ B1 T+ C; R8 ]# ~ dot=0;: `' Z6 `6 X5 g; n
EA = 1; //开总中断6 o1 K1 z' j6 t) t. W8 C
ConfigTimer0(10); //T0定时10ms6 C4 n1 E0 H( k# O7 a
// M1=0; M1=0;M2=0;M3=0;D1=0;D2=0;: b# f( N. u$ R" q4 m4 F+ d& F+ X
DHT_Start(); j: i/ x- P* o* l
delay(5);
$ n% V6 ^! S" w. E0 N, V/ G6 j5 {9 F, Q
" p; `+ S+ G( |. }; ]7 m0 f while (1)
& k4 Q) o, ?2 K6 g {5 Q8 c5 i6 `- `. R& E8 F
9 T* `- \/ G4 E* @; R) L
. u$ O. `: X/ q4 \- p7 a
' O8 q2 K7 D: E" h% o& w
/ j9 \5 M- {- J if(flag10ms) //数码管刷新频率; X- Z F$ k7 x) c
{' f. } L0 M. Y0 x
if(st==0){
/ K. d6 P: u) c6 G- j3 m3 V( L Display_temp(&str);
+ K" g+ t( G* v1 O flag10ms=0;2 A" Q" e6 r# F5 ?* H! G5 v
}8 H3 g& s* S% x
else if(st==1)7 D2 A0 K' g- @) V
{
9 q2 u" F- c/ c. F Display_hum(&str);$ B! E% Y* ?( w
flag10ms=0;
# q. l$ E. ?8 R7 l2 W }# L$ u% h @! E! H. F W$ ?+ r
( k/ P; {" b2 }( ^" p- ] u4 i
! [. I! Y F' J1 R# p+ O9 z
4 B, _3 r V' b; Y
. b8 N+ Y( b- v$ h0 B! V
}
1 }% G( S; J# f' H; q. }1 h% Z else if (flag1s) //每秒更新一次温度、湿度1 J: ~/ z2 N: I- |# l
{
7 W, {9 d3 ?% j( J9 K) C7 _ DHT_Start();9 ]% e5 v( S- ~ q. M
tmp=DHT_ByteRead(&DHT);
9 n A9 N9 ~ b$ D/ i if(tmp==1)
' i, g. l( w+ q6 E0 S& O: p* f {+ {/ u' {3 \, Q+ h6 F
2 u' r8 E4 \% P8 E& h% f
: ^# i4 D" v$ { ]5 g
if(st==0): `5 J# {$ |! g J, w" x
{+ ]. w* `1 v4 X$ d! k
str = DHT[2] ; //温度( K9 k7 A% i7 Z& v5 V5 e
Display_temp(&str); : J! g0 z. r/ B8 |2 g1 M- }
flag1s =0; //标志位清零1 ~+ v0 ~! A3 l8 @) T* j
}" X- [. a2 \% R" k w, ?) r
else if(st==1){. Y( e+ E1 |% B3 }. B7 y0 f; k
2 Z- j- b/ X8 N, M( J
7 E* Q6 Q- Q( S! v- l' I4 P
str = DHT[0] ; //湿度
% U/ C' ?( v* J5 R) F( z Display_hum(&str);
- h- C2 q' B( M ^* Z5 c( A flag1s =0; //标志位清零
( e' O _- p& k0 Q Y7 y } K! W/ I6 ^! U' h- v, n$ c
}* [& \) Y/ g5 e9 x
4 |6 G" B' y$ J# [: {7 B# w
: y7 y7 @4 O1 j9 ^8 S- G2 Y
* B6 U6 r8 P2 {. k$ Z2 E8 r3 {0 `5 U
}! R7 N: ]( P& P, n6 q
}
0 L' ~/ j9 L( D5 T- l- X4 \ [9 a if(button1==0)
. ^6 i6 M- J( B& w7 N0 x7 ? {# n% T! j$ |* e
delay(2);% K: e5 h9 i5 u2 Q9 D+ ^0 i* X
. N% F# {4 z1 ^, O% ?7 _) v% ?% i+ x if(button1==0)
1 l6 x& D% N3 ~, ]9 j {
. m! `' X) z% Q0 V2 y ! Q9 C: |* ^. u6 P
mode++;
. m+ c% w( }9 p& ^ switch(mode)
! B% [: i* l; l$ ] p; G/ R {
, d7 @8 s# r$ V; r6 a2 k- h case 0: st=0; break;5 {" P! _* i" ^1 c
case 1: st=1; break;; b2 k7 D( O9 C+ |# C! M, ?
case 2: td=1; break;
% A- I# u- ?0 H, T( R* @ default: break;
$ b" Y) E. @6 Y' _- B0 M }6 B2 d2 f9 d2 P
if(mode>=3)
& ]3 r) Z: k- t, o {* G. B) E, K/ O! d/ a3 L a) {' z' p) i
td=0;2 q* Y6 [* p$ U' h0 S. P& ]3 |
mode=0;5 K: m5 }9 Y! H0 S1 p% o
}
$ L+ g0 b* y2 j5 V while(button1==0)/ y$ D$ d, N8 i) b
{! A" t' }1 _ Q1 R
} y! A- y. E- Q0 k: K
* k. p/ y% F- {) b
; d" M1 g ^. F' S1 e# w9 W* A8 ~* z
: B$ g$ L8 @# a) O% b) K$ N3 c& ^$ M' I6 }; r7 x/ B
}; N& T- X' Y6 q+ r6 w# _5 Z* S& H9 Y
5 {1 |5 `+ d- y7 _; B
9 a8 K! Q# @" [. W
}
) K" K- i- Y3 V; C
5 P4 I* }) w) Z: E% a& o7 [5 Q) \# t9 T" \: Y( I ]+ ?, S
2 ]9 }0 w5 w/ K( y! y
; a2 `2 p9 J0 g0 z- Z$ g
% \. V2 J: L' @6 ], l/ [3 @3 \
) R* Z* O6 V9 C, V }
0 f- H6 [8 y R/ c5 [}
j- O' M3 l$ i8 P1 I: P9 Z
4 j7 Q" N- L* h% O7 e
; O6 x. P6 y5 Q: U- o) q8 T, z/ E; \2 M3 W q+ }+ W
* p o# n8 ]! s+ @ G/* 配置并启动T0,ms-T0定时时间 *// t- f, c# ~% V. |9 y
void ConfigTimer0(unsigned int ms)
/ h+ l q* y/ c{, l6 U$ }% E2 Y4 }, d
unsigned long tmp; //临时变量
! t. B5 v$ m5 x3 | 2 j1 N9 W }$ G3 W! h
tmp = 11059200 / 12; //定时器计数频率
9 w- m( W" o B' J) K( I9 f tmp = (tmp * ms) / 1000; //计算所需的计数值
+ G4 T; n" M, o0 K) l' G0 N tmp = 65536 - tmp; //计算定时器重载值
) N x$ ~" r" j9 i) H7 R! V, [# R tmp = tmp + 12; //补偿中断响应延时造成的误差
+ ^5 q/ \5 ~/ Y$ k# _ T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
6 ?- l' |# A6 Y7 R7 D/ I) ` T0RL = (unsigned char)tmp;
& T1 w7 k% ]! ` TMOD &= 0xF0; //清零T0的控制位8 [/ b8 ?6 K* k
TMOD |= 0x01; //配置T0为模式1: R! b7 |4 a/ X: ?! h, c
TH0 = T0RH; //加载T0重载值
, v1 Z7 i0 ]6 N+ R TL0 = T0RL;
9 g& \) z: A& R7 C* b' L ET0 = 1; //使能T0中断
- L+ e/ T6 R) u6 C Y. i/ d TR0 = 1; //启动T0
?# U$ \& L! }0 S* ^# j}
6 _# v- R. Y, h0 b4 t/* T0中断服务函数,完成1秒定时 */& [0 V. N& @9 ?5 D# h6 m
void InterruptTimer0() interrupt 1) m/ g% D, G% u2 ~- H& p) _. e
{; i8 c# S* f6 Y3 n. x
- i7 R$ \3 F. m- `9 p2 S
% Y; P8 A+ ~% e/ Q TH0 = T0RH; //重新加载重载值
$ ]+ b& \; }* F; c. }% y' ] TL0 = T0RL;
( r" K: K* e! O% f4 g tmr1s++;
( \5 \: l- h' j% Z sdd++;2 \; @0 f1 K, ?: u$ }+ g
tmr10ms++;' \: @4 d. u9 p: {
- ~. l* v% j+ H. ^# G2 ?
. P) ]: x& b* B2 p6 K
if(tmr10ms>=1) // 数码管刷新频率6 ^) c' @- j3 w% w# P+ M
{
6 N' e, @; A+ f" V& x7 d& ~ tmr10ms=0;& }- e7 ]1 t5 m! v! N! H: |5 O
flag10ms = 1;6 U# g' n9 Z$ |8 E8 I5 Y" _$ u
}
7 P. e6 _, t: H* \- r if(td==1)
$ @' V& ^* q# I8 E* o3 R {- B) x$ |. g9 v* D; J
if(sdd>=500) //温度显示5s 、湿度显示5s
' N6 Y: ]( \4 O9 \$ g; n {. }4 r+ N8 v8 r, L5 n: x. P; J9 O6 ?
sdd=0;
( Z$ I/ i* M3 S+ `0 e4 k if(st==0)) e: P9 ~7 G }+ x
{) K8 }! n5 b; g1 c% L
st=1; c" P6 `4 I: M( W' L3 r3 W
}
6 f5 M, V# `1 Y/ D% B else st=0;3 | `! A4 o2 U# Q* v* m+ C2 O, T
}
6 e+ I9 T* T( K, _- N5 a+ R }
, v/ y, E0 U, I2 b( p if (tmr1s >= 200) //1s 数据更新频率
; ]; B& o6 ?! W/ f {6 ^, T7 E' \: ^, y
tmr1s = 0;# j$ k" S! U9 e9 g6 G
flag1s = 1;
3 t( [8 Z: w4 k5 f' p4 p, k: D }$ I" o; ?, w. z/ P5 z
& y2 e( @" S$ A1 `
) e2 f4 d" w8 V9 V, {6 t; e # [6 B% i7 V, u6 W2 J# Q* _% c
}
* Y1 ~: L& x* a! A9 [* k* T6 x5 w4 l7 ?- N
7 k; W! D ~! N4 }3 r& K8 c$ ^8 P% h下载:
9 {# P+ g( z+ n# s0 l7 R" t+ k/ \8 j J7 G& ^
' Q# R6 V: o% \' \) l |
|