基于51单片机的智能水表水流量计流量报警器proteus仿真原理图PCB

功能:
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;

    }
}

仿真演示视频:
https://www.bilibili.com/video/BV1CD4y1t7yo/

实物演示视频:
https://www.bilibili.com/video/BV1o24y117cw/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值