硬件构成:
STM32F103C8T6单片机最小系统板(包含+3.3V稳压电路+时钟晶振电路+复位电路(上电自复位,手动复位)),水流量传感器、继电器、LCD1602液晶显示、按键、蜂鸣器、蓝牙模块及电源组成;
功能介绍:
1、通过LCD1602液晶实时显示瞬时流量和累计流量、设置的累计流量。
2、通过按键设置累计流量阈值,如果累计流量超过设置阈值,蜂鸣器报警、继电器断开,否则不报警继电器闭合。
3、继电器模拟水阀开关,如果当前累计流量低于设置流量,打开继电器打开水阀的意思。
4、按键有设置按键、设置+、设置-,在设置情况下可以对设置值进行加减运算。
5、蓝牙模块可与手机APP连接,实现手机APP对实物的实时数据的监控和控制;
主要物料清单及型号
显示屏:LCD1602-5V;
单片机:STM32F103C8T6;
蓝牙模块:JDY-31-SPP;
水流量传感器:YF-S201;
继电器:SRD-05V;
蜂鸣器:5V有源蜂鸣器;
PCB:
程序:
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include <stdio.h>
#include "timer.h"
#include "key.h"
#include "lcd1602.h"
#include "exti.h"
char dis0[17]; //显示暂存数组
char dis1[17];
unsigned long plu=0; //脉冲计数
float shunShiVal=0; //瞬时流量
float leiJiVal=0; //累计流量
u16 ushunShiVal=0; //瞬时流量
u16 uleiJiVal=0; //累计流量
u16 leiJiWarn=50; //累计流量
u16 warn_flag=0;
u8 refresh=1;
u8 t_1s=0;
unsigned char dealLiuliang=0; //流量处理
unsigned char i ;
unsigned char setMan = 1; //设置标志
unsigned char valCheckFlag =0;//是否对比
u8 CheckKey(void);
u8 key;
u8 set=0;
extern u8 revData;
void key_handle(void)
{
switch(key)
{
case 1:
{
buzzer = 0;
delay_ms(50);
buzzer = 1;
while(key1==0);
set++;
if(set>=2)
set=0;
if(set==1)
{
Lcd_SetXY(14,0);
Lcd_Write_Command(0x0f,1);//打开显示 无光标 光标闪烁
}
else
{
Lcd_SetXY(14,0);
Lcd_Write_Command(0x0c,1);//打开显示 无光标 光标闪烁
}
}
break;
case 2:
{
buzzer = 0;
delay_ms(50);
buzzer = 1;
while(key2==0);
if(set==0)
{
leiJiVal=0.0;
}
else if(set==1)
{
leiJiWarn++;
if(leiJiWarn>999)
leiJiWarn=0;
Lcd_SetXY(11,0);
Lcd_Write_Data(leiJiWarn/100+0x30);
Lcd_Write_Data(leiJiWarn%100/10+0x30);
Lcd_Write_Data('.');
Lcd_Write_Data(leiJiWarn%10+0x30);
Lcd_SetXY(14,0);
Lcd_Write_Command(0x0f,1);//打开显示 无光标 光标闪烁
}
}
break;
case 3:
{
buzzer = 0;
delay_ms(50);
buzzer = 1;
while(key3==0);
if(set==1)
{
if(leiJiWarn>0)
leiJiWarn--;
else
leiJiWarn=999;
Lcd_SetXY(11,0);
Lcd_Write_Data(leiJiWarn/100+0x30);
Lcd_Write_Data(leiJiWarn%100/10+0x30);
Lcd_Write_Data('.');
Lcd_Write_Data(leiJiWarn%10+0x30);
Lcd_SetXY(14,0);
Lcd_Write_Command(0x0f,1);//打开显示 无光标 光标闪烁
}
}
break;
}
key=0;
}
int main(void)
{
delay_init(); //延时函数初始化
uart_init(9600); //串口初始化为9600
TIM3_Int_Init(499,7199);//50ms
NVIC_Configuration();
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init();
EXTIX_Init(); //外部中断初始化
Lcd_GPIO_init(); //初始化lcd引脚
Lcd_Init(); //初始化lcd屏幕
Lcd_Puts(0,0, " WELCOME ");
relay = 0;buzzer = 0; //硬件动作下
delay_ms(2000);
relay = 1;buzzer = 1; //关闭
while(1)
{
key=CheckKey();//按键处理
key_handle();
APP_handle();
if(disFlag==1) //显示
{
disFlag = 0;
t_1s++;
if(t_1s>10)
{
t_1s=0;
APP_Update();
}
if(uleiJiVal>leiJiWarn)
{
if(warn_flag==0)
warn_flag=1;
relay = 0;
}
else
{
warn_flag=0;
relay = 1;
}
if(warn_flag>0)
{
buzzer=warn_flag%2;
}
else
buzzer=1;
if(warn_flag>0)
warn_flag++;
dealLiuliang++;//处理数据
if(dealLiuliang >= 5)//计数
{
dealLiuliang = 0; //定时发送数据清空
leiJiVal=leiJiVal+(float)plu*0.00315; //累计计算累计流量
plu = 0;//清空周期计数
ushunShiVal=(u16)(shunShiVal*100);
uleiJiVal=(u16)(leiJiVal*10);
}
Lcd_Puts(0,1,(unsigned char*)"SJ:00.0L/s "); //显示
Lcd_SetXY(3,1);
Lcd_Write_Data(ushunShiVal/100+0x30);
Lcd_Write_Data('.');
Lcd_Write_Data(ushunShiVal%100/10+0x30);
Lcd_Write_Data(ushunShiVal%10+0x30);
Lcd_Puts(7,1,(unsigned char*)"L/s "); //显示
Lcd_Puts(0,0,(unsigned char*)"LJ:"); //显示
Lcd_SetXY(3,0);
if((uleiJiVal/100)>0)
Lcd_Write_Data(uleiJiVal/100+0x30);
else
Lcd_Write_Data(' ');
Lcd_Write_Data(uleiJiVal%100/10+0x30);
Lcd_Write_Data('.');
Lcd_Write_Data(uleiJiVal%10+0x30);
Lcd_Puts(7,0,(unsigned char*)"L S:"); //显示
if(set==0)
{
Lcd_SetXY(11,0);
Lcd_Write_Data(leiJiWarn/100+0x30);
Lcd_Write_Data(leiJiWarn%100/10+0x30);
Lcd_Write_Data('.');
Lcd_Write_Data(leiJiWarn%10+0x30);
Lcd_Write_Data('L');
}
else
{
Lcd_SetXY(14,0);
Lcd_Write_Command(0x0f,1);//打开显示 无光标 光标闪烁
}
}
}
}
u8 CheckKey(void)
{
unsigned char rekey=0;
if((key1==0)||(key2==0)||(key3==0)) //检测到按键按下
{
delay_ms(10); //小抖动
if(rekey==0)
{
if(key1==0) //检测是否按下
{
rekey=1;
}
else if(key2==0)//设置值键
{
rekey=2;
}
else if(key3==0)//设置值键
{
rekey=3;
}
}
}
else
{
rekey=0; //防止重复检测到按键
}
return rekey;
}