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