根据你提供的代码和功能描述,我来总结一下这个基于 IAP15F2K60S2 单片机的液位/重量监测系统上电后的运行状态及各功能交互逻辑:
---
🟢 一、上电初始状态
· 默认界面:
· 主界面 Main_Interface = 0(数据界面)
· 子界面 Sub_Interface = 0(时间 + 温度)
· 数码管显示:
· 格式:HH:MM:SS + ±XX℃
· 示例:23:59:50 + 25℃
· LED 指示灯:
· L1 点亮(表示当前处于数据界面-时间子界面)
---
🔘 二、按键操作与数码管显示对应关系
按键 功能说明 数码管响应
S4 切换主界面(0→1→2→0) 切换后子界面重置为0
S5 切换当前主界面的子界面 更新显示内容,LED L1~L4 对应点亮
S8 仅在校准界面有效:电压+0.1V 显示 EXX=X.XV,如 E00=2.6V
S9 仅在校准界面有效:电压-0.1V 同上,电压值减少
---
📟 各主界面显示内容
主界面 0:数据界面(4个子界面)
子界面 显示内容 LED
0 时间 HH:MM:SS + 温度 ±XX℃ L1
1 液位 X.XXm + 温度 ±XX℃ L2
2 剩余百分比 XX% + 体积 X.Xm³ L3
3 温度 ±XX℃ + 重量 XX.X吨 L4
主界面 1:参数界面(8个子界面)
· 显示格式:Pn = 参数值
· 示例:P1=2.5(表示 H1=2.5)
主界面 2:校准界面(5个子界面)
· 显示格式:EXX=X.XV
· 示例:E00=2.5V(表示 0 吨对应 2.5V)
---
🔁 三、串口通信交互
指令格式 功能 响应
(T:HHMMSS) 设置时间 OK / ERROR
(H1?) 查询 H1 (H1,2.5)
(H1,3.0) 设置 H1=3.0 OK / WARN / ERROR
(F?) 查询频率阈值 (F,2000)
(S,1) 设置容器类型为圆柱体 OK
✅ 支持多参数连续配置,如:(H1,3.0)(S,1)
---
🌡️ 四、传感器数据采集与显示
· 采集频率:每 1 秒 更新一次(由定时器中断控制)
· 采集内容:
· 温度 t:read_t()
· 液位 Liquid_Level:Calc_Liquid_Level()
· 体积 Liquid_Vol:Calc_Liquid_Vol()
· 重量 Weight:Calc_Weight()
· 显示位置:
· 温度:子界面 0、3
· 液位:子界面 1
· 体积:子界面 2
· 重量:子界面 3
---
🚨 五、异常检测与报警
系统会检测以下异常,并通过串口上报和LED指示:
异常类型 错误码 LED 说明
液位超上限 500 L5 常亮 Liquid_Level > H1
液位低于下限 501 L5 常亮 Liquid_Level < H2
频率超阈值 502 L6 常亮 Freq_Cur > F
频率连续上升/下降 503 L7 闪烁 连续5次上升/下降
频率剧烈变化 504 L8 闪烁 2秒内变化 >1000Hz
🔌 任意异常触发时,继电器吸合(abnormal_flag = 1)
---
✅ 总结
这是一个功能完整的液位/重量监测系统,具备:
· ✅ 多界面数码管显示
· ✅ 按键交互(切换、校准)
· ✅ 串口通信(设置、查询、配置)
· ✅ 多传感器数据采集(温度、液位、体积、重量)
· ✅ 异常检测与报警(液位、频率)
· ✅ LED 状态指示 + 继电器控制
我需要你进一步帮我优化代码结构、添加注释或设计通信协议文档,我可以继续协助。/*头文件声明区*/
#include <STC15F2K60S2.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Init.h>
#include <Led.h>
#include <Key.h>
#include <Seg.h>
#include <onewire.h>
#include <icc.h>
#include <ultrasonic.h>
#include <Uart.h>
#include <ds1302.h>
/*
* 程序功能:基于IAP15F2K60S2单片机的液位/重量监测系统
* 优化版本:解决数码管闪烁问题,优化代码结构
*/
//-------------------------- 宏定义 --------------------------
#define SEG_BLANK 10 // 数码管熄灭
#define SEG_DASH 11 // 数码管显示"-"
#define SEG_P 12 // 数码管显示"P"
#define SEG_E 13 // 数码管显示"E"
#define MAIN_DATA 0 // 数据主界面
#define MAIN_PARAM 1 // 参数主界面
#define MAIN_CALIB 2 // 标定主界面
#define SUB_TIME 0 // 时间子界面
#define SUB_LEVEL 1 // 液位子界面
#define SUB_VOLUME 2 // 体积子界面
#define SUB_WEIGHT 3 // 重量子界面
//-------------------------- 全局变量定义 --------------------------
unsigned char Key_Val, Key_Down, Key_Old, Key_Up;
unsigned char Key_Slow_Down;
unsigned char Seg_Pos;
unsigned int xdata Seg_Slow_Down;
unsigned char xdata ucLed[8] = {0};
unsigned char Uart_Recv_Index = 0;
unsigned char Main_Interface = MAIN_DATA;
unsigned char Sub_Interface = SUB_TIME;
bit Trend_Reported = 0;
unsigned char Freq_Index = 0;
unsigned int Freq_Cur = 0;
unsigned char Data_Cnt = 0;
bit abnormal_flag = 0;
// 传感器数据变量
float xdata t = 0.0;
unsigned char xdata RTC_Time[3] = {0x23, 0x59, 0x50};
unsigned char xdata Seg_Buf[8] = {SEG_BLANK, SEG_BLANK, SEG_BLANK, SEG_BLANK,
SEG_BLANK, SEG_BLANK, SEG_BLANK, SEG_BLANK};
unsigned char xdata Seg_Point[8] = {0};
unsigned int xdata F = 2000;
unsigned char xdata S = 2;
unsigned char xdata Timer100ms_Cnt = 0;
// 界面显示缓存变量
float xdata param_val;
unsigned char xdata ton;
float xdata total_vol;
unsigned char xdata remain_percent;
unsigned char xdata hh, ss, mm;
char xdata* buf;
bit has_error = 0, has_warn = 0;
char xdata* param_start;
bit param_ok;
float xdata val;
// 静态变量(内部使用)
static unsigned int xdata cnt100ms = 0;
static bit ld7_flag = 0;
static unsigned int xdata ld8_cnt = 0;
static bit ld8_flag = 0;
// 通信缓存
char xdata Uart_Send[50] = {0};
unsigned char xdata Uart_Recv[30] = {0};
unsigned int xdata Freq_Arr[6] = {0};
// 容器参数
float xdata H1 = 1.0, H2 = 0.1;
float xdata r = 1.0, L = 1.0, W = 1.0, H = 1.0;
// 重量标定电压
float xdata Calib_Volt[5] = {0.0, 1.0, 2.0, 4.0, 5.0};
float xdata Calib_Volt_Old[5];
float xdata Ultrasonic_Dist = 0;
float xdata Liquid_Level = 0;
float xdata Liquid_Vol = 0;
float xdata Weight = 0.0;
/*-------------------------- 功能函数定义 --------------------------*/
/**
* @brief 频率测量中断服务函数
* @note 每1秒计数一次脉冲数,获取频率
*/
void Timer1_Service(void) interrupt 3
{
TR1 = 0;
Freq_Cur = (TH1 << 8) | TL1;
Freq_Arr[Freq_Index++] = Freq_Cur;
if (Freq_Index >= 6) Freq_Index = 0;
TL1 = 0x00;
TH1 = 0x00;
TR1 = 1;
}
/**
* @brief 液位计算
* @note 容器总高度 - 超声波测距值,处理边界情况
*/
void Calc_Liquid_Level(void)
{
Ultrasonic_Dist = Wave_Read();
Liquid_Level = H - Ultrasonic_Dist;
// 边界处理
if (Liquid_Level < 0) Liquid_Level = 0;
if (Liquid_Level > H) Liquid_Level = H;
}
/**
* @brief 体积计算
* @note 根据容器类型使用对应公式
*/
void Calc_Liquid_Vol(void)
{
float pi = 3.14;
switch (S)
{
case 0: // 球体容器
if (Liquid_Level <= 2 * r)
Liquid_Vol = pi * Liquid_Level * Liquid_Level * (3 * r - Liquid_Level) / 3.0;
else
Liquid_Vol = (4.0 / 3.0) * pi * r * r * r;
break;
case 1: // 圆柱体容器
Liquid_Vol = pi * r * r * Liquid_Level;
break;
case 2: // 长方体容器
Liquid_Vol = L * W * Liquid_Level;
break;
default:
Liquid_Vol = 0.0;
}
}
/**
* @brief 读取RB2引脚电压(AD转换+温度校准)
*/
float Read_RB2_Volt(void)
{
unsigned int ad_val = ad_Read(0x01);
float volt = (ad_val / 255.0) * 5.0;
// 温度校准
float calib = (0.04 * t * t - 10 * t + 225) / 1000.0;
volt += calib;
// 电压范围限制
if (volt < 0) volt = 0;
if (volt > 5.0) volt = 5.0;
return volt;
}
/**
* @brief 重量计算
* @note 基于校准后的电压,分段线性插值
*/
void Calc_Weight(void)
{
float volt = Read_RB2_Volt();
if (volt <= Calib_Volt[0])
Weight = 0.0;
else if (volt >= Calib_Volt[4])
Weight = 20.0;
else if (volt <= Calib_Volt[1])
Weight = 5.0 * (volt - Calib_Volt[0]) / (Calib_Volt[1] - Calib_Volt[0]);
else if (volt <= Calib_Volt[2])
Weight = 5.0 + 5.0 * (volt - Calib_Volt[1]) / (Calib_Volt[2] - Calib_Volt[1]);
else if (volt <= Calib_Volt[3])
Weight = 10.0 + 5.0 * (volt - Calib_Volt[2]) / (Calib_Volt[3] - Calib_Volt[2]);
else
Weight = 15.0 + 5.0 * (volt - Calib_Volt[3]) / (Calib_Volt[4] - Calib_Volt[3]);
}
/**
* @brief 时间戳转换
* @param buf 输出缓冲区,至少7字节
*/
void Get_TimeStamp(char* buf)
{
buf[0] = (RTC_Time[0] >> 4) + '0';
buf[1] = (RTC_Time[0] & 0x0F) + '0';
buf[2] = (RTC_Time[1] >> 4) + '0';
buf[3] = (RTC_Time[1] & 0x0F) + '0';
buf[4] = (RTC_Time[2] >> 4) + '0';
buf[5] = (RTC_Time[2] & 0x0F) + '0';
buf[6] = '\0';
}
/**
* @brief 异常判定与上报
* @note 检测液位、频率相关异常,控制LED和继电器
*/
void Check_Abnormal(void)
{
char time_buf[7];
Get_TimeStamp(time_buf);
abnormal_flag = 0; // 重置异常标志
// (1) 液位异常检测
if (Liquid_Level > H1)
{
sprintf(Uart_Send, "[500,%s,%.2f]\r\n", time_buf, Liquid_Level);
Uart_Send_String((unsigned char*)Uart_Send);
ucLed[4] = 1;
abnormal_flag = 1;
}
else if (Liquid_Level < H2)
{
sprintf(Uart_Send, "[501,%s,%.2f]\r\n", time_buf, Liquid_Level);
Uart_Send_String((unsigned char*)Uart_Send);
ucLed[4] = 1;
abnormal_flag = 1;
}
else
{
ucLed[4] = 0;
}
// (2) 频率数值异常
if (Freq_Cur > F)
{
sprintf(Uart_Send, "[502,%s,%d]\r\n", time_buf, Freq_Cur);
Uart_Send_String((unsigned char*)Uart_Send);
ucLed[5] = 1;
abnormal_flag = 1;
}
else
{
ucLed[5] = 0;
}
// (3) 频率趋势异常
if (Freq_Index >= 5)
{
bit up_flag = 1, down_flag = 1;
int i;
for (i = 0; i < 5; i++)
{
if (Freq_Arr[i] >= Freq_Arr[i+1]) up_flag = 0;
if (Freq_Arr[i] <= Freq_Arr[i+1]) down_flag = 0;
}
if (up_flag && !Trend_Reported)
{
sprintf(Uart_Send, "[503,%s,1]\r\n", time_buf);
Uart_Send_String((unsigned char*)Uart_Send);
Trend_Reported = 1;
ucLed[6] = 1;
abnormal_flag = 1;
}
else if (down_flag && !Trend_Reported)
{
sprintf(Uart_Send, "[503,%s,0]\r\n", time_buf);
Uart_Send_String((unsigned char*)Uart_Send);
Trend_Reported = 1;
ucLed[6] = 1;
abnormal_flag = 1;
}
else if (!up_flag && !down_flag)
{
Trend_Reported = 0;
ucLed[6] = 0;
}
}
// (4) 频率剧烈变化
if (Freq_Index >= 2)
{
int diff = abs(Freq_Arr[Freq_Index-1] - Freq_Arr[Freq_Index-3]);
if (diff > 1000)
{
sprintf(Uart_Send, "[504,%s,%d]\r\n", time_buf, diff);
Uart_Send_String((unsigned char*)Uart_Send);
ucLed[7] = 1;
Timer100ms_Cnt = 30;
abnormal_flag = 1;
}
}
// 继电器控制
Relay(abnormal_flag);
}
/**
* @brief 数码管显示更新(优化版本,解决闪烁问题)
* @note 只在数据变化时更新显示缓存,避免频繁清空
*/
void Update_Seg(void)
{
// 只在数据界面切换或数据更新时完全重置显示
static unsigned char last_main = 0xFF, last_sub = 0xFF;
if (last_main != Main_Interface || last_sub != Sub_Interface)
{
// 界面切换时完全重置显示
memset(Seg_Buf, SEG_BLANK, sizeof(Seg_Buf));
memset(Seg_Point, 0, sizeof(Seg_Point));
last_main = Main_Interface;
last_sub = Sub_Interface;
}
// (1) 数据界面显示
if (Main_Interface == MAIN_DATA)
{
switch (Sub_Interface)
{
case SUB_TIME: // 时间显示 HH:MM:SS
Seg_Buf[0] = (RTC_Time[0] >> 4) & 0x0F;
Seg_Buf[1] = RTC_Time[0] & 0x0F;
Seg_Buf[2] = SEG_DASH;
Seg_Buf[3] = (RTC_Time[1] >> 4) & 0x0F;
Seg_Buf[4] = RTC_Time[1] & 0x0F;
Seg_Buf[5] = SEG_DASH;
Seg_Buf[6] = (RTC_Time[2] >> 4) & 0x0F;
Seg_Buf[7] = RTC_Time[2] & 0x0F;
break;
case SUB_LEVEL: // 温度 + 液位 XX℃ X.XXm
// 温度显示
if (t >= 0)
{
Seg_Buf[0] = (int)t / 10 % 10;
Seg_Buf[1] = (int)t % 10;
}
else
{
Seg_Buf[0] = SEG_DASH;
Seg_Buf[1] = (int)-t % 10;
}
Seg_Buf[2] = SEG_DASH;
// 液位显示
Seg_Buf[3] = (int)Liquid_Level % 10;
Seg_Buf[4] = (int)(Liquid_Level * 10) % 10;
Seg_Buf[5] = (int)(Liquid_Level * 100) % 10;
Seg_Point[3] = 1;
break;
case SUB_VOLUME: // 剩余百分比 + 体积 XX% X.Xm3
// 计算总容积
switch (S)
{
case 0: total_vol = (4.0/3.0)*3.14*r*r*r; break;
case 1: total_vol = 3.14*r*r*H; break;
case 2: total_vol = L*W*H; break;
default: total_vol = 1.0;
}
remain_percent = (total_vol - Liquid_Vol) / total_vol * 100;
Seg_Buf[0] = remain_percent / 10 % 10;
Seg_Buf[1] = remain_percent % 10;
Seg_Buf[2] = SEG_DASH;
// 体积显示
Seg_Buf[3] = (int)Liquid_Vol % 10;
Seg_Buf[4] = (int)(Liquid_Vol * 10) % 10;
Seg_Point[3] = 1;
break;
case SUB_WEIGHT: // 温度 + 重量 XX℃ XX.X吨
// 温度显示
if (t >= 0)
{
Seg_Buf[0] = (int)t / 10 % 10;
Seg_Buf[1] = (int)t % 10;
}
else
{
Seg_Buf[0] = SEG_DASH;
Seg_Buf[1] = (int)-t % 10;
}
Seg_Buf[2] = SEG_DASH;
// 重量显示
Seg_Buf[3] = (int)Weight / 10 % 10;
Seg_Buf[4] = (int)Weight % 10;
Seg_Buf[5] = (int)(Weight * 10) % 10;
Seg_Point[4] = 1;
break;
}
}
// (2) 参数界面显示
else if (Main_Interface == MAIN_PARAM)
{
Seg_Buf[0] = SEG_P;
Seg_Buf[1] = Sub_Interface + 1;
Seg_Buf[2] = SEG_DASH;
switch (Sub_Interface)
{
case 0: param_val = H1; Seg_Point[5] = 1; break;
case 1: param_val = H2; Seg_Point[5] = 1; break;
case 2: param_val = F; break;
case 3: param_val = S; break;
case 4: param_val = r; Seg_Point[5] = 1; break;
case 5: param_val = L; Seg_Point[5] = 1; break;
case 6: param_val = W; Seg_Point[5] = 1; break;
case 7: param_val = H; Seg_Point[5] = 1; break;
}
if (Sub_Interface == 2 || Sub_Interface == 3)
{
Seg_Buf[4] = (int)param_val / 1000 % 10;
Seg_Buf[5] = (int)param_val / 100 % 10;
Seg_Buf[6] = (int)param_val / 10 % 10;
Seg_Buf[7] = (int)param_val % 10;
}
else
{
Seg_Buf[5] = (int)param_val % 10;
Seg_Buf[6] = (int)(param_val * 10) % 10;
Seg_Buf[7] = SEG_BLANK;
}
}
// (3) 标定界面显示
else
{
Seg_Buf[0] = SEG_E;
ton = Sub_Interface * 5;
Seg_Buf[1] = ton / 10 % 10;
Seg_Buf[2] = ton % 10;
Seg_Buf[3] = SEG_DASH;
Seg_Buf[5] = (int)Calib_Volt[Sub_Interface] % 10;
Seg_Buf[6] = (int)(Calib_Volt[Sub_Interface] * 10) % 10;
Seg_Point[5] = 1;
Seg_Buf[4] = Seg_Buf[7] = SEG_BLANK;
}
}
/**
* @brief 按键处理函数
*/
void Key_Proc()
{
if(Key_Slow_Down) return;
Key_Slow_Down = 1;
Key_Val = Key_Read();
Key_Down = Key_Val & (Key_Old ^ Key_Val);
Key_Up = ~Key_Val & (Key_Old ^ Key_Val);
Key_Old = Key_Val;
// S4按键:主界面切换
if (Key_Down == 4)
{
// 离开标定界面时校验标定值
if (Main_Interface == MAIN_CALIB)
{
bit calib_valid = 1;
int i;
for (i = 0; i < 4; i++)
{
if (Calib_Volt[i] > Calib_Volt[i+1] || Calib_Volt[i] < 0 || Calib_Volt[i] > 5.0)
{
calib_valid = 0;
break;
}
}
if (!calib_valid)
memcpy(Calib_Volt, Calib_Volt_Old, sizeof(Calib_Volt));
}
Main_Interface = (Main_Interface + 1) % 3;
Sub_Interface = 0;
if (Main_Interface == MAIN_CALIB)
memcpy(Calib_Volt_Old, Calib_Volt, sizeof(Calib_Volt));
// 发送当前温度
sprintf(Uart_Send, "T = %.2f\r\n", t);
Uart_Send_String((unsigned char*)Uart_Send);
// 立即更新显示
Update_Seg();
}
// S5按键:子界面切换
if (Key_Down == 5)
{
switch (Main_Interface)
{
case MAIN_DATA:
Sub_Interface = (Sub_Interface + 1) % 4;
break;
case MAIN_PARAM:
Sub_Interface = (Sub_Interface + 1) % 8;
break;
case MAIN_CALIB:
Sub_Interface = (Sub_Interface + 1) % 5;
break;
}
// 立即更新显示
Update_Seg();
}
// S8/S9按键:标定界面调整电压
if (Main_Interface == MAIN_CALIB)
{
if (Key_Down == 8)
{
Calib_Volt[Sub_Interface] += 0.1;
if (Calib_Volt[Sub_Interface] > 5.0)
Calib_Volt[Sub_Interface] = 5.0;
Update_Seg(); // 立即更新显示
}
if (Key_Down == 9)
{
Calib_Volt[Sub_Interface] -= 0.1;
if (Calib_Volt[Sub_Interface] < 0)
Calib_Volt[Sub_Interface] = 0;
Update_Seg(); // 立即更新显示
}
}
}
/**
* @brief 串口指令解析
*/
void Parse_Uart_Recv(void)
{
if (Uart_Recv_Index == 0) return;
buf = (char*)Uart_Recv;
has_error = 0;
has_warn = 0;
recv_reset:
// (1) 配置时间指令
if (buf[0] == '(' && buf[1] == 'T' && buf[2] == ':')
{
if (Uart_Recv_Index < 9)
{
Uart_Send_String((unsigned char*)"ERROR\r\n");
goto recv_reset;
}
hh = ((buf[3]-'0')<<4) | (buf[4]-'0');
mm = ((buf[5]-'0')<<4) | (buf[6]-'0');
ss = ((buf[7]-'0')<<4) | (buf[8]-'0');
if (hh < 24 && mm < 60 && ss < 60)
{
RTC_Time[0] = hh;
RTC_Time[1] = mm;
RTC_Time[2] = ss;
Set_Rtc(RTC_Time);
Uart_Send_String((unsigned char*)"OK\r\n");
}
else
{
Uart_Send_String((unsigned char*)"ERROR\r\n");
}
goto recv_reset;
}
// (2) 参数查询指令
if (buf[0] == '(' && buf[3] == '?')
{
switch (buf[1])
{
case 'H':
if (buf[2] == '1')
sprintf(Uart_Send, "(H1,%.1f)\r\n", H1);
else if (buf[2] == '2')
sprintf(Uart_Send, "(H2,%.1f)\r\n", H2);
else if (buf[2] == ')')
sprintf(Uart_Send, "(H,%.1f)\r\n", H);
else
has_error = 1;
break;
case 'h':
if (buf[2] == ')')
sprintf(Uart_Send, "(H,%.1f)\r\n", H);
else
has_error = 1;
break;
case 'F':
sprintf(Uart_Send, "(F,%d)\r\n", F);
break;
case 'S':
sprintf(Uart_Send, "(S,%d)\r\n", S);
break;
case 'r':
sprintf(Uart_Send, "(r,%.1f)\r\n", r);
break;
case 'L':
sprintf(Uart_Send, "(L,%.1f)\r\n", L);
break;
case 'W':
sprintf(Uart_Send, "(W,%.1f)\r\n", W);
break;
default:
has_error = 1;
}
if (has_error)
Uart_Send_String((unsigned char*)"ERROR\r\n");
else
Uart_Send_String((unsigned char*)Uart_Send);
goto recv_reset;
}
// (3) 参数配置指令
param_start = buf;
while (*param_start == '(')
{
char id1 = *(param_start+1);
char id2 = *(param_start+2);
char* val_start = strchr(param_start, ',') + 1;
char* param_end = strchr(param_start, ')');
if (!val_start || !param_end)
{
has_warn = 1;
break;
}
*param_end = '\0';
val = atof(val_start);
param_ok = 1;
switch (id1)
{
case 'H':
if (id2 == '1' && val > 0)
H1 = val;
else if (id2 == '2' && val > 0)
H2 = val;
else if (id2 == ',' || id2 == ')')
{
if (val > 0)
H = val;
else
param_ok = 0;
}
else
param_ok = 0;
break;
case 'F':
if (val > 0)
F = (unsigned int)val;
else
param_ok = 0;
break;
case 'S':
if (val == 0 || val == 1 || val == 2)
S = (unsigned char)val;
else
param_ok = 0;
break;
case 'r':
if (val > 0)
r = val;
else
param_ok = 0;
break;
case 'L':
if (val > 0)
L = val;
else
param_ok = 0;
break;
case 'W':
if (val > 0)
W = val;
else
param_ok = 0;
break;
default:
param_ok = 0;
break;
}
if (!param_ok) has_warn = 1;
param_start = (char*)param_end + 1;
}
// 响应配置结果
if (has_error)
Uart_Send_String((unsigned char*)"ERROR\r\n");
else if (has_warn)
Uart_Send_String((unsigned char*)"WARN\r\n");
else
Uart_Send_String((unsigned char*)"OK\r\n");
// 重置接收缓存
Uart_Recv_Index = 0;
memset(Uart_Recv, 0, sizeof(Uart_Recv));
}
/**
* @brief 定时器0中断服务函数(1ms)
* @note 优化显示逻辑,解决数码管闪烁
*/
void Timer_Server() interrupt 1
{
TL0 = 0x18;
TH0 = 0xFC;
// 1. 按键消抖计数
if (Key_Slow_Down > 0)
Key_Slow_Down--;
// 2. 数码管动态刷新(关键优化:稳定扫描)
Seg_Disp(Seg_Pos, Seg_Buf[Seg_Pos], Seg_Point[Seg_Pos]);
Seg_Pos = (Seg_Pos + 1) % 8; // 稳定的循环扫描
// 3. 数据采集计数(1秒触发)
if (++Data_Cnt >= 1000)
{
Data_Cnt = 0;
t = read_t();
Read_Rtc(RTC_Time);
Calc_Liquid_Level();
Calc_Liquid_Vol();
Calc_Weight();
Check_Abnormal();
Update_Seg(); // 数据更新后刷新显示
}
// 4. 100ms计时(LED闪烁控制)
if (++cnt100ms >= 100)
{
cnt100ms = 0;
// LD8闪烁计时
if (Timer100ms_Cnt > 0)
Timer100ms_Cnt--;
else
ucLed[7] = 0;
// LD7闪烁控制
ld7_flag = !ld7_flag;
Led_Disp(6, ucLed[6] ? ld7_flag : 0);
// LD8闪烁控制
if (++ld8_cnt >= 2)
{
ld8_cnt = 0;
ld8_flag = !ld8_flag;
Led_Disp(7, ucLed[7] ? ld8_flag : 0);
}
}
// 5. 数据界面指示灯
Led_Disp(0, (Main_Interface == MAIN_DATA && Sub_Interface == SUB_TIME) ? 1 : 0);
Led_Disp(1, (Main_Interface == MAIN_DATA && Sub_Interface == SUB_LEVEL) ? 1 : 0);
Led_Disp(2, (Main_Interface == MAIN_DATA && Sub_Interface == SUB_VOLUME) ? 1 : 0);
Led_Disp(3, (Main_Interface == MAIN_DATA && Sub_Interface == SUB_WEIGHT) ? 1 : 0);
// 6. 异常指示灯
Led_Disp(4, ucLed[4]);
Led_Disp(5, ucLed[5]);
}
/**
* @brief 串口1中断服务函数
*/
void Uart1_Service() interrupt 4
{
if(RI == 1)
{
Uart_Recv[Uart_Recv_Index] = SBUF;
Uart_Recv_Index++;
RI = 0;
}
}
/**
* @brief 主函数
*/
void main(void)
{
// 初始化硬件模块
System_Init();
Timer0_Init();
Timer1_Init();
Uart_Init();
Read_Rtc(RTC_Time);
Uart_Send_String((unsigned char*)"System Ready\r\n");
// 初始显示
Update_Seg();
// 主循环
while (1)
{
Key_Proc();
Parse_Uart_Recv();
}
}
最新发布