基于51单片机的水位水质检测系统Proteus仿真原理图PCB

本系统基于STC89C52单片机,利用LCD1602液晶屏实时显示水位及水质百分比,并可通过按键设置阈值。具备声光报警功能,支持断电数据保存,适用于水质监测场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示水位、水质百分比
2.按键设置水位水质阈值并通过液晶显示
3.具备4个LED分别作为水位水质的上下限指示灯
4.具备声光报警功能
5.设置的阈值数据掉电不丢失
6.两组继电器可外接进水和出水设备,当水位超过上下限时对应的继电器会切换状态
7.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:
在这里插入图片描述

PCB :
在这里插入图片描述

主程序:

#include <stdio.h>
#include <reg52.h>
#include "tlc0832.h"
#include "lcd1602.h"
#include "eepom52.h"
#include "delay.h"

sbit KEY_ENTER = P3^5;     //自动手动模式切换按键
sbit KEY_SET = P3^3;     //设置按键
sbit KEY_ADD = P3^4;     //加按键
sbit KEY_SUB = P3^6;     //减按键
sbit LED_WATER_DEPTH_UP = P1^3;       //水位上限指示灯
sbit LED_WATER_DEPTH_LOW = P1^4;       //水位下限指示灯
sbit LED_WATER_QUALITY_UP = P1^5;       //水质上限指示灯
sbit LED_WATER_QUALITY_LOW = P1^6;       //水质上限指示灯
sbit BUZZER = P2^2;        //蜂鸣器
sbit RELAY1 = P2^0;       //继电器1 进水
sbit RELAY2 = P2^1;       //继电器2 出水

void UpdataWaterValue();         //更新当前水深到LCD1602
void UpdataMinMaxWaterValue(); //更新最大最小水深到LCD1602

void UpdateEEPROM();              //更新eeprom存储的数据
void InitEEPROM();                //初始化eeprom

void Check();            //水位检测比较报警函数

bit refreshFlag = 1;

unsigned char curWaterDepth = 0;        //当前水深
unsigned char maxWaterDepth = 70;       //最大水深
unsigned char minWaterDepth = 0;       //最小水深

unsigned char setFlag = 0;     //设置按键标志位
bit alarmFlag = 0;   //报警标志位

unsigned char curWaterQuality = 0;        //当前水质
unsigned char maxWaterQuality = 70;       //最大浊度
unsigned char minWaterQuality = 0;       //最小浊度


void KeyScan(void)
{
	if (KEY_SET == 0) //设置按键按下
	{
		DelayMs(2);
		if (KEY_SET == 0)
		{
			setFlag++;
			if (setFlag >= 5)
			{
				setFlag = 1;
			}
			switch(setFlag)
			{
				case 0: LCD_DispOneChar( 5, 0, ' ' ); LCD_DispOneChar( 11, 0, ' ' ); LCD_DispOneChar( 5, 1, ' ' ); LCD_DispOneChar( 11, 1, ' ' ); break;
				case 1: LCD_DispOneChar( 5, 0, '>' ); LCD_DispOneChar( 11, 0, ' ' ); LCD_DispOneChar( 5, 1, ' ' ); LCD_DispOneChar( 11, 1, ' ' ); break;
				case 2: LCD_DispOneChar( 5, 0, ' ' ); LCD_DispOneChar( 11, 0, '>' ); LCD_DispOneChar( 5, 1, ' ' ); LCD_DispOneChar( 11, 1, ' ' ); break;
				case 3: LCD_DispOneChar( 5, 0, ' ' ); LCD_DispOneChar( 11, 0, ' ' ); LCD_DispOneChar( 5, 1, '>' ); LCD_DispOneChar( 11, 1, ' ' ); break;
				case 4: LCD_DispOneChar( 5, 0, ' ' ); LCD_DispOneChar( 11, 0, ' ' ); LCD_DispOneChar( 5, 1, ' ' ); LCD_DispOneChar( 11, 1, '>' ); break;
			}
			while (KEY_SET == 0);
			UpdateEEPROM();
		}
	}

	if (KEY_ADD == 0 && setFlag != 0) //加键按下
	{
		DelayMs(180);
		if (KEY_ADD == 0 && setFlag != 0)
		{
			switch (setFlag)
			{
			case 0:
				break;
			case 1:
				if (maxWaterDepth < 100)
					maxWaterDepth++;
				break;
			case 2:
				if (minWaterDepth < maxWaterDepth)
					minWaterDepth++;
				break;
			case 3:
				if (maxWaterQuality < 100)
					maxWaterQuality++;
				break;
			case 4:
				if (minWaterQuality < maxWaterQuality)
					minWaterQuality++;
				break;
			}
			UpdataMinMaxWaterValue();
			//while (KEY_ADD == 0);
			UpdateEEPROM();
		}
	}

	if (KEY_SUB == 0 && setFlag != 0) //减键按下
	{
		DelayMs(180);
		if (KEY_SUB == 0 && setFlag != 0)
		{
			switch (setFlag)
			{
			case 0:
				break;
			case 1:
				if (maxWaterDepth > minWaterDepth)
					maxWaterDepth--;
				break;
			case 2:
				if (minWaterDepth > 0)
					minWaterDepth--;
				break;
			case 3:
				if (maxWaterQuality > minWaterQuality)
					maxWaterQuality--;
				break;
			case 4:
				if (minWaterQuality > 0)
					minWaterQuality--;
				break;
			}
			UpdataMinMaxWaterValue();
			//while (KEY_SUB == 0);
			UpdateEEPROM();
		}
	}

	if (KEY_ENTER == 0) //确认键按下
	{
		DelayMs(2);
		if (KEY_ENTER == 0)
		{
			setFlag = 6;
			LCD_DispOneChar(5, 0, ' ');
			LCD_DispOneChar(11, 0, ' ');
			LCD_DispOneChar(5, 1, ' ');
			LCD_DispOneChar(11, 1, ' ');
			while (KEY_ENTER == 0)
				;
		}
	}
}

