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