功能介绍:
0.本系统采用STC89C52作为单片机
1.系统采用LCD1602实时显示水箱水位等信息
2.通过四个功能按键可设置水位等阈值
3.水位检测传感器采用的是声学的方式,超声波模块使用的是HC-SR04型号
4.采用DC002作为电源接口可直接输入5V给整个系统供电
5.一路继电器模拟控制水阀的开关,当水位低于设定阈值,继电器驱动水阀打开,反之则关闭
6.NB模块采用的是SIM7020C,该模块使用简易且性能稳定。
原理图:

PCB :

主程序:
#include "main.h"
/*******************变量定义*********************/
enum _MODE_DF_ dispMode;
bit modeFlag = AUTO; //模式标记
uchar setIndex = 0;
bit flag = 1;
float distance = 0;//水位距离
xdata int distance_H = 500;//水位上限
xdata int distance_L = 50;//水位下限
bit drawFlag1 = 0; //抽水标志1
bit buzzerFlag1 = 0; //蜂鸣器标志1
/********************************************************
函数名称:void mian()
函数作用:主函数
参数说明:
********************************************************/
void main()
{
TRIG = 0;
LCD_Init(); //初始化液晶
DelayMs(200); //延时有助于稳定
LCD_DispStr(4, 0, "Welcome!");
Uart_Init(); //初始化串口
lte_reset();
LTE_Process();
Timer0_Init();
Timer1_Init(); //初始化定时器0
LCD_Clear(); //清屏
LCD_DispStr(0, 0," H: L: ");
LCD_DispStr(0, 1," Now: mm ");
Disp4Num(3, 0, (int)distance_H);
Disp4Num(11, 0, (int)distance_L);
while (1) //死循环
{
if (flag == 1)
{
flag = 0;
if (distance > (1050 - distance_L)) //达到水位下限,1050是因为要除去超声波的盲区50mm
{
drawFlag1 = 1; //开启抽水
buzzerFlag1 = 1;
}
else if (distance < (1050 - distance_H)) //达到水位上限
{
drawFlag1 = 0; //停止抽水
buzzerFlag1 = 0;
}
else
{
buzzerFlag1 = 0;
}
if (buzzerFlag1) //蜂鸣器报警
{
BUZZER = ON;
}
else
{
BUZZER = OFF;
}
if (drawFlag1) //抽水
{
RELAY_DRAW_WATER = ON;
}
else
{
RELAY_DRAW_WATER = OFF;
}
}
else
{
LTE_Process();
}
}
}
void LTE_Process(void)
{
if (!(lte_init_flag && lte_net_flag && lte_connect_flag)) // 如果核心板未初始化、未网络配置、未连接则进行初始化
{
err_num = lte_init(); // 核心板初始化,并将初始化结果保存在 err_num
// sprintf(dis, "%1d %1d %1d %5d", (int)lte_init_flag ,(int)lte_net_flag, (int)lte_connect_flag, (int)err_num);
// LCD_DispStr(0, 1, dis);
}
if (!(lte_net_flag && lte_connect_flag) && lte_init_flag) // 初始化完成,未网络配置,未连接
{
err_num = lte_net_config(); // 进行核心板网络配置
// sprintf(dis, "%1d %1d %1d %5d", (int)lte_init_flag ,(int)lte_net_flag, (int)lte_connect_flag, (int)err_num);
// LCD_DispStr(0, 1, dis);
}
if (!lte_connect_flag && lte_init_flag && lte_net_flag) // 完成初始化和网络配置,开始连接服务器
{
err_num = lte_connect(); // 开始 TCP 连接
// sprintf(dis, "%1d %1d %1d %5d", (int)lte_init_flag ,(int)lte_net_flag, (int)lte_connect_flag, (int)err_num);
// LCD_DispStr(0, 1, dis);
}
if (!err_num && lte_init_flag && lte_connect_flag && lte_net_flag) // 连接成功,数据交互处理
{
err_num = lte_send_process();
DelayS(1);
lte_receive_process(); // 处理TCP发送过来的数据
// if (!err_num) // 未出错
// {
// lte_receive_process(); // 处理TCP发送过来的数据
// // err_num = lte_send_process();
// // err_num = heard_beat_process(); // 心跳包处理
// }
// sprintf(dis, "%1d %1d %1d %5d", (int)lte_init_flag ,(int)lte_net_flag, (int)lte_connect_flag, (int)err_num);
// LCD_DispStr(0, 1, dis);
}
if (!(lte_init_flag || lte_net_flag || lte_connect_flag) && err_num) // AT命令报错
{
err_process(err_num); // 出错处理
// sprintf(dis, "%1d %1d %1d %5d", (int)lte_init_flag ,(int)lte_net_flag, (int)lte_connect_flag, (int)err_num);
// LCD_DispStr(0, 1, dis);
}
}
/************************* 定时器0初始化 *************************/
void Timer0_Init(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
// TH0 = (65536 - 9216) / 256; //重新赋值 10ms
// TL0 = (65536 - 9216) % 256;
TH0 = 0;
TL0 = 0;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 0; //定时器开关打开
}
/************************* 定时器0中断 *************************/
void Timer0_Interrupt(void) interrupt 1
{
// static unsigned int time10ms = 0;
// TH0 = (65536 - 9216) / 256; //重新赋值 10ms
// TL0 = (65536 - 9216) % 256;
}
/************************* 定时器1初始化 *************************/
void Timer1_Init(void)
{
TMOD |= 0x10; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH1 = (65536 - 9216) / 256; //重新赋值 10ms
TL1 = (65536 - 9216) % 256;
//PT1 = 1; //高优先级
EA = 1; //总中断打开
ET1 = 1; //定时器中断打开
TR1 = 1; //定时器开关打开
}
/************************* 定时器1中断 *************************/
void Timer1_Interrupt(void) interrupt 3
{
static unsigned int time10ms = 0;
static unsigned char key_cnt = 0; // 按键计时
TH1 = (65536 - 9216) / 256; //重新赋值 10ms
TL1 = (65536 - 9216) % 256;
time10ms++;
if (time10ms > 100) //1s测一次
{
flag = 1;
Measuring(&distance);
Disp4Num(7, 1, (1050 - distance));
time10ms = 0;
}
if (KEY_SET == 0) //设置键按下
{
key_cnt++;
if (KEY_SET == 0 && key_cnt > 15)
{
setIndex++;
if (setIndex > 2)
{
setIndex = 1;
}
if (setIndex == 1)
{
LCD_DispOneChar(0, 0, '>');
LCD_DispOneChar(8, 0, ' ');
}
else if (setIndex == 2)
{
LCD_DispOneChar(0, 0, ' ');
LCD_DispOneChar(8, 0, '>');
}
key_cnt = 0;
}
}
if (KEY_ENTER == 0) //设置键按下
{
key_cnt++;
if (KEY_ENTER == 0 && key_cnt > 15)
{
setIndex = 0;
LCD_DispOneChar(0, 0, ' ');
LCD_DispOneChar(8, 0, ' ');
key_cnt = 0;
}
}
if (KEY_ADD == 0) //加键按下
{
key_cnt++;
if (KEY_ADD == 0 && key_cnt > 15)
{
if (setIndex == 1)
{
distance_H = distance_H + 10;
if (distance_H > 1000)
{
distance_H = distance_L + 10;
}
Disp4Num(3, 0, (int)distance_H);
}
else if (setIndex == 2)
{
distance_L = distance_L + 10;
if (distance_L >= distance_H)
{
distance_L = 0;
}
Disp4Num(11, 0, (int)distance_L);
}
key_cnt = 0;
}
}
if (KEY_SUB == 0) //减键按下
{
key_cnt++;
if (KEY_SUB == 0 && key_cnt > 15)
{
if (setIndex == 1)
{
distance_H = distance_H - 10;
if (distance_H <= distance_L)
{
distance_H = 1000;
}
Disp4Num(3, 0, (int)distance_H);
}
else if (setIndex == 2)
{
distance_L = distance_L - 10;
if (distance_L < 0)
{
distance_L = distance_H - 10;
}
Disp4Num(11, 0, (int)distance_L);
}
key_cnt = 0;
}
}
}
/************************* 超声波测距 *************************/
void Measuring(float *distance)
{
static long cnt = 0; //定时器计数
ES = 0;
TR1 = 0;
TRIG = 1; //启动一次模块 //不可以使用其他终端 容易造成死循环
DelayUs10x(1);
TRIG = 0;
while (!ECHO)
; //当RX为零时等待
TR0 = 1; //开启计数
while (ECHO)
; //当RX为1计数并等待
TR0 = 0;
cnt = (long)(TH0 * 256 + TL0);
TH0 = 0;
TL0 = 0;
*distance = (float)cnt * 17 / 100.0 * 1.102; //算出来是mm (g_cnt * 340 / 2) / 1000.0 * 1.102;系数
cnt = 0;
TR1 = 1;
ES = 1;
if (*distance > 1050)
{
*distance = 1050;
}
}
/************************* 显示数值 *************************/
void Disp4Num(unsigned char column, unsigned char row, int num)
{
unsigned char qian = 0;
unsigned char bai = 0;
unsigned char shi = 0;
unsigned char ge = 0;
qian = num / 1000;
bai = num % 1000 / 100;
shi = num % 100 / 10;
ge = num % 10;
LCD_DispOneChar(column, row, qian + '0');
LCD_DispOneChar(column+1, row, bai + '0');
LCD_DispOneChar(column+2, row, shi + '0');
LCD_DispOneChar(column+3, row, ge + '0');
}
该系统基于STC89C52单片机,采用LCD1602实时显示水箱水位,并通过HC-SR04超声波传感器检测水位。用户可通过四个按键设置阈值,当水位低于或超过设定值时,继电器控制水阀开关,并通过SIM7020C模块进行NB-IoT通信,实现远程监控和报警。系统还具备10ms定时器和1s定时器功能,用于水位测量和按键操作处理。
7959

被折叠的 条评论
为什么被折叠?



