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

View File

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