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