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