/************************* 定时器0初始化 *************************/
void Timer0_Init(void)
{
    TMOD &= 0xF0;
    TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
    TH0 = (65536 - 9216) / 256; //重新赋值 10ms
    TL0 = (65536 - 9216) % 256;
    EA = 1;  //总中断打开
    ET0 = 1; //定时器中断打开
    TR0 = 1; //定时器计数打开
    // PT0 = 1; //高优先级
}

//主函数
void main()
{

	Timer0_Init();
	InitEEPROM();	//初始化eeprom
	LCD_Init(); //初始化1602
	LCD_Clear();
	LCD_DispStr(0, 0, "W:    H:    L:  ");
	LCD_DispStr(0, 1, "Z:    H:    L:  ");
	UpdataWaterValue();		  //更新当前水深到LCD1602
	UpdataMinMaxWaterValue(); //更新最大最小水深到LCD1602
	BUZZER = 1; //关闭蜂鸣器
	LED_WATER_DEPTH_UP = 1;
	LED_WATER_DEPTH_LOW = 1;
	while (1)
	{
		if (refreshFlag == 1)
		{
			refreshFlag = 0;
			UpdataWaterValue();
			UpdataMinMaxWaterValue();
			Check();	//水位检测比较报警函数
		}
	
		KeyScan();
	}
}

//更新当前水深到LCD1602
void UpdataWaterValue()
{
	unsigned char lcd1602_data[4] = {0};

	curWaterDepth = ReadADC(AIN1_GND);
	curWaterDepth = curWaterDepth * 100 / 255;
	if (curWaterDepth > 99)
	{
		curWaterDepth = 99;
	}
	lcd1602_data[0] = curWaterDepth % 100 / 10 + 48;
	lcd1602_data[1] = curWaterDepth % 10 + 48;
	LCD_DispStr(2, 0, lcd1602_data);
	DelayMs(10);

	curWaterQuality = ReadADC(AIN0_GND);
	curWaterQuality = 100 * (255 - curWaterQuality) / 255;
	if (curWaterQuality > 99)
	{
		curWaterQuality = 99;
	}
	lcd1602_data[0] = curWaterQuality % 100 / 10 + 48;
	lcd1602_data[1] = curWaterQuality % 10 + 48;
	LCD_DispStr(2, 1, lcd1602_data);
	DelayMs(10);
}

