高级会员
主题
回帖0
积分603
阅读权限30
注册时间2014-6-5
最后登录1970-1-1
在线时间 小时
|
楼主 |
发表于 2020-12-4 09:56
|
显示全部楼层
本帖最后由 leishidianzi 于 2020-12-14 08:44 编辑 . o- N# A S6 U* x5 k5 }7 I1 o
/ m1 \8 \( [: A) e6 n9 P
& [" b: |3 c y7 T( l0 _
/***************************************************************
' }& P" v* t5 U# t# Z# q ~ 名称:基于51单片机的超声波水位监测报警系统
% `8 T1 T- y* @# e4 L7 C 单片机型号:AT89C51% O1 o& z4 Y/ f$ W( D) N9 Q
单片机设置:时钟12T,晶体12MHZ
( A/ Y; B) w: p7 t( ?+ A1 B. S+ Q 注:修改增加水泵控制和排水控制,即双继电器
) X! @/ e( G0 ^0 v***************************************************************/* v! {# \3 {. M
: {+ V. E, {; P. H! U) o#include <reg51.h>! u6 g. |1 i, ` M& a
#include <intrins.h> // 包含循环移位:_cror_
9 l. M4 U8 Q$ V) J1 [#include "main.h" + x' @# I. ]' l$ ^( f- s0 K5 h0 c
//----------------------------------------------------------------------
7 I, u! { O+ a- E0 p5 I
1 J( j# N, S' y& I. puchar code TabNumASCII[10] = {'0','1','2','3','4','5','6','7','8','9'};
: i4 G m% G- { P2 U6 x
+ k4 x) W) g7 I" L: nbool g_flag = isNo; //用于标记超时(65.536ms) # Y& ]+ `0 D+ r8 Z$ p$ K& c0 @
bool g_flag05s = isNo; //用于标记0.52秒
6 m) d$ Z; ?, }! Tuchar ucCount = 0; //用于计数0.52秒 6 j0 x; O. T- V3 Z! W2 k
. x# ]6 |. U B; B) S
uint uiH = 86; //设定的最高报警水位 H5 h( r+ A4 i# U9 o2 ^" A
uint uiL = 73; //设定的最低报警水位 L' D. R% x' H# p/ p5 P6 j# f n
uint uiD =156; //检测探头到水库底部的距离 D
; I8 k. H. j3 {4 d6 O0 i' L4 [/ s0 T3 F8 O2 w+ H# U
bool g_flagSwitch = isNo; //控制阀门连续开启间隔延时(保护)标志- ]$ V9 H- l, }6 Q2 d
bool g_flagBeepTimer = isNo; //定时提醒标志7 o$ l: W6 @- ]4 {
. o8 f/ i( }; `8 j3 m' R
- R) ^# ^5 U( W& `- H x& E//-----------------------------------------------------------------------
- g# r/ m& j2 b// 延时10us6 B2 @; y9 t+ @( k% h
void delay10us(void) //@12MHz5 `- t+ ~* `. k1 T4 Z" f
{
% @- G1 {" f8 p6 i* ]4 J6 J2 U unsigned char i;/ @8 v4 v4 p! A. H
2 j) F) F! M* k0 p: _! [
_nop_();
( H% t- E1 }# N' a$ S4 w i = 2;. v; |* b+ d" Y3 _7 K
while (--i);+ ]1 u& Z6 f6 U
}" L- W9 Y8 y% @ s6 j, E
+ S. u. ^+ n. p6 v4 D// 延时100us- N- M& z, l5 u
void delay100us(void) //@12MHz
3 z' s, h& q) g{
: i; R& S+ L# p8 I uchar i;
# V1 ?4 P* r* i+ h6 S- `( F8 }
5 ?* s9 l4 }# z B: N _nop_();$ m* k; j8 t# v- Q) g
i = 47;# m* p) |# i1 W/ O5 k/ u2 w
while (--i);& k H8 D1 T4 g7 |" v+ I4 x+ U" H
}+ z+ Z! _+ [ a4 {/ V
7 z5 ^9 P! j l! j4 q `" _0 j, Z// 延时125us" q& w6 `1 ]2 ~* s6 H
void delay125us(void) //@12MHz- V6 B/ N/ Z: `, @5 t6 g4 a
{
$ J. n8 q- Q% n7 p0 x# F$ c# D unsigned char i;
! L+ t( z$ v' C i = 60;# l- o. v; W9 ^. T! I" L
while (--i);
' A+ F8 B, O4 ^7 |3 V}1 x# ^, c5 N7 |! f
4 E9 h6 n, U3 M4 G// 延时5ms
8 i k4 A9 [; Y/ v, n, k5 P7 O+ nvoid delay5ms(void) //@12.000MHz4 S& A+ J2 G/ H" o4 B& A
{
5 p1 }( x1 }. V+ H, s# o7 w unsigned char i, j;& H! p4 T) {& |
, f; p( u [9 d! Y9 _" u: o
i = 10;
/ P" P( V; d+ l k7 w' O0 v j = 183;
# p: x- w* j3 n0 g F do, f* |6 i8 H# v1 ` [
{
& ]6 ^# [6 x4 z" V' ~2 @ while (--j);
+ D! n, c7 B7 C: ~- s2 h/ k } while (--i);/ n \" X) \3 x3 Z% U4 J2 ]1 l
}7 y6 [1 X* k; B/ L- a" D4 J! S5 |. L! S
5 j. }. ~6 F; ~0 U* i ?" k
// 延时500ms6 S. \ ]: b7 h F- l
void delay500ms(void) //@12MHz
3 W$ c) ]( w0 r/ O b' J{
& Z- c: r* Y3 [0 e unsigned char i, j, k;) N1 `2 o, j1 ]( l5 B7 n& U' L
9 v: v# }( F$ P# ~& n- i6 I6 _; S
_nop_(); t* @: c7 h3 L4 J1 d% x# n0 K
i = 4;! q* K) i1 B- E$ H
j = 205;
4 u# Y, M$ l! K8 n( M6 w5 ~5 Y7 V k = 187;
6 L0 l0 A L. |, B0 q) a" Q ? do
, k/ p' e! P9 D+ W/ @ {9 E6 E8 Z, C, ?' p9 o3 |% M
do
+ N7 @0 b) F! U7 K3 G {5 t4 x+ V0 [- x7 F0 d; c% M3 N
while (--k);8 G. J) D, j. _8 u3 Q
} while (--j);7 q8 T4 Y" M% M6 f) ]( n
} while (--i);, X+ @: H# [+ m! _
}3 ~3 K- |% K* p$ @
- l* l( l. ?1 @6 h0 f//-----------------------------------------------------------------------
/ k9 _& s* b1 H; o0 E% _//初始化IO端口 - F- a4 ?. l+ } v! U. D
void initIO(void)
* h, q( R' x+ A" y* I& G% Z# g{4 c6 I, P9 j3 m# [, e9 K
P0 = 0xff;
# W X: ^8 D. v6 p% l6 r0 @ P1 = 0xff;% ?4 u) n! V% d0 O
P2 = 0xff;
: H7 t% N0 Y% M+ b( w P3 = 0xff;# b/ f4 m* A4 l; f& q% s
}
$ l' c- e2 M% g
. l: u8 m9 r# ~8 b* [$ C// 初始化定时器0,定时器时钟12T模式 模式1,16位 @12.000MHz; t' X3 p5 @* a' u+ @ @6 W! c, h
void initTimer0(void)
7 P( d7 l* _' i# j( C% \{- b7 Y2 f' E; k3 n4 N {" j
TMOD &= 0xF0; //设置定时器模式
$ N; }/ q2 J u4 D' { TMOD |= 0x01; //设置定时器模式3 U3 ]9 _; X8 U4 J4 R, A8 h
TL0 = 0; //定时器初值清零
/ D; ]( d8 c, S7 Q# X% t TH0 = 0; //定时器初值清零. h8 x) ~* J6 R: _
//TR0 = 1; //开定时器0
, T; P/ |+ L. ^, X: K8 t ET0 = 1; //开定时器0中断
4 i* q9 w& @7 u. m2 |2 k EA = 1; //开总中断 8 x; M# m( R$ {) W" V
: j1 a/ [: d( B! Z& j" t* y2 h$ K2 f8 `}
7 n M; F3 r( p2 i4 F% Z6 a: M% G
' C2 k% \9 C/ g/ o: a1 M// 初始化定时器1,定时器时钟12T模式 模式1,16位 @12.000MHz9 ]" S' e5 ^) i' {) u
void initTimer1(void) //50毫秒@12.000MHz! [; j4 V) n8 b- c i+ A
{ / l$ L7 S% n- Q
TMOD &= 0x0F; //设置定时器模式 D+ P6 ^8 f: s0 f9 V$ n
TMOD |= 0x10; //设置定时器模式4 g! g) G9 }- U
TL1 = 0xB0; //设置定时初值
; W( |! S* A' |. w+ j( N/ B TH1 = 0x3C; //设置定时初值
( s) |+ S) P5 ~$ |0 m: R. o TR1 = 1; //定时器1开始计时
# }6 ~9 o8 M* l% s ET1 = 1; //开定时器0中断
- y4 P* k- G5 O' H: |( G}
9 `* H* t' b' s3 K: T! |% f3 E8 ]1 s3 p
//-----------------------------------------------------------------------
! ?: M' ~& Q! R& D0 Z//定时器0中断* s' o; Q; ~& u! M7 k. i/ Z; @
void zd0(void) interrupt 1
8 U* }. S ` J8 c+ C) Y' S{6 S/ b: p. [2 C: z P: B I# |6 Q- b
& x# u- x h; q% \! w0 ~ g_flag = isYes; //中断溢出标志,g_flag = isYes超过测距范围
0 Z0 B" w& ]$ }% L8 f' V* t; D if(++ucCount >= 8)7 Z X3 Z" V3 l9 h' m
{) |/ f2 r$ j* J
ucCount = 0;
`: H9 X# ?! T- M/ X' M* ^ g_flag05s = isYes; //g_flag05s = isYes定时0.52秒到,用于测量周期延时
' J( Y: ]7 }! Z, g. |* x) [" q }% @# S* I( i" t5 N, M/ \
TL0 = 0; //设置定时初值
( f }5 N0 v, w9 m* ? TH0 = 0; //设置定时初值
|: u% n0 c+ z6 [3 W 5 T! f: P/ J- W8 _! v
}
: c# P3 N& g. |
0 @$ x- `- O9 f, W' K6 d! V0 M: E) M8 [2 ?# K" W
//定时器1中断 定时50ms
8 M* m+ S( Y8 p# D, bvoid tm1_isr() interrupt 3 using 1
/ H: L) D3 h( Z/ [# K- A- x{' D0 d3 q u6 ~$ e
static uchar count = DATA_switchTime; //50ms的200倍 = 10S( \0 v5 l' ?: a4 g1 y
static uchar uiCount = 1200; // = 1分钟 . Y! a! U4 Q! K- `& G
static uint uiCount_BeepTimer = DATA_BeepTimer;
5 N0 C- P( P- z3 Z% S/ l! F1 f9 ]6 o( o" c
TL1 = 0xB0; //设置定时初值
! s% ~) e& z0 F. W& s TH1 = 0x3C; //设置定时初值
}( f; m2 V0 f. w- z9 n, N& B. a+ S3 g) p2 Q1 K
if (g_flagSwitch == isNo)
R8 W* j2 b/ T; s {
' {+ |6 Y' v7 Z' y2 c& q) s7 }7 J if (count-- == 0) //50ms * 200 -> 10s4 J5 W8 H' y6 I( s' K3 c# G
{. s6 G- Z3 D1 s5 |1 X4 u
count = DATA_switchTime;% K" ?& ]1 @5 M% }6 x% O2 c
g_flagSwitch = isYes;1 s8 K2 i, Y5 V5 r ^! X/ Y
// TR1 = 0;5 c' ^* i% C5 [! t2 z. a# M6 ?
}; P; G- g. l& \2 x/ g/ S' R7 Y/ `/ E3 ~
}
5 b* G' H1 N5 k% e% \" k
, f* h, r/ ]' q6 s; H( U1 t if(g_flagBeepTimer == isNo)" _* t$ `1 E& g3 j6 F
{
' R7 e. r0 J9 S) e/ i" M if (uiCount-- == 0) //= 1分钟
. Z }0 a% F+ U" ~2 B0 d {
6 l: S4 r; ~7 {. G uiCount = 1200;
, D3 e# r: N- l' {. a if(uiCount_BeepTimer-- == 0)- L7 o4 X }' j6 M
{
L/ F6 t2 h, N4 G6 Q4 k) n @; r" g1 M uiCount_BeepTimer = DATA_BeepTimer;
4 h6 O' Z# \; j* U# f' g' H3 Q g_flagBeepTimer = isYes;" h, _. e0 y6 J" g4 s2 |
// TR1 = 0;. Z8 P* x2 E/ T8 _6 G" o
} - @" h V6 i8 l1 m. }! _7 _
" k; Q1 m/ _. I$ W3 D* J }
' U8 I1 d+ w f) o
! C6 P/ m, I( O5 a }9 d9 {4 s# R1 k6 c2 [/ p
}
6 t! \ v. W# g. A4 S
6 s# M# | U* U0 E$ z//-----------------------------------------------3 f# _, p' a0 Y1 ]& M
4 M5 a. S2 R7 L; }- ?' [
( q8 y. e: |" K$ @( P% Z3 S' L7 p, a- K
# h6 ^2 t1 e3 G( G, H& H# U5 L# _5 r% @ ~2 S8 D4 x
//外部中断17 m% }' Z7 {% r, ^5 d( p2 ?/ A5 b
void exint1() interrupt 2
0 s! l) N) H) M, H9 b{
, Q" @0 O6 ], p EX1 = 0; //关闭当前中断3 s0 q! G8 v7 W- }" Q
TR0 = 0; //关闭时器0) p0 }; h4 n2 r
$ I# e6 [8 ^) _7 D" @' s8 P$ q
}
' G0 m0 F+ C, ~6 d( S3 h9 N2 l3 H; y//----------------------------------------------------------------------- } r. D/ E9 l
' Q; |- J' y i0 |' ~4 l
//读LCD忙状态并等待忙状态结束0 H ^/ }0 G. D2 t+ _0 D7 X
void LCD_waitNotBusy(void)
; I* n [+ w( k3 P' X; l( ~7 Z; K{
5 z& x7 D) G7 N IO_LCD_Data = 0xFF;
% q. N8 [: O* ]) @ io_LCD_RS = 0;; v& w- n$ b; ~) U' r! W
io_LCD_RW = 1;8 F1 I- x, Z$ u: }, r: t
io_LCD_E = 0;
/ V! l: J, l( Z7 r7 _9 [ _nop_();2 W G' L' k" S: W
_nop_();
: L4 d2 Y3 F4 V io_LCD_E = 1;
" r: D3 a, Y2 \# C+ ?" n while(IO_LCD_Data & 0x80); //检测如果是忙信号,一直等到不忙
% T: d8 F" x, V7 Z9 W4 f: n; W" F}' p) R2 F6 d" g# |$ P
" d( ~" U6 v2 c. Q$ |8 P0 ^
//给LCD写指令8 Z' K, Y1 ]# D" h/ x2 K
void LCDWriteCommand(uchar command,bool ifReadBusy) //ifReadBusy = 1 时先进行忙检测% |1 p0 u" W0 f
{. O: D0 `2 N# T' V S+ \
if (ifReadBusy == isReadBusy) LCD_waitNotBusy(); //根据需要检测忙
6 ^6 K$ t9 H. @9 A: l IO_LCD_Data = command;
1 ^2 [9 a% O) j1 A io_LCD_RS = 0;( [) p( M% d# ?& M0 h* A
io_LCD_RW = 0; 1 `( |8 l- B) o: |
io_LCD_E = 0;: r Y+ y% X1 h( ^
_nop_();
; U. y3 [3 l1 J" B _nop_();& h0 y7 o' C4 A5 _
io_LCD_E = 1;
. w; m7 K# y3 F}2 B- @. o( W) p# J
, l7 |" F! ]9 x4 {" H6 w+ n3 o//给LCD写数据1 G, ~; A, j/ B# D& C. A6 Q, U! ]0 }
void LCDWriteData(uchar dat) / m" ]1 L1 b' j H
{) \- P3 d& J3 r W0 w
LCD_waitNotBusy(); //等到不忙
4 g6 O x6 g8 y: h% K" P$ P" P IO_LCD_Data = dat;
% @9 V3 R6 J8 `# g; g" k, c5 e% c io_LCD_RS = 1;' I& Q& w/ v* C1 M# C
io_LCD_RW = 0;
9 p" m1 s! {; x! }7 E2 ^2 g io_LCD_E = 0; $ k7 Q5 g- B3 [; ^% ]5 R
_nop_();
( F9 _0 [& O' i# V+ i _nop_(); F `5 V {/ l
io_LCD_E = 1;
' z; ^4 C9 h' B8 R0 Z}
/ y/ r; J1 p. k+ \5 f) }0 H( H: B4 o" r; c/ s
5 V& k8 l9 o. {5 d, i! F4 [
7 [5 F- Z4 E0 G+ S
7 c S) M; |: K5 B+ _6 O3 k% A/ N+ U// 初始化LCD1602液晶显示屏9 X# b3 p9 c+ f7 N0 o; G: z5 E
void initLCD1602(void)
3 V/ V8 V/ }) N* O* \% K{1 V, B; ~: E6 N, G6 Y! r
uchar i;
: n% D5 c, c; ?9 ~) O! Z IO_LCD_Data = 0; // 数据端口清零
' s, {) q7 v4 `: C for(i = 0; i < 3; i++) // 设置三次显示模式
0 R3 p: P% C+ b: F9 e9 p* A9 x {
p# k( R }, o. \0 ]( f; @4 q4 p7 l LCDWriteCommand(0x38,isNotReadBusy); // 不检测忙信号8 a2 r3 p6 K J$ \/ h
delay5ms();
+ x$ s" I3 q6 \+ |, ?2 |2 \6 F }2 N& T( J6 P0 P! o2 v, [ i
$ U) D0 Y( k! T3 U! l
LCDWriteCommand(0x38,isReadBusy); // 设置显示模式,检测忙信号
5 p% j% ^4 _4 x3 z! ~! { B LCDWriteCommand(0x08,isReadBusy); // 关闭显示# \- N4 o7 V- S4 Y: `& n4 G
LCDWriteCommand(0x01,isReadBusy); // 显示清屏
- N# v4 t, S/ \3 }$ I9 ~ LCDWriteCommand(0x06,isReadBusy); // 显示光标移动设置3 T5 s8 ~' N! q f d
LCDWriteCommand(0x0F,isReadBusy); // 显示开及光标设置% R d* z. v, ~9 O8 ]
}( h3 D$ @0 O0 o5 l+ r
5 ~+ @$ ^' R& L# l: z, C$ M
, L: u) c( s& J4 v" g- {, b8 ^0 L6 [$ W' l
//按指定位置显示一个字符
6 f4 b: [% v, ^! \, A% ?' Xvoid putOneCharToLCD1602(uchar line, uchar position, uchar ucData)0 W5 J6 d" A! B/ B; A
{! H# m' l/ h) C/ w3 u" t
3 J1 l# V7 v" u( Q9 H; N0 t9 w$ a
line &= DATA_LineMax;% A2 a6 H, k. Z1 d5 `5 _7 b
position &= DATA_PositionMax;/ X$ p( v0 [% M1 J
if (line == DATA_LineTow) position |= 0x40; //当要显示第二行时地址码+0x40;( Q' B% N) d6 E/ c
position |= 0x80; //设置两行显示格式 D7 = 1;
! X0 P9 w& I% w1 s: i LCDWriteCommand(position, isReadBusy); //发送命令 设置字符地址1 z7 i# K7 x1 F" P
LCDWriteData(ucData); //写入字符的数据 / `0 i" j3 I7 V5 ?: D4 @* c. W
}
: q& \/ B( C- T, J: n- n9 {3 J/ F
. j0 b) K) {( x( p" c5 S. ~//按指定位置显示一串字符5 g0 I) U% M7 k2 ?
void putLineCharsToLCD1602(uchar line, uchar position, uchar count, uchar code *ucData): P# i% l9 O$ D+ l( J8 m2 y
{
+ n/ B/ ^0 U' p! j/ c0 u0 z uchar i;
& u3 i3 o" S2 k o8 a for(i = 0; i < count; i++) //连续显示单个字符6 n0 h1 y! b L+ i6 s! D
{, j3 Y, f8 d9 {( y
putOneCharToLCD1602(line, position + i, ucData);
0 }( E3 u. ?) ^; R }9 n' D3 K9 V8 n7 h, g9 m
}
- \3 D p. `1 h' g1 [% u3 F( Y
* \: h7 ^$ C* k5 p8 ?: k# a5 t' }, R' s' b* r
//按指定位置连续显示三个字符(三位数字)" E: u* l7 C5 F1 y/ j
void putThreeCharToLCD1602(uchar line, uchar position, uint uiNumber); x3 O: i6 Z8 J8 K
{- J0 l9 h0 g$ \1 }5 M
uiNumber %= 1000;
7 H# m0 ]6 }- o# W7 Q/ h0 z ? putOneCharToLCD1602(line, position, TabNumASCII[uiNumber / 100]);: n0 U- ~2 V1 _5 F$ B; j3 U9 j
putOneCharToLCD1602(line, ++position, TabNumASCII[uiNumber % 100 / 10]);
+ P) J- m8 }) _8 U7 C ^ putOneCharToLCD1602(line, ++position, TabNumASCII[uiNumber % 100 % 10]);
! A& ]0 ]" o' M4 E 0 A% J! a2 C7 m, A& ^
}
1 w0 H- E& a* j( e( n& ]/ i3 ?
1 n: S. V: g( F* z3 q2 ?2 p
7 a ?- P) c* z$ s9 v0 R1 {& m; D1 }4 D
* A3 T; P% H2 W7 F* N0 O5 m( s9 R// 按键检测子程序,有键按下返回键端口数据,无键返回01 X( B, f* y: C, D
uchar GetKey(void)
% U8 S" c( {( W- {$ p{ # z* I; i/ i$ W+ L, ~+ I* S( h" z6 @
uchar KeyTemp = (IO_KEY | DATA_KEY_ORL); //获取按键端口数据 L" t& v% {& N1 V" Z, f- ^
! I1 Z# a, Q! Y if( KeyTemp != DATA_KEY_Null ) // 如果不为空9 p1 N( c8 W1 A
{
) r- L2 k( W: ~) P uchar CountTemp = 0;9 J% v; \" I( J* M$ J
do( R) r, I0 _4 W" c
{+ V! h- a& H8 s Q3 x- i+ e
delay125us();
# B/ N: M- O: a4 s if(KeyTemp != (IO_KEY | DATA_KEY_ORL)) return 0; //在延时期间检测键,如果不稳定保持则退出
5 J' }4 y) a2 \: \ ' J" Z( r+ Q& v# t* K
} while(++CountTemp > Data_Key20msCountMax); // 延时20ms去抖动
- N w: E( x8 {/ V
V' ~ r, P/ S while((IO_KEY | DATA_KEY_ORL) != DATA_KEY_Null); //等键释放
" f. Z8 {5 _( z 8 i" S1 ^& x2 Q/ y* Y
return KeyTemp; // 有键按下返回键端口数据: \- o, |* I) z' d7 M
}, q" m, T2 |& f$ t* H
7 G) F) j' n1 C; d& O3 n; _: ^
return 0; // 无有效键返回0. ~1 m1 _; R" i( Y4 a) [
}
# a. ^6 `. O7 h- U' S$ [6 S9 h6 l7 ^7 _* k; g: S$ j! V
$ D) _' c" Z" x/ q
# b( D' }) E- D2 K! D R! }- v//加一0 Y n/ ^0 e: t$ M% S
uchar INC_Number(uchar Number, uchar Min, uchar Max)0 ~6 t4 {% n" X# |& K6 d" h, T- p
{
" G4 r- ~1 Q6 v( _ if(Number >= Max) return Min; else return (++ Number);: V" V: M! z Q) K; }8 O4 i
% \ H E) O& u5 k6 M9 T
}
. l8 h7 y+ M, G
?% N% O4 j; d* d+ {' O* ?( l6 s5 s, w//减一- b7 N- o$ @; g$ U
uchar DEC_Number(uchar Number, uchar Min, uchar Max)
" @/ j) x: t+ {2 C1 j/ T' C/ f6 d, |{# G# e7 M2 z/ S0 \9 U g
if(Number <= Min) return Max; else return (-- Number);
" ~$ i$ p6 Z) l! c' B I+ X7 _ & z6 S) G9 S8 M7 M
}
) {3 g9 {& m, y& R2 ~) d* z) E
2 ] E) K2 u6 m. s// 检测到有按键后 这里执行按键任务 " I4 S4 ?7 y* s$ \* G3 S) ]
void execute_key_task(uchar ucKeyValue)
% C7 c2 V% P; l! O5 p6 L+ \8 |{# x3 L. S7 g. g4 ~0 b1 ]
uchar state = 0; //定义调整数据的状态变量/ |0 g# b' ]# R) L
uchar keyValue = 0; //定义键值的临时变量
8 I( n" Q4 J+ p# f: x ( }5 e+ L* n5 q
if(ucKeyValue != DATA_KEY_Set) return; //不是设置键退出
6 n8 ^$ H+ z* ?4 B ) G7 i5 Q; Y2 P) a+ @. Z3 C
//是设置键继续-----------------------------------------------------
3 [# s8 {# }3 z* R9 {
2 T7 P0 N. |: ~+ |+ x7 M' q putLineCharsToLCD1602(lineTow, 8, 8, "C:000cm "); //清零显示当前距离CURRENT " ?) C- l* X' s9 I& e) q4 ~
putThreeCharToLCD1602(lineOne, 8 + 2, uiD); //光标调整到调整总距离(检测探头到水库底部的距离“D:000cm”) , F8 ]( h7 k0 O4 d& G C8 `9 d7 D
/ H- j1 L$ I& M
while(1)+ t+ Q" a; i: }4 U0 C4 G1 A
{) P# R) b0 I( d4 L
keyValue = GetKey(); " X% p) j, c, F3 k
if(keyValue == 0) continue;' K! O- B9 f$ n8 Q7 m( v, E* ^; G
$ ~, f2 m+ o2 P2 o8 y8 h/ W
switch(keyValue)/ Y. ]# n" t/ Q0 b. Z5 [
{3 H6 b( _ Y) ]8 z& v6 q
case DATA_KEY_Set:
: c$ j2 m8 O/ ^: ] I% Z8 _ {
) x& c* A" |* U8 l // 如果按的是设置键,顺序设置总距离D——高水位H——低水位L——退出
7 |2 G o$ \" b( B+ ~# X7 @; E: H switch(state)! N5 j) ]6 [# m0 S% A3 y
{
4 M. u! H0 w1 c6 K- G9 {0 @ case 0: // 如果是设置总距离状态,改变为设置高水位状态,并显示高水位,实现移动光标到高水位后面9 p' i0 f @) ~$ P' {+ d% K
{% A5 |5 O+ G/ \, U% O/ u( N" k
state = 1; 9 b1 L3 N4 j- c `
putThreeCharToLCD1602(lineOne, 0 + 2, uiH);
, W3 e9 K# T4 U( N$ B3 r& D }4 K& s/ h+ i. s/ T% ?1 Y
break;
/ W1 l! Z' {7 H; C2 F case 1:
& M% }/ V) I4 b& b5 k% h9 | {
5 v" c6 A! _) G# T2 g uchar tempMax = uiD - DATA_uiD_Min;
; g* W/ ~* M3 H& k; m if(tempMax < 2 + 2) tempMax = 2 + 2; - {8 T, G, K$ a
if(uiH > tempMax)
4 S" y; W) n6 k6 B$ A {! }9 O( y, t' k7 N$ n9 \5 P2 W2 Z2 ]
uiH = tempMax;
; |; f# F" A' k0 o. s( E% g putThreeCharToLCD1602(lineOne, 0 + 2, uiH);
+ s" B; m. C* V }
- o d/ s! G2 S- R1 p* [/ b else if(uiH < 2 + 2)
- _/ L1 ~! e7 \: W3 \ {7 t( @6 K: B: o, R& W1 u5 z/ U+ p. T
uiH = 2 + 2; " g3 \; u5 _2 v. t9 n4 z
putThreeCharToLCD1602(lineOne, 0 + 2, uiH);: c4 d/ v9 p- @1 K: P% `$ {: A
} 3 ] a/ |' P- ~: ?5 a/ T8 W
state = 2;! @" K, l" {3 e
putThreeCharToLCD1602(lineTow, 0 + 2, uiL);8 V: C7 z6 a9 Y1 U# H- `
}, Q2 W8 F# o9 r3 V
break; h4 P$ J0 f7 y9 L1 k- b
case 2:
, z2 S# v+ i% N8 f2 [, O {8 n ~+ r1 \& O# R, {7 u$ ]2 r
if(uiL > uiH - 2) + S/ C& u7 h0 [1 A, G* H7 n" o, {* U1 v
{
" n' L/ p& L& S0 F7 K, j) o uiL = uiH - 2;
; X1 o, k3 i/ O, ]$ w; @) I5 w putThreeCharToLCD1602(lineTow, 0 + 2, uiL);
5 D, _- p, F4 t+ R }
! q% A+ c( _4 l return; $ r2 V9 ]- A% x. r* h+ N
8 Y; M* p4 F: U4 H, _" S }
/ S3 q- R6 l# c( x; {" \0 a7 W break;
6 o5 {( E0 _: o0 }8 k }
4 |' c% f8 W- p5 X 2 g1 ]. I/ r5 \! b, C( _' i7 v2 U
}+ m( e8 s9 P6 R% |/ Y
break;
& f6 _3 B4 ^. [6 f' E // 如果按的是增加键,改变相应数据并显示
4 H) u) G! r6 E, Z5 g( l8 F8 |2 K case DATA_KEY_INC:) s. T" _8 w, u- V3 M4 N
{5 ?8 _! ^' ?# G5 S _; d- v
switch(state)
* ^7 c/ b& h- F' T( U4 p. w {
! ], o/ D7 ? _8 B& a- a2 k case 0:
2 k# a6 B. P. G# C, i+ Y( \ {, H% |4 M' z% u
uiD = INC_Number(uiD, DATA_uiD_Min, DATA_uiD_Max);4 B5 h1 l- h% R e+ L1 s* ~2 j+ S( T
putThreeCharToLCD1602(lineOne, 8 + 2, uiD);
5 m4 K9 ?, B% U' Y3 G* ^ J8 T- G" r9 t5 n }, z( A- V3 r7 n, u. N) u
break;
9 V5 Y4 b5 k. z/ \ case 1:
J1 y' R `3 G g1 Q% h5 `, N4 W {. r* C# J- @$ o" W- ?6 r7 i
uchar tempMax = uiD - DATA_uiD_Min;' L' ~1 S" L: D: q L
if(tempMax < 2 + 2) tempMax = 2 + 2;
# ]6 l7 |7 f: R) ?) f uiH = INC_Number(uiH, 2, tempMax); 7 m9 \) h* k# P W: N0 ]. e
putThreeCharToLCD1602(lineOne, 0 + 2, uiH);
9 d0 l2 I/ f7 j2 `% u; }; b3 y }
2 O2 M9 v2 I5 b) S. K break;/ s% n4 [% c$ ^8 b6 y" ?' \4 D
case 2:* ?# E n7 g( A. ?& C4 S/ |8 D0 u1 R
{
( i( S5 t# w" s, @, j* n& t% V uiL = INC_Number(uiL, 0, uiH - 2);
1 Q; F, V% S) H8 n$ g+ s q0 @ putThreeCharToLCD1602(lineTow, 0 + 2, uiL); " r: {6 X8 E1 T; Z
}
; k# j3 Q/ N( F8 }+ }, x break;. p$ M" H3 u) |8 u7 D
}; t- v4 q: w* g3 }( j. c$ L9 X
# e7 P2 O' P7 Z }
+ R: e, _& Q% \ break;
/ B1 D. O) t5 p+ u) d* R: M; d // 如果按的是减少键,改变相应数据并显示" r( @% j! N+ X8 d2 F1 x
case DATA_KEY_DEC:$ Y0 E) b1 p$ o5 M
{
4 ? v) g6 W& c switch(state)
) F2 i l/ d) @# O- o8 I9 ^1 W0 d8 X {
2 a" p, @4 W! r7 r1 I" `- G case 0:" k6 y4 r2 R; h& A
{# B7 g6 @* v. v
uiD = DEC_Number(uiD, DATA_uiD_Min, DATA_uiD_Max); $ I+ B; d+ [2 X! o9 B
putThreeCharToLCD1602(lineOne, 8 + 2, uiD);
- m) `8 h9 s1 m4 X+ e8 G# E }; a8 m& y/ }* {
break;
. X! p0 \7 E5 c9 n case 1:
1 m! [4 t! p& S* `( s {: E/ q: S! }: `. _7 D
uchar tempMax = uiD - DATA_uiD_Min;
8 [( _6 B+ V7 `" u) X7 o4 b7 v if(tempMax < 2 + 2) tempMax = 2 + 2;! h/ o( R: M- {( F
uiH = DEC_Number(uiH, 2, tempMax);
; c, @4 ]" g3 q+ k$ Z putThreeCharToLCD1602(lineOne, 0 + 2, uiH); : R6 e/ G7 ?& [! G
& r1 r( K9 z! a; F6 M7 l
}* @, @8 ~2 r1 ]" i/ [
break;* I( c8 Z; ?1 ^) K* Y8 r5 v
case 2:3 y/ \, _6 C- Z+ H5 @8 N* h& ~
{0 k: w4 p9 g: C5 p
uiL = DEC_Number(uiL, 0, uiH - 2);
6 t% H7 P1 k# F; Z3 m( @ putThreeCharToLCD1602(lineTow, 0 + 2, uiL);
1 u" q+ v) s3 R/ K" Q; o/ M/ m' s2 I+ w# D) V& s* j5 }
}
( g9 h W/ D2 ]1 T. P break;
) O+ a- J, e9 _# I* z: z& O* A0 z }9 b5 n) k& P k5 {
! e6 G. g& u4 d& r, P3 k7 B4 j2 S }
' ^! W; K8 N) ~- |; n0 N) j break;" b- y0 a3 p# \' I( L
! ~$ F$ a# @( E/ B# T
}
! w) ?4 {; }. p! {0 z ) Q4 C8 i4 O- f8 g
}
' |6 K) |2 o; {* C6 F4 R 0 y2 Q; ^. n4 o- u
}' y& ?. t& T: M: k) g+ w
m) T6 H5 Q3 P& d4 c# Y; e
R( L: a) X+ `1 G- ^, g( C1 Q! a2 m
* H4 @6 G8 O4 ~" X* p; h// 蜂鸣器 " @7 M7 R' n5 [7 r( f% l" c
void buzzerCall(void): J n" O* E3 @' _ `. ~
{, A' l! c. {9 ?. a; }
uchar i; u/ Q) p+ {- S$ Z- B; p8 G4 c
- Q$ R9 o, K4 C) m for(i = 0; i < 90; i++)) M+ P9 l% B6 i3 `( p" L2 ^
{
) H a* q# w, S. I7 D* s io_Buzzer = 0; v/ q5 N1 ~8 _% t8 G2 l
delay100us();0 m! k$ v0 ?3 s, g) @% ^9 m
io_Buzzer = 1;1 y8 D- t$ j |- Y% w) J$ T
delay100us();1 U8 G' ~( k/ c5 ?. [- W2 Y% w
delay100us(); " w: x h; C- H
}
) J; U# C9 J! Q, G T5 I( R& f) V% r delay100us(); 2 W% t M3 u1 ~; ^/ s! e" w/ t% y
delay100us(); 0 `: h5 A9 F, u' W1 s
}
+ r( f6 r$ }+ s6 e: {# T, _2 Q6 x+ p; j* b. w3 p7 [
//计算水位. F, A2 l/ F+ N( C
bool CalculatedWaterLevel(void)
" R2 t' X, w- a0 f- E# n5 m{
. k9 b- h* L+ x9 w5 Q uchar i = 8 + 2; //当前水位的数字在LCD屏显示的起点位置
% @7 x r0 j# j& [6 W uint uiTime; //声波传播时间6 B5 u5 P( t$ b+ ^2 ?- _# J0 N0 J( q
ulong ulDis; //实时测量到距离
1 u' p+ Q) u& `$ f! o
3 u6 n/ I$ Z, c+ p. k uiTime = TH0 << 8 | TL0;
' P" ^+ t% U; N- k3 ? ulDis = (uiTime * 3.40) / 200; //计算当前测量的距离,单位cm& Z# J b8 J" b p" a
) a! ^# y1 X2 X' U TH0 = 0;
' \5 W1 y4 J2 a4 j ] TL0 = 0; 4 I) Y, r* `& a* {& ~& q
7 L6 A# m) A' R7 w4 y' e
if((ulDis > uiD) || (g_flag == isYes )) // ulDis > uiD 超出测量范围;g_flag == isYes超时;2 u, h _+ R5 c: m
{
, F' P( ~/ A# P8 U$ V) s; ^ g_flag = isNo;
; m7 H) r% j: j% K5 J* l9 U9 X" M TR0 = 0;/ R3 F+ m* W0 R- z1 i& f0 }* m
putLineCharsToLCD1602(lineTow, i, 3, "Err"); // 显示Err 5 c0 i9 ?7 E- V" e- [
; e$ c1 d# K( {7 T //阀门动作: ! U- x+ S' D( H0 u" E7 V
// if(g_flagSwitch == isYes)+ ]2 S0 ]* Y+ n# _) E5 R
// {
8 K* G# V) }" _, F6 C! l8 n" b* L // io_Control_Inlet = isio_Control_Inlet_OFF; - L6 \/ @1 R7 z8 {1 e0 B- E. }
// io_Control_Outlet = isio_Control_Outlet_ON;
4 B o) h2 z" k7 F, S( ]& {3 a // g_flagSwitch = isNo;
0 N2 c6 N! H ~! w) C5 S // }
; n* I3 E4 w5 x0 }* K% l. m7 B1 n" _
6 S: c6 h- f7 y; b1 t. E //指示灯:
/ |+ b r( H* E/ u: [# r: e5 ? ioLed_Red = ! ioLed_Red; // 三个灯同时快速闪亮' w5 E) d5 s- t9 n
ioLed_Green = ! ioLed_Green;; Y, R$ Y1 C9 |3 V# k4 w
ioLed_Yellow = ! ioLed_Yellow;
0 ^5 b8 h/ K: s* I5 Q% ~ 2 O1 H3 n' N9 _% O0 G$ n( ]
// 蜂鸣器叫:
K k: p' H; F5 L* ~ if(buzzerCallFlag == isCall)1 o& }! C! z" V( q* K
{
|4 x% g! \7 T( a6 K9 l. J3 K! B buzzerCall(); // 蜂鸣器叫 , p( l; q9 e# ^1 a, o! n" `
}
8 a# \# [( {+ c( N0 y0 B$ |5 A% v . }6 g5 g* v( Z* B7 f
return isNo; // 返回错误信息( A* x3 H+ d7 h( M1 [
}
8 T& U+ c) {, o R else$ p2 ^. I1 e7 ~" b
{ k( g0 U5 ?/ l( l& Q' ]# N
ulDis = uiD - ulDis; // 当前水位C = 总距离 - 当前检测到的距离% X2 O) ^! Z8 _5 A$ d
5 Q( N0 A! A1 o! Y, |: ?
if(ulDis > uiH) // 如果水位超高
% z3 Q6 l% g% G {
+ i4 j9 i$ N! d. F B ' Z, D9 M' j+ a. z& f$ _
//阀门动作:% A3 A, [/ P: t5 G% l& G
io_Control_Inlet = isio_Control_Inlet_OFF;
0 x& M, Y- q4 v# ] io_Control_Outlet = isio_Control_Outlet_ON; & S$ F: b9 q0 u8 U% a3 N! `
g_flagSwitch = isNo;0 o( {* z$ o p( u( [" E3 ^ a
" m1 g: R6 \9 l) p- X$ \5 D
//指示灯:% }, m4 ~, x) a' f) h9 {
ioLed_Red = ! ioLed_Red; // 红灯闪
6 Z! l/ N, L0 C/ ` ioLed_Green = isLedOFF; $ b- N, H4 w/ a4 J/ G
ioLed_Yellow = isLedOFF;
) O$ _. C V+ j9 [1 U // 蜂鸣器叫:
6 `% x3 S* m3 C if(ulDis - uiH > (uiD - uiH) / DATA_alarmCoefficient) //当“当前水位”超出最高水位“ ((“总高度减高水位)除以2的值”)时报警
I3 y1 v& S2 ] {
/ s+ A6 C: U2 R, S; [7 X+ o0 h n! Y1 i buzzerCall(); // 蜂鸣器叫% ~' `2 j$ R+ ?% i! r! c
}3 c+ ]( n0 |, B
* q7 M0 q' C( f6 C; K, {# s0 |- \ }
% @4 z3 p/ S7 Q- G else if(ulDis < uiL) // 如果水位超低 [% a8 E; j9 Q
{
0 Q4 h0 f7 r) y( x% L //阀门动作: ) @# f: W/ b# E+ r: b
if(g_flagSwitch == isYes)
. e$ V$ ^, L5 b {
- R. l# c' ]' k/ v io_Control_Outlet = isio_Control_Outlet_OFF;
8 k! ?; ~7 X( u6 y! J% r4 O io_Control_Inlet = isio_Control_Inlet_ON; 1 D. S5 X/ V6 h8 D e; N2 ^1 v
g_flagSwitch = isNo;1 n8 V, g7 Q% I& [8 H
} 4 h& P2 c; }6 W& ?2 A6 y- k
; e4 |6 A: h' {! p
//指示灯:
4 U9 u% q8 R1 t9 E d0 _ ioLed_Red = isLedOFF;: M5 F* v" x |, |1 j$ U
ioLed_Green = isLedOFF;
$ W! g. M* x; {1 P8 W0 w" Y" E ioLed_Yellow = ! ioLed_Yellow; //黄灯闪$ V9 k& z( ]" B' N w' [4 b3 L: y
// 蜂鸣器叫: , b" P# c3 R, @
if( uiL - ulDis > uiL / DATA_alarmCoefficient)//uiL / 2 当“当前水位”低于“低水位” “低水位除以2的值”时报警0 m! Y: ]# p( B2 C3 Z, x
{5 E$ G0 m4 G7 l0 }1 N! z
buzzerCall(); // 蜂鸣器叫6 {) u& P9 P( p) r r" }/ s6 |6 c
}! Q. J! W; n, q: {& p
% E7 u1 b* A) L) _% C: z ) D4 a0 h& ^. U
} l& R- v3 \ O0 G1 l! t
else // 水位在正常范围 ; `) k9 N, ^# C z: ~
{ + X+ o8 ?* M. K
ioLed_Red = isLedOFF;
" R& G6 T5 F3 _4 j ioLed_Green = ! ioLed_Green;2 ^4 P) r# x6 j: Q# e9 r* S
ioLed_Yellow = isLedOFF;
v3 ~0 h$ S, k& c( L: Z) Z( I$ O
9 y7 g8 T1 O" L& c6 ] }1 Z9 l- P' \% a) j( Z6 F
putThreeCharToLCD1602(lineTow, i, ulDis);' g! \$ b/ Y& N& }
return isYes; 1 ?- h$ c% I; ?# j6 e% g2 L
$ @ \& H5 T7 }+ [ }) S! I( f% x! q" p3 y2 v. l
return isYes;/ @5 u! x2 R% A1 @
}
/ F, O1 D7 ~3 K5 G/ q8 w2 ?7 ^# Z! W( K, |" B' ]9 B
/*********************************************************/4 ` ~8 p e- u; P" V4 h( ]
void main(void)1 g% [/ h3 Q- o5 _ x
{0 G8 w/ e: r) l& \
initIO(); //初始化IO端口 $ e9 ^. e8 }5 w+ Y5 C$ I3 h
delay500ms(); //启动延时,给器件进入正常工作状态留够时间
1 M6 ~1 P, i! V' ^& B! A initLCD1602(); //LCD初始化 8 h$ a0 k! \% z& H; W' G5 p$ r* @
putLineCharsToLCD1602(lineOne, 8, 8, "D:000cm "); //显示distance (总)距离(检测探头到水库底部的距离)D/ S) X7 k2 |5 s) i1 v
putThreeCharToLCD1602(lineOne, 8 + 2, uiD); //显示三位数值, S/ S" A6 \' c1 U- H( m$ v
putLineCharsToLCD1602(lineOne, 0, 8, "H:000cm "); //显示设定的最高报警水位H( ~/ J; `5 y* t: x7 K; T
putThreeCharToLCD1602(lineOne, 0 + 2, uiH); //显示三位数值8 |5 g9 N: `, q( h
putLineCharsToLCD1602(lineTow, 0, 8, "L:000cm "); //显示设定的最低报警水位L
8 J& o( `7 E5 x1 B) \" Z1 Z putThreeCharToLCD1602(lineTow, 0 + 2, uiL); //显示三位数值7 R" R U+ ?4 n0 p3 W4 N
putLineCharsToLCD1602(lineTow, 8, 8, "C:000cm "); //显示当前CURRENT水位C! }* ^* i7 |( d& y, }% _8 z
* j$ q. M& h) x3 ]% v7 L initTimer0(); //初始化定时器0
9 n& m9 b- q5 F initTimer1();
* D& u/ q, E W' k6 ~7 O & y* f; }- i+ Q+ W8 L" ^# ^
//阀门动作:初始先排水
U1 k1 n" e6 ^* v" V* j, g$ K9 d io_Control_Inlet = isio_Control_Inlet_OFF; 9 I: f o; u% E+ _
io_Control_Outlet = isio_Control_Outlet_ON;
0 s9 q1 A8 W( o g_flagSwitch = isNo; & o% Z2 Y9 Z. W9 S
. ~4 r3 `( ^& n/ G9 V/ T while(1)
2 Y9 j( [/ Y. V# F {
; j* |6 Z* ?0 ^ io_US_TX = 1; //启动超声波模块信号
8 ^7 \ P) ?* J' T/ ?2 x9 x8 S delay10us();# l: S& B5 x& \; T5 b# ` q) m
io_US_TX = 0;
1 S4 q; [# }* c& L( j' m# d! }
( t6 f7 T7 f3 r' j& E# E; K while(io_US_RX == 0); //等待计时开始* q. N/ n# x$ B
TR0 = 1; //开启定时器0,计时开始
/ d# F2 \* E: p4 [ IT1 = 1; //设置外中断INT1输入信号模式(1:Falling only仅下降沿有效 0:Low level低电平有效)4 \" M( ?' S- F* ] t
EX1 = 1; //使能外中断INT1 % D( ]8 d! S9 e2 J: D
3 s/ Z5 @+ g/ w3 V+ |/ \- j
while(EX1 == 1 && g_flag == isNo)//等待中断或超时退出
. |3 n( f! h; A& [ {$ ^) f" ~% Y# I) A* U
uchar ucKeyValue = GetKey(); //在等待中检测按键
5 K% B8 s+ A& u+ \ if(ucKeyValue) execute_key_task(ucKeyValue); //如果有键按下则执行按键任务
2 e8 k$ {3 L& q# X" n9 G }
' d+ B3 J& I$ g# Q F/ _" @1 y/ j4 k6 n- B* z
if(CalculatedWaterLevel() == isNo) continue; //计算水位,如果超出范围返回isNo并重新循环
2 C8 l9 C2 u2 s( b2 g$ h- x 5 ]( {* {/ v- ?2 \! [! p2 H4 w
TR0 = 0; //暂时关闭定时器08 v" j2 C3 u7 k, i% T" f( d
//清零定时器和计数变量以及标志
% u5 U" _: h% _- m5 `, o TL0 = 0;
" x M. X# b4 `! D2 u W6 v2 c9 e' o TH0 = 0;
/ H# I, E3 N( E; c g_flag = isNo;" p/ I4 z# p0 @( C3 C& X% A
ucCount = 0;, E1 }' l, X) k0 {
g_flag05s = isNo;
* [( l3 L/ d5 z3 j6 [) j* j" o
' } U3 V E2 ^3 U TR0 = 1; //打开定时器0
; z; |, a+ o) u while(g_flag05s == isNo) //延时0.52秒,以防止此期间返回的超声波产生错误信息,并使显示变化放慢,保证视觉效果) v1 S4 b- o+ b4 J: |- f; l) w) _6 t7 B
{ - u* {9 T$ W4 R" O$ Z9 P
uchar ucKeyValue = GetKey();
' z# `% W" H" b& H7 M3 d* t if(ucKeyValue)
9 F/ F. K( o9 O1 q! f8 n: ? {
" I' w; G; f, X8 v4 O if(ucKeyValue == DATA_KEY_DEC)3 P" @; ~( i! p, h: N. k3 |$ O
{
( F- R0 P/ w6 n/ o9 V g_flagBeepTimer = isNo;//用减小按键取消报警标志2 B- }% G" y5 h; @2 ?5 ?
}) |1 T, h \" S4 S) s& S& z/ A! z, O1 D
! ~9 H4 o/ w2 [+ v/ l execute_key_task(ucKeyValue); //如果有键按下则执行按键任务
" B# C& Q' l8 F' f+ y; Q; s }
1 B; z! Z9 k4 {4 s7 U- ?
7 c, W% H- t& p [4 c } $ A- z1 I7 k& ~
TR0 = 0; //暂时关闭定时器02 o9 v( j! u0 t+ p
//清零定时器和复位标志
9 p0 d7 V* L9 z* j: q; L TL0 = 0;
7 G8 d! ~8 `# l% ]# F, T+ M TH0 = 0; ( G R1 x7 p9 I+ c8 q% S
g_flag = isNo;
, ~7 \) k; h, P& r. S7 _6 t% \ & k8 Y) S! L( k) o, d
//-----------------------------------
' {* W8 v% s) S6 B" J2 I7 p //水箱清洗提示:7 j9 O% S- d' y) B0 \1 s
% a- o1 M: {$ }7 D if(g_flagBeepTimer == isYes)
& Y+ |9 }" H/ r) z0 |& _4 E" J {
! K7 t# Q$ s [0 T, J* | buzzerCall();
' _" _4 `. \+ r* l( j& y2 k //用减小按键取消报警标志" `+ {5 k9 T O% V! _; K
H7 E1 o9 ~. z, S6 @4 `
}
. L# D; v" h5 k O3 Z* w //-----------------------------------+ b: V8 `! ]0 q, f+ E4 t
, Z1 k" [9 x6 d" q2 C, R
}- T7 Z* D" n: A, l
}7 M3 h' ~! H7 f9 U" X
. L- S/ s- y. f% r2 {2 P( F5 j* ?* y5 X' Z' r
#ifndef __MAIN_H__0 D# B' n8 d" |3 a, I% Q T3 k/ z
#define __MAIN_H__4 c6 m5 M7 p, R" A0 y, M: T
' d2 b9 E7 e; R//-----------------------------------------------
" S! t9 [4 c$ w" ~% G8 \2 x; C' Mtypedef unsigned char uchar; //为了方便书写定义别名
( `1 }" y+ y) p! {/ k( Qtypedef unsigned int uint;+ Q1 O2 Q. V- b3 \; F# S
typedef unsigned long ulong;
7 C% t' Y7 w+ O6 ?. V; ~typedef bit bool;9 ~4 }* N" W- E, |- g& ~
8 F* [/ V7 K' A) c! Lsbit io_Control_Inlet = P1 ^ 7; //定义进水继电器(水泵)控制端口! _; Z. J+ t1 X1 |! G, \
#define isio_Control_Inlet_ON 0
) \; C* e1 s3 C' t0 I#define isio_Control_Inlet_OFF 1 A( u+ C2 R* S( V3 d
J! |) e3 n# r3 z/ C! Asbit io_Control_Outlet = P0 ^ 0; //定义出水继电器(水泵)控制端口
0 m4 ?# i; X5 f- j0 e#define isio_Control_Outlet_ON 0
" [4 k* v8 M8 y#define isio_Control_Outlet_OFF 1
& h4 `% U% I, b) U7 P) t0 {2 U. P- \2 y+ W9 S
#define isYes 18 N9 v3 i9 _* {3 l! ]
#define isNo 0
6 Q! \. I; l7 f+ l, S//----------------------------------------------------, `; `. \1 c# G) M2 A
//定义超声波模块引脚& g* T( H! }1 c
sbit io_US_RX = P3 ^ 3;
; n. b6 @1 |! {5 s7 m! Vsbit io_US_TX = P3 ^ 2;
j) e2 l- q3 |; q- t//----------------------------------------------------
E! r- R2 h3 D' w; }//定义LCD引脚1 m& h" R. M" N, c) z$ T- K' S/ k
sbit io_LCD_RW = P3 ^ 6; " G8 t, n. s+ x! K# {
sbit io_LCD_RS = P3 ^ 7;3 b% p6 h5 l8 T k
sbit io_LCD_E = P3 ^ 5; ' z3 `3 O3 ^2 k( x6 o
#define IO_LCD_Data P2
5 y) }7 D+ ]' x# x7 v$ b- \#define lineOne 0
" d$ t0 T) [8 H V9 @( N, X' Y#define lineTow 1
! f8 z5 }3 u: U% j" O% H1 V k& x! s# ~( r( J
#define isReadBusy 1. r3 k7 d7 c8 c" p3 E2 `- e
#define isNotReadBusy 0* x1 g$ D) w/ ?) S
# F/ [8 S$ a* m6 Y" c4 d
#define DATA_LineMax 0x01 //LCD最大的行索引数$ n6 t" {7 w% Z9 ~9 L4 I# `5 V1 K
#define DATA_PositionMax 0x0F //(16 - 1) 字符在LCD一行中的最后一个索引位置
! \. J% p4 M4 u; |& r. }#define DATA_LineTow 0x01 //LCD第二行的索引值4 _2 j0 J% z& ~) t8 z
//-------------------------------------------3 G* v& T( I3 t' ^0 x
#define Data_Key20msCountMax 160 //125us * 160 = 20ms 键去抖动延时
h& l: j7 k6 t; v& P) K$ g9 a//------------------------------------------------- z+ H2 O( ?# Z# r# U. D
// 定义指示灯端口+ K( m( X+ b+ H I9 s/ d
sbit ioLed_Red = P1 ^ 3;0 R! N+ k4 ]9 [5 d& Y
sbit ioLed_Green = P1 ^ 2;* O8 S8 h$ D) [' A1 d, E! ^
sbit ioLed_Yellow = P1 ^ 1;9 W e/ }- w/ k
; p, A/ W' c4 e. a% f7 w1 {) l#define isLedOFF 1 // 关闭LED+ v. S# J; H; D. o9 W, Y% ^
#define isLedON 0 // 点亮LED
$ B3 m+ v3 `2 I( A# X//---------------------------------------------
3 G4 U6 m5 g" U, ]: D//定义按键端口
+ g% Q# H, [! _" f0 ]; }3 i: o#define IO_KEY P1 $ S% F" f$ A8 b
) d, K, Y# t5 g! K% e& Z2 C M
#define DATA_KEY_ORL 0x8f //10001111 //过滤按键以外的端口的数据2 E' ~) R0 S+ d# i
#define DATA_KEY_Null 0xff //11111111 //无键按下的数据
9 P' T8 ^# {1 A8 N. E# v+ H# O3 U& ?0 c
#define DATA_KEY_Set 0xef //11101111 //设置时间按键按下的数据" ~4 z/ [: R- Z+ E/ D4 f& s; X7 [
#define DATA_KEY_INC 0xdf //11011111 //增加键按下的数据4 E0 ~" y& p1 B$ H% i
#define DATA_KEY_DEC 0xbf //10111111 //减少键按下的数据
8 j$ t3 ~+ o; j& P, `, E" e2 x//---------------------------------------------0 N3 f3 ?- h1 |# S# O9 ]) ]
//定义蜂鸣器端口5 _# G. S% ]; z9 K5 o
sbit io_Buzzer = P1 ^ 0; - r5 ]5 C) ]. H T2 n$ ]1 ~
//---------------------------------------------+ Q& _* j' n" O) Y7 q! c4 o& Q
//定义检测探头到水库底部的设定距离范围
) n/ W( o7 s) j9 n
#define DATA_uiD_Min 255 // 定义检测探头到水库底部的最小设定距离 单位cm
+ f3 v: H6 G$ [& E#define DATA_uiD_Max 20 // 定义检测探头到水库底部的最大设定距离 单位cm1 `; c7 {* U+ f. J% Y2 Z2 Q2 b
3 I5 i: G2 r' ~! N g; H6 H#define DATA_alarmCoefficient 2 // 超限报警阀值的系数
2 w U+ K& ~8 g; [( C3 m#define DATA_switchTime 200 //50ms的200倍 = 10S,控制阀门连续开启间隔延时(保护)8 o# J3 \4 s5 h, ~- ^- t7 n" R/ w
#define DATA_BeepTimer 100 // 清洗水箱提示:分钟的倍数
+ e# S/ t8 t% _
5 |- T8 I8 W" }! Q9 `3 ] a( lsbit buzzerCallFlag = P3 ^ 4;
% R+ j$ d+ x( l) n: K1 ]: h2 I#define isCall 0& K+ }) l2 @2 n4 m1 T
#endif
5 Z, Y2 x9 }" V: B4 g# b* _% H; a
& s3 \; T! Z+ {( B$ V
9 J+ r2 u8 U" E5 }
. [6 ^8 |" b5 D5 J- G' A# d4 q! Q, ?6 s
|
|