From 9220da7373411e111527eb3316ca00f64024e78d Mon Sep 17 00:00:00 2001 From: zouhaitao Date: Fri, 10 Jul 2026 09:34:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Sensor=5FSlot=20?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E8=87=B3=204=20=E5=AD=97=E8=8A=82=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20flags=5Fsuffix=20=E5=90=8E=E7=BC=80?= =?UTF-8?q?=E5=BA=8F=E5=8F=B7=E4=B8=8E=E5=9C=B0=E5=9D=80=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=AD=98=E5=82=A8=EF=BC=8C=E5=B9=B6=E6=94=AF=E6=8C=81=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E5=90=8D=E7=A7=B0=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/config.h | 7 ++--- App/main.c | 86 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 66 insertions(+), 27 deletions(-) diff --git a/App/config.h b/App/config.h index 798c718..e6054b5 100644 --- a/App/config.h +++ b/App/config.h @@ -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 diff --git a/App/main.c b/App/main.c index a4c4dc1..e8ef0c1 100644 --- a/App/main.c +++ b/App/main.c @@ -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 (type < 5) + // 动态计算同类型传感器的后缀序号 (如果不是覆盖已有设备) + if ((sensor_list[slot_to_use].flags_suffix & 0x80) != 0x80) { - sensor_list[slot_to_use].zone = default_zones[type]; // 自动绑定普通或24h防区类型 - // 绑定默认英文字符名 - for (i = 0; i < 15; i++) + for (i = 0; i < 16; i++) { - sensor_list[slot_to_use].name_gbk[i] = default_names[type][i]; - if (default_names[type][i] == '\0') break; + 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++; + } + } } - sensor_list[slot_to_use].name_gbk[15] = '\0'; } + else + { + // 覆盖已有设备时,保留原有后缀序号 + suffix = sensor_list[slot_to_use].flags_suffix & 0x7F; + } + + // 写入防区各项核心数据 + 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;