//更新最大最小水深到LCD1602
void UpdataMinMaxWaterValue()
{
	unsigned char lcd1602_data[4] = {0};
	if (maxWaterDepth > 99)
	{
		maxWaterDepth = 99;
	}
	lcd1602_data[0] = maxWaterDepth % 100 / 10 + 48;
	lcd1602_data[1] = maxWaterDepth % 10 + 48;
	LCD_DispStr(8, 0, lcd1602_data);

	if (minWaterDepth > 99)
	{
		minWaterDepth = 99;
	}
	lcd1602_data[0] = minWaterDepth % 100 / 10 + 48;
	lcd1602_data[1] = minWaterDepth % 10 + 48;
	LCD_DispStr(14, 0, lcd1602_data);

	if (maxWaterQuality > 99)
	{
		maxWaterQuality = 99;
	}
	lcd1602_data[0] = maxWaterQuality % 100 / 10 + 48;
	lcd1602_data[1] = maxWaterQuality % 10 + 48;
	LCD_DispStr(8, 1, lcd1602_data);

	if (minWaterQuality > 99)
	{
		minWaterQuality = 99;
	}
	lcd1602_data[0] = minWaterQuality % 100 / 10 + 48;
	lcd1602_data[1] = minWaterQuality % 10 + 48;
	LCD_DispStr(14, 1, lcd1602_data);
}

//初始化eeprom
void InitEEPROM()
{
	unsigned char is_first_init = ReadByte(0x2020);
	if (is_first_init == 1)
	{
		maxWaterDepth = ReadByte(0x2000);
		minWaterDepth = ReadByte(0x2001);
		maxWaterQuality = ReadByte(0x2002);
		minWaterQuality = ReadByte(0x2003);
	}
	else
	{
		EraseSector(0x2000);
		WriteByte(0x2000, maxWaterDepth);
		WriteByte(0x2001, minWaterDepth);
		WriteByte(0x2002, maxWaterQuality);
		WriteByte(0x2003, minWaterQuality);
		WriteByte(0x2020, 1);
	}
}

//更新eeprom存储的数据
void UpdateEEPROM()
{
	EraseSector(0x2000);
	WriteByte(0x2000, maxWaterDepth);
	WriteByte(0x2001, minWaterDepth);
	WriteByte(0x2002, maxWaterQuality);
	WriteByte(0x2003, minWaterQuality);
	WriteByte(0x2020, 1);
}

//水位检测比较报警函数
void Check()
{
	if( curWaterDepth < minWaterDepth || curWaterDepth > maxWaterDepth || curWaterQuality > maxWaterQuality || curWaterQuality < minWaterQuality )
	{
		alarmFlag = 1;
	}
	else
	{
		alarmFlag = 0;
	}
	
	if(curWaterDepth < minWaterDepth)
	{
		LED_WATER_DEPTH_UP = 1;
		LED_WATER_DEPTH_LOW = 0;
	}
	else if(curWaterDepth > maxWaterDepth)
	{
		LED_WATER_DEPTH_UP = 0;
		LED_WATER_DEPTH_LOW = 1;
	}
	else
	{
		LED_WATER_DEPTH_UP = 1;
		LED_WATER_DEPTH_LOW = 1;
	}
	
	if(curWaterQuality < minWaterQuality)
	{
		LED_WATER_QUALITY_UP = 1;
		LED_WATER_QUALITY_LOW = 0;
	}
	else if(curWaterQuality > maxWaterQuality)
	{
		LED_WATER_QUALITY_UP = 0;
		LED_WATER_QUALITY_LOW = 1;	
	}
	else
	{
		LED_WATER_QUALITY_UP = 1;
		LED_WATER_QUALITY_LOW = 1;
	}
	
	if(curWaterDepth < minWaterDepth)
	{
		RELAY1 = 0; 
		RELAY2 = 1;
	}
	else if(curWaterDepth >= maxWaterDepth)
	{
		RELAY2 = 0; 
		RELAY1 = 1;
	}
	else 
	{ 
		RELAY2 = 1; 
		RELAY1 = 1; 
	}


}

/************************* 定时器0中断处理 *************************/
void Timer0_Interrupt(void) interrupt 1
{
    static unsigned int time10ms  = 0;

    TH0 = (65536 - 9216) / 256; //重新赋值 10ms
    TL0 = (65536 - 9216) % 256;
    time10ms++;

    if (time10ms > 50)
    {
        time10ms = 0;
		refreshFlag = 1; //刷新标志
        
        if (alarmFlag == 1)
        {
            BUZZER = !BUZZER;
        }
        else
        {
            BUZZER = 1;
        }
    }
    

}

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值