功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶显示水流量/累计流量/累计流量阈值
2.按’清零‘键清除累计流量,按’加’'减’设置累计流量报警阈值,按’启停’启动停止水泵
3.超过累计流量阈值,停止水泵,蜂鸣器报警提醒一段时间
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include "lcd1602.h"
#include "delay.h"
sbit KEY_ADD = P3^4; //按键加
sbit KEY_SUB = P3^6; //按键减
sbit KEY_CLEAR = P3^3; //按键设置
sbit KEY_SWITCH = P3^5; //按键模式
sbit RELAY = P2^1; //继电器
sbit BUZZER = P2^2; //蜂鸣器
bit refreshFlag = 1; //刷新标志
bit switchFlag = 0; //开关标志
unsigned long g_waterFlowCnt = 0; //检测速度转化来的脉冲量
unsigned long g_timeMs; //定时器计数
float g_waterFlow = 0; //瞬时流量
float g_totalFlow = 0; //累计流量
float g_alarmTotalFlow = 5; //流量报警值
unsigned char buzzerCnt = 0;
void DisplayWaterFlow(unsigned char *fisrtStr, unsigned char *secondStr);
void Init_Timer1(void); //函数声明
void Key_Scan(void); //按键处理
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)
{
char dis0[16]; //显示更新暂存
char dis1[16]; //显示更新暂存
Init_Timer1(); //定时器1初始化
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏
while (1) //主循环
{
if (refreshFlag == 1)
{
refreshFlag = 0;
sprintf(dis0, "Speed: %5.2fL/s", g_waterFlow); // 瞬时流量
sprintf(dis1, "T:%4.1fL S:%4.1fL", g_totalFlow, g_alarmTotalFlow); // 累计流量
DisplayWaterFlow(dis0, dis1);
if (buzzerCnt > 1)
{
buzzerCnt--;
BUZZER = 0;
}
else
{
BUZZER = 1;
}
}
if ((g_totalFlow >= g_alarmTotalFlow)) //累计流量超过阈值
{
switchFlag = 0;
if (buzzerCnt == 0)
{
buzzerCnt = 10; //蜂鸣器报警时长10*500ms
}
} //蜂鸣器报警 断开继电器
else
{
BUZZER = 1;
} //关闭蜂鸣器 闭合继电器
if (switchFlag == 1) //继电器控制标志
{
RELAY = 0;
}
else
{
RELAY = 1;
}
Key_Scan();
}
}
void DisplayWaterFlow(unsigned char *fisrtStr, unsigned char *secondStr)
{
LCD_Write_String(0, 0, fisrtStr);
LCD_Write_String(0, 1, secondStr);
}
void Key_Scan(void)
{
if (KEY_CLEAR == 0) // 设置键按下
{
DelayMs(20);
// 清零
if (KEY_CLEAR == 0)
{
buzzerCnt = 0;
g_waterFlow = 0;
g_totalFlow = 0;
}
while (KEY_CLEAR == 0);
}
if (KEY_ADD == 0) // 加键按下
{
DelayMs(180);
if (KEY_ADD == 0)
{
if (g_alarmTotalFlow < 99.9) // 设置值++
{
g_alarmTotalFlow = g_alarmTotalFlow + 0.1;
}
}
}
if (KEY_SUB == 0) // 减键按下
{
DelayMs(180);
if (KEY_SUB == 0) // 减键按下
{
if (g_alarmTotalFlow > 0.1) // 设置值--
{
g_alarmTotalFlow = g_alarmTotalFlow - 0.1;
}
}
}
if (KEY_SWITCH == 0) // 切换
{
DelayMs(20);
if (KEY_SWITCH == 0)
{
buzzerCnt = 0;
switchFlag = ~switchFlag; //启停水泵
}
while (KEY_SWITCH == 0);
}
}
/************************* 定时器1初始化 *************************/
void Init_Timer1(void)
{
TMOD &= 0x0F;
TMOD |= 0x10; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH1 = (65536 - 20000) / 256; //重新赋值 20ms
TL1 = (65536 - 20000) % 256;
ET1 = 1; //定时器中断打开
TR1 = 1; //定时器开关打开
IT0 = 1; //外部中断打开
EX0 = 1; //外部开关打开
EA = 1; //总中断打开
}
/*------------------------------------------------
外部中断程序
------------------------------------------------*/
void ISR_Key(void) interrupt 0
{
g_waterFlowCnt++; //脉冲计数
}
void Timer1_isr(void) interrupt 3
{
TH1 = (65536 - 20000) / 256; //重新赋值 20ms
TL1 = (65536 - 20000) % 256;
g_timeMs++;
if (g_timeMs >= 25) //时间定时500ms
{
refreshFlag = 1;
g_waterFlow = (float)g_waterFlowCnt * 0.00223 * 2; //计算瞬时流量 一个脉冲代表0.00223ml
g_totalFlow = g_totalFlow + g_waterFlow; //累计计算累计流量
g_waterFlowCnt = 0; //清空计数;
g_timeMs = 0;
}
}