feat: 优化 Sensor_Slot 结构至 4 字节,实现 flags_suffix 后缀序号与地址合并存储,并支持动态名称生成

This commit is contained in:
2026-07-10 09:34:46 +08:00
parent 53b859b1c1
commit 9220da7373
2 changed files with 66 additions and 27 deletions

View File

@@ -33,11 +33,8 @@ typedef enum {
// 传感器存储结构
typedef struct {
unsigned char is_used; // 是否配对 (0x01: 已配对, 其它: 空闲)
unsigned char addr[3]; // 24位对码地址 (EV1527)
unsigned char type; // 传感器类型: 0~4
unsigned char zone; // 防区类型: 0: 24h防区, 1: 普通防区
unsigned char name_gbk[16]; // 中文防区名称 (预留)
unsigned char flags_suffix; // 属性字节Bit 7 代表有效标志 (1: 有效, 0: 空闲)Bit 0~6 代表法语防区名称的后缀序号 (01~99)
unsigned char addr[3]; // 24位对码地址 (EV1527 20位物理地址 + 4位状态数据码)
} Sensor_Slot;
#define MAIN_Fosc 24000000UL

View File

@@ -103,6 +103,7 @@ void Uart_SendHex20(u32 val);
void Uart_SendHex32(u32 val);
void Uart_SendHex16(u16 val);
void FormatHex(u32 val, char *buf);
void Format_Sensor_Name(u8 slot, char *buf);
// IAP 闪存读写底层声明
void IAP_Disable(void);
@@ -344,16 +345,18 @@ void Add_Sensor(u32 addr, u8 type)
{
u8 i;
u8 slot_to_use = 15; // 若槽位已满,默认覆盖最后一个位置
u8 suffix = 1;
u32 db_addr = (addr << 4) | (type & 0x0F);
// 查找是否有空余位置,或者该 ID 已经配对过
for (i = 0; i < 16; i++)
{
if (sensor_list[i].is_used == 0x01)
if ((sensor_list[i].flags_suffix & 0x80) == 0x80)
{
u32 existing_addr = ((u32)sensor_list[i].addr[0] << 16) |
((u32)sensor_list[i].addr[1] << 8) |
sensor_list[i].addr[2];
if (existing_addr == addr)
if ((existing_addr >> 4) == addr)
{
slot_to_use = i;
break;
@@ -366,24 +369,34 @@ void Add_Sensor(u32 addr, u8 type)
}
}
// 写入防区各项核心数据
sensor_list[slot_to_use].is_used = 0x01;
sensor_list[slot_to_use].addr[0] = (u8)(addr >> 16);
sensor_list[slot_to_use].addr[1] = (u8)(addr >> 8);
sensor_list[slot_to_use].addr[2] = (u8)addr;
sensor_list[slot_to_use].type = type;
// 动态计算同类型传感器的后缀序号 (如果不是覆盖已有设备)
if ((sensor_list[slot_to_use].flags_suffix & 0x80) != 0x80)
{
for (i = 0; i < 16; i++)
{
if ((sensor_list[i].flags_suffix & 0x80) == 0x80)
{
u32 slot_addr = ((u32)sensor_list[i].addr[0] << 16) |
((u32)sensor_list[i].addr[1] << 8) |
sensor_list[i].addr[2];
if ((slot_addr & 0x0F) == type)
{
suffix++;
}
}
}
}
else
{
// 覆盖已有设备时,保留原有后缀序号
suffix = sensor_list[slot_to_use].flags_suffix & 0x7F;
}
if (type < 5)
{
sensor_list[slot_to_use].zone = default_zones[type]; // 自动绑定普通或24h防区类型
// 绑定默认英文字符名
for (i = 0; i < 15; i++)
{
sensor_list[slot_to_use].name_gbk[i] = default_names[type][i];
if (default_names[type][i] == '\0') break;
}
sensor_list[slot_to_use].name_gbk[15] = '\0';
}
// 写入防区各项核心数据
sensor_list[slot_to_use].flags_suffix = 0x80 | (suffix & 0x7F);
sensor_list[slot_to_use].addr[0] = (u8)(db_addr >> 16);
sensor_list[slot_to_use].addr[1] = (u8)(db_addr >> 8);
sensor_list[slot_to_use].addr[2] = (u8)db_addr;
Save_Database(); // 立即同步存盘
}
@@ -394,12 +407,12 @@ bit Check_Sensor_ID(u32 addr, u8 *out_slot_index)
u8 i;
for (i = 0; i < 16; i++)
{
if (sensor_list[i].is_used == 0x01)
if ((sensor_list[i].flags_suffix & 0x80) == 0x80)
{
u32 slot_addr = ((u32)sensor_list[i].addr[0] << 16) |
((u32)sensor_list[i].addr[1] << 8) |
sensor_list[i].addr[2];
if (slot_addr == addr)
if ((slot_addr >> 4) == addr)
{
*out_slot_index = i;
return 1; // 匹配成功
@@ -511,6 +524,27 @@ void FormatHex(u32 val, char *buf)
buf[13] = '\0';
}
void Format_Sensor_Name(u8 slot, char *buf)
{
u8 i = 0;
u32 slot_addr = ((u32)sensor_list[slot].addr[0] << 16) |
((u32)sensor_list[slot].addr[1] << 8) |
sensor_list[slot].addr[2];
u8 type = slot_addr & 0x0F;
u8 suffix = sensor_list[slot].flags_suffix & 0x7F;
char *name_prefix = (type < 5) ? default_names[type] : "SENSOR";
while (name_prefix[i] != '\0' && i < 15)
{
buf[i] = name_prefix[i];
i++;
}
buf[i++] = ' ';
buf[i++] = '0' + (suffix / 10);
buf[i++] = '0' + (suffix % 10);
buf[i] = '\0';
}
/* =========================================================================
* UI 页面渲染函数
* ========================================================================= */
@@ -737,7 +771,9 @@ void Timer1_Isr(void) interrupt 3
else if (current_state == STATE_ALARM)
{
// 传感器告警模式:根据不同传感器类型执行专属灯光颜色与特定振动模式
u8 stype = sensor_list[alarm_sensor_slot].type;
u8 stype = (((u32)sensor_list[alarm_sensor_slot].addr[0] << 16) |
((u32)sensor_list[alarm_sensor_slot].addr[1] << 8) |
sensor_list[alarm_sensor_slot].addr[2]) & 0x0F;
alarm_timer_ms++;
if (alarm_timer_ms >= 5000) alarm_timer_ms = 0; // 5秒周期循环
@@ -1306,10 +1342,12 @@ void main(void)
else if (current_state == STATE_ALARM)
{
u8 slot;
static char alarm_name[24];
char *name = "UNKNOWN SENSOR";
if (Check_Sensor_ID(captured_addr, &slot))
{
name = sensor_list[slot].name_gbk; // 获取对应的注册英文名字
Format_Sensor_Name(slot, alarm_name);
name = alarm_name;
alarm_sensor_slot = slot;
}
UI_ShowAlarmPage(name, 1);
@@ -1339,11 +1377,15 @@ void main(void)
u8 slot;
if (Check_Sensor_ID(rx_addr, &slot)) // 检查接收 of 地址是否在配对列表中
{
u8 sensor_type = sensor_list[slot].type;
u32 slot_addr = ((u32)sensor_list[slot].addr[0] << 16) |
((u32)sensor_list[slot].addr[1] << 8) |
sensor_list[slot].addr[2];
u8 sensor_type = slot_addr & 0x0F;
if (sensor_type < 5) // 仅触发普通防区传感器彻底过滤并排除SOS信号接收
{
u8 zone = default_zones[sensor_type];
// 24小时防区 (zone==0) 任何时候都触发,普通防区 (zone==1) 仅在 ARMED 状态下触发
if (sensor_list[slot].zone == 0 || current_state == STATE_ARMED)
if (zone == 0 || current_state == STATE_ARMED)
{
captured_addr = rx_addr;
current_state = STATE_ALARM;