本系统由STC89C52单片机电路+水流量传感器模块电路+LCD1602液晶显示电路+按键电路+继电器控制电路+电源电路组成。
1、水流量传感器采用椭圆齿轮传感器。
2、通过液晶LCD1602液晶实时显示瞬时流量和累计流量。
3、通过按键设置累计流量阈值,继电器默认断开状态。如果累计流量低于设置阈值,继电器闭合。否则继电器断开。
4、通过液晶LCD1602液晶实时显示设置流量设置值。
5、累积流量和设置的流量阈值掉电不丢失数据。
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdio.h>
#include "1602.h"
#include "delay.h"
#include "eeprom.h"
sbit relay=P1^2; //继电器
sbit key1=P1^1; //按键1
sbit key2=P1^0; //按键2
sbit key3=P2^0; //按键3
unsigned long PluNum=0; //检测速度转化来的脉冲量
unsigned long time_ms; //定时器计数
float ShunShi=0; //瞬时流量
char dis0[16]; //显示更新暂存
char dis1[16]; //显示更新暂存
unsigned char dealFlag=0; //处理速度标志
bit rekey =0; //防止重复
unsigned char eeprInitFlag;
float LeiJi = 0;//累计计算
unsigned char llQ = 0; //累计流量
unsigned char setQ =10; //设置流量
void Init_Timer0(void); //函数声明
/******************把数据从单片机内部eepom中读出来*****************/
void read_eeprom()
{
llQ = byte_read(0x2001); //读取eeprom存储之
setQ = byte_read(0x2002);
eeprInitFlag = byte_read(0x2055); //数据初始化读取
}
/******************把数据保存到单片机内部eepom中******************/
void write_eeprom()
{
SectorErase(0x2000); //擦除整个扇区 注意整个扇区数据都擦出了
byte_write(0x2001, llQ);
byte_write(0x2002, setQ);
byte_write(0x2055, eeprInitFlag);
}
/**************开机初始化保存的数据*****************/
void init_eeprom()
{
read_eeprom(); //先读
if(eeprInitFlag != 0x55) //新的单片机初始单片机内问eeprom 如果不是0x55重新写入
{
llQ = 0; //赋值初始化
setQ = 10;
eeprInitFlag = 0x55;
write_eeprom(); //保存数据
}
}
void main (void)
{
Init_Timer0(); //定时器0初始化
EX0=1; //外部中断0开
IT0=1; //边沿触发
EA=1; //全局中断开
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏
init_eeprom();
while (1) //主循环
{
if(dealFlag==1) //定时处理流速
{
if( llQ < setQ ) //对比设置和实际值
{relay=0;} //打开继电器
else
{relay=1;} //关闭关闭继电器
write_eeprom();
}
if((key1 == 0)||(key2 == 0)||(key3 == 0)) //有按键情况下
{
if(rekey == 0)
{
DelayMs(10);
if(key1 == 0) //按键1按下
{
rekey =1; //防止重复按下
if(setQ < 250)
setQ =setQ + 1;
}
}
}
else
{
rekey = 0; //防止重复按下
}
}
}
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
void Timer0_isr(void) interrupt 1
{
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
time_ms++;
if(time_ms%25==0) //时间定时500ms
{
dealFlag=1;
}
}
/*------------------------------------------------
外部中断程序
------------------------------------------------*/
void ISR_Key(void) interrupt 0 using 1
{
PluNum++; //脉冲计数
}
资料下载地址