diff --git a/leakage_system/MDK-ARM/RTE/_leakage_system/RTE_Components.h b/leakage_system/MDK-ARM/RTE/_leakage_system/RTE_Components.h
index 0246594..153dac0 100644
--- a/leakage_system/MDK-ARM/RTE/_leakage_system/RTE_Components.h
+++ b/leakage_system/MDK-ARM/RTE/_leakage_system/RTE_Components.h
@@ -11,5 +11,11 @@
#define RTE_COMPONENTS_H
+/*
+ * Define the Device Header File:
+ */
+#define CMSIS_device_header "stm32f4xx.h"
+
+
#endif /* RTE_COMPONENTS_H */
diff --git a/leakage_system/MDK-ARM/leakage_system.uvprojx b/leakage_system/MDK-ARM/leakage_system.uvprojx
index 78663ef..1c6f363 100644
--- a/leakage_system/MDK-ARM/leakage_system.uvprojx
+++ b/leakage_system/MDK-ARM/leakage_system.uvprojx
@@ -10,14 +10,14 @@
leakage_system
0x4
ARM-ADS
- 5060960::V5.06 update 7 (build 960)::.\ARMCC
+ 5060750::V5.06 update 6 (build 750)::ARMCC
0
STM32F407VGTx
STMicroelectronics
- Keil.STM32F4xx_DFP.3.0.0
- https://www.keil.com/pack/
+ Keil.STM32F4xx_DFP.2.15.0
+ http://www.keil.com/pack/
IRAM(0x20000000,0x00020000) IRAM2(0x10000000,0x00010000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE
@@ -185,7 +185,6 @@
0
2
0
- 0
1
0
8
@@ -352,7 +351,7 @@
0
0
0
- 4
+ 0
@@ -787,13 +786,4 @@
-
-
-
- leakage_system
- 1
-
-
-
-
diff --git a/leakage_system/usr/app/app.c b/leakage_system/usr/app/app.c
index 49c34e6..4fddc85 100644
--- a/leakage_system/usr/app/app.c
+++ b/leakage_system/usr/app/app.c
@@ -60,6 +60,8 @@ void app_init(void)
/*flash*/
w25q32.init();
+// HAL_Delay(5000);
+
/*串口初始化*/
com_uart1.init(&com_uart1);
com_uart2.init(&com_uart2);
@@ -148,7 +150,7 @@ void task_500ms(void)
modbus_leakage[APP_COM1].tx_task(&modbus_leakage[APP_COM1]);
modbus_leakage[APP_COM2].tx_task(&modbus_leakage[APP_COM2]);
modbus_leakage[APP_COM3].tx_task(&modbus_leakage[APP_COM3]);
-// modbus_leakage[APP_COM4].tx_task(&modbus_leakage[APP_COM4]);
+ modbus_leakage[APP_COM4].tx_task(&modbus_leakage[APP_COM4]);
}
diff --git a/leakage_system/usr/app/app_com.c b/leakage_system/usr/app/app_com.c
index 842b3a1..36bf6c8 100644
--- a/leakage_system/usr/app/app_com.c
+++ b/leakage_system/usr/app/app_com.c
@@ -1,5 +1,7 @@
#include "app_com.h"
#include "app_leakage.h"
+#include "bsp_w25q.h"
+#include
#include "proto_modbus_master_leakage.h"
/*com口对应的串口*/
@@ -11,32 +13,91 @@ bsp_uart_t *com_to_uart[APP_COM_NUM] =
&com_uart6,
};
-static void app_com_uart_class_rate_set(app_com_class_t * p_com,u16 baud_rate);
+static void app_com_class_baud_rate_set(app_com_class_t *p_com, u32 baud_enum);
static void app_com_class_update(void );
static void app_com_init(void);
+static void app_com_save_baudrate_to_flash(void);
+static void app_com_load_baudrate_from_flash(void);
app_com_t app_com=
{
.init = app_com_init,
.class_update = app_com_class_update,
+ .save_flah = app_com_save_baudrate_to_flash,
};
+
static void app_com_init(void)
{
u8 i;
for(i=0;icom_uart->set.baud_rate(p_com->com_uart,baud_rate);
+ u32 baud_value;
+ switch (baud_enum) {
+ case 0: baud_value = 4800; break;
+ case 1: baud_value = 9600; break;
+ case 2: baud_value = 19200; break;
+ case 3: baud_value = 57600; break;
+ case 4: baud_value = 115200; break;
+ default: baud_value = 115200; break;
+ }
+ if (p_com->com_uart && p_com->com_uart->set.baud_rate) {
+ p_com->com_uart->set.baud_rate(p_com->com_uart, baud_value);
+ }
+}
+
+/* 从Flash加载波特率到内存并应用 */
+static void app_com_load_baudrate_from_flash(void)
+{
+ u8 baud_vals[APP_COM_NUM];
+ w25q32.read(W25Q32_COM_BAUDRATE_ADDR, baud_vals, APP_COM_NUM);
+
+ for (u8 i = 0; i < APP_COM_NUM; i++) {
+ if (baud_vals[i] == 0xFF) { // 未初始化,设为默认115200
+ app_com.com[i].flash_data.baudrate = 4;
+ } else {
+ app_com.com[i].flash_data.baudrate = baud_vals[i];
+ }
+ // 应用波特率到串口硬件
+ app_com_class_baud_rate_set(&app_com.com[i], app_com.com[i].flash_data.baudrate);
+ }
+}
+
+/* 将当前波特率保存到Flash */
+static void app_com_save_baudrate_to_flash(void)
+{
+ u8 current_vals[APP_COM_NUM];
+ u8 flash_vals[APP_COM_NUM];
+
+ /*当前内存中的波特率枚举值*/
+ for (u8 i = 0; i < APP_COM_NUM; i++) {
+ current_vals[i] = app_com.com[i].flash_data.baudrate;
+ }
+
+ /*从 Flash 读取已存储的值*/
+ w25q32.read(W25Q32_COM_BAUDRATE_ADDR, flash_vals, APP_COM_NUM);
+
+ // 比较是否完全相同
+ if (memcmp(current_vals, flash_vals, APP_COM_NUM) == 0) {
+ // 没有变化,无需写入
+ return;
+ }
+
+ // 擦除包含该地址的扇区(4K对齐)
+ uint32_t erase_addr = W25Q32_COM_BAUDRATE_ADDR & ~(W25Q32_SECTOR_SIZE - 1);
+ w25q32_sector_erase(erase_addr);
+ w25q32.write(W25Q32_COM_BAUDRATE_ADDR, current_vals, APP_COM_NUM);
}
@@ -61,10 +122,18 @@ static void app_com_class_update(void )
/********************************************COM口划分******************************************************/
com_index = leakage.sub_device_data[i].flash_data.com;
id = leakage.sub_device_data[i].flash_data.modbus_id;
+
+ proto_sensor_class_t *p_sensor = &modbus_leakage[com_index].sensor[modbus_leakage[com_index].sensor_num];
+
+ /* ★ 清空整个传感器结构体 */
+ memset(p_sensor, 0, sizeof(proto_sensor_class_t));
+
/*绑定modbus id*/
- modbus_leakage[com_index].sensor[modbus_leakage[com_index].sensor_num].comm.id = id;
+ p_sensor->comm.id = id;
/*绑定子设备索引索引*/
- modbus_leakage[com_index].sensor[modbus_leakage[com_index].sensor_num].comm.leakage_data_index = i;
+ p_sensor->comm.leakage_data_index = i;
+ /* ★ 设置初始状态为默认(发送请求) */
+ p_sensor->comm.state = PROTO_LEAKAGE_COMM_STATE_DEFAULT;
/*comm口设备总数++*/
modbus_leakage[com_index].sensor_num++;
}
diff --git a/leakage_system/usr/app/app_com.h b/leakage_system/usr/app/app_com.h
index a9453f0..042a0fe 100644
--- a/leakage_system/usr/app/app_com.h
+++ b/leakage_system/usr/app/app_com.h
@@ -26,7 +26,7 @@ struct app_com_class_t
bsp_uart_t *com_uart; /*绑定的实际物理串口*/
struct
{
- void (*baud_rate)(app_com_class_t *,u16); /*设置波特率*/
+ void (*baud_rate)(app_com_class_t *,u32); /*设置波特率*/
}set;
//void (*init)(app_com_class_t *); /*初始化*/
};
@@ -36,6 +36,7 @@ typedef struct
app_com_class_t com[APP_COM_NUM];
void (*init)(void); /*初始化*/
void (*class_update)(void ); /*com区域分类*/
+ void (*save_flah)(void);
}app_com_t;
extern app_com_t app_com;
diff --git a/leakage_system/usr/app/app_leakage.c b/leakage_system/usr/app/app_leakage.c
index b7affb8..71e914d 100644
--- a/leakage_system/usr/app/app_leakage.c
+++ b/leakage_system/usr/app/app_leakage.c
@@ -4,6 +4,7 @@
#include "bsp_w25q.h"
#include "bsp_buzzer.h"
#include "bsp_relay.h"
+#include "bsp_DS1302.h"
static void history_clear_all(void);
static u8 history_read_record(u32 record_index, app_leakage_history_alarm_t *record);
@@ -32,6 +33,11 @@ app_hitory_t history =
static void app_leakage_init(void)
{
+// for(int i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
+// {
+// memset(leakage.sub_device_data[i].ch_data, 0,
+// sizeof(leakage.sub_device_data[i].ch_data));
+// }
app_leakage_region_classify();
}
@@ -61,7 +67,7 @@ void app_leakage_region_classify(void)
if(0 == memcmp(p_leakage->region_data[j].name,p_leakage->sub_device_data[i].flash_data.region_name, APP_LEAKAGE_STRING_NANE_LEN))/*名称相同*/
{
/*添加子设备*/
- p_leakage->region_data[j].sub_device_index[p_leakage->region_data[j].leakage_num] = i;/*绑定子设备索引*/
+ p_leakage->region_data[j].sub_device_index[p_leakage->region_data[j].sub_device_num] = i;/*绑定子设备索引*/
p_leakage->region_data[j].sub_device_num++; /*区域中子系统数据++*/
add_region_flag = 0;/*不添加新区域*/
break;
@@ -72,10 +78,13 @@ void app_leakage_region_classify(void)
if(add_region_flag)/*添加新区域*/
{
/*复制名称*/
- memcpy(p_leakage->region_data[p_leakage->region_num].name,p_leakage->sub_device_data[i].flash_data.region_name, APP_LEAKAGE_STRING_NANE_LEN);
- p_leakage->region_data[p_leakage->region_num].sub_device_index[p_leakage->region_data[p_leakage->region_num].leakage_num] = i;/*绑定子设备索引*/
- p_leakage->region_data[p_leakage->region_num].sub_device_num++; /*区域中子系统数据++*/
- p_leakage->region_num++; /*区域数量++*/
+ memcpy(p_leakage->region_data[p_leakage->region_num].name,
+ p_leakage->sub_device_data[i].flash_data.region_name,
+ APP_LEAKAGE_STRING_NANE_LEN);
+ // 第一个设备索引为0
+ p_leakage->region_data[p_leakage->region_num].sub_device_index[0] = i;
+ p_leakage->region_data[p_leakage->region_num].sub_device_num = 1;
+ p_leakage->region_num++;
}
}
}
@@ -153,6 +162,12 @@ void app_leakage_task(void)
continue;
}
+ /* 检查设备是否屏蔽 */
+ if(p_leakage->sub_device_data[sub_device_index].flash_data.shield != UNBLOCKED)
+ {
+ continue;
+ }
+
/*历史报警存储*/
for(k = 0; k < APP_LEAKAGE_SUB_DEVICE_CH_NUM; k++)
{
@@ -195,6 +210,7 @@ void app_leakage_task(void)
{
p_leakage->region_data[i].time_out_num++;
p_leakage->alarm_state |= APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT;
+ break;
}
else if(current_state & APP_LEAKAGE_SUB_DEVICE_STATE_OPEN)
{
@@ -204,7 +220,7 @@ void app_leakage_task(void)
else if(current_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
{
p_leakage->region_data[i].leakage_num++;
- p_leakage->alarm_state |= APP_LEAKAGE_SUB_DEVICE_STATE_OPEN;
+ p_leakage->alarm_state |= APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE;
}
}
@@ -217,21 +233,15 @@ void app_leakage_task(void)
/* 获取当前时间 */
static void get_current_time(u8 *time_buffer)
{
-// RTC_TimeTypeDef sTime;
-// RTC_DateTypeDef sDate;
-//
-// /* 获取RTC时间 */
-// HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
-// HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
-//
-// /* 年: 2字节 (例如: 2024 -> 0x07 0xE8) */
-// uint16_t year = 2000 + sDate.Year; /* RTC年份通常从2000开始 */
-// time_buffer[0] = (year >> 8) & 0xFF; /* 高字节 */
-// time_buffer[1] = year & 0xFF; /* 低字节 */
-// time_buffer[2] = sDate.Month; /* 月 */
-// time_buffer[3] = sDate.Date; /* 日 */
-// time_buffer[4] = sTime.Hours; /* 时 */
-// time_buffer[5] = sTime.Minutes; /* 分 */
+ /* 年: 2字节 (例如: 2024 -> 0x07 0xE8) */
+ uint16_t year = 2000 + DS1302.Time.Year; /* RTC年份通常从2000开始 */
+ time_buffer[0] = (year >> 8) & 0xFF; /* 高字节 */
+ time_buffer[1] = year & 0xFF; /* 低字节 */
+ time_buffer[2] = DS1302.Time.Month; /* 月 */
+ time_buffer[3] = DS1302.Time.Day; /* 日 */
+ time_buffer[4] = DS1302.Time.Hour; /* 时 */
+ time_buffer[5] = DS1302.Time.Minute; /* 分 */
+ time_buffer[6] = DS1302.Time.Second; /* 秒 */
}
/* 从Flash读取历史报警元数据 */
diff --git a/leakage_system/usr/app/app_leakage.h b/leakage_system/usr/app/app_leakage.h
index 8739a9a..1fc04fa 100644
--- a/leakage_system/usr/app/app_leakage.h
+++ b/leakage_system/usr/app/app_leakage.h
@@ -6,6 +6,9 @@
#define ENABLE (1)
#define DISABLE (0)
+#define BLOCKED (1) /*屏蔽*/
+#define UNBLOCKED (0)
+
#define APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE (0x0001) /*漏液状态*/
#define APP_LEAKAGE_SUB_DEVICE_STATE_OPEN (0x0002) /*断带状态*/
#define APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT (0x8000) /*通讯超时*/
@@ -24,6 +27,8 @@ typedef struct
{
u8 state; /*状态 使能 非使能*/
u8 com; /*端口*/
+ u8 baudrate; /*波特率*/
+ u8 shield; /*设备屏蔽状态*/
u8 modbus_id; /*modbus id*/
u8 device_name[APP_LEAKAGE_STRING_NANE_LEN]; /*设备名*/
u8 region_name[APP_LEAKAGE_STRING_NANE_LEN]; /*区域名*/
@@ -61,7 +66,7 @@ typedef struct
u8 device_id; /* 设备ID */
u8 device_name[APP_LEAKAGE_STRING_NANE_LEN]; /* 设备名称 */
u16 alarm_type; /* 报警类型 */
- u8 start_time[6]; /* 开始时间: 年(2字节)月日时分 */
+ u8 start_time[7]; /* 开始时间: 年(2字节)月日时分 */
u16 leak_distance; /* 漏液距离 (0表示非漏液报警) */
u8 channel; /* 通道号 (0-3) */
} app_leakage_history_alarm_t;
diff --git a/leakage_system/usr/bsp/bsp_buzzer.c b/leakage_system/usr/bsp/bsp_buzzer.c
index 778cfec..97aaac1 100644
--- a/leakage_system/usr/bsp/bsp_buzzer.c
+++ b/leakage_system/usr/bsp/bsp_buzzer.c
@@ -1,4 +1,5 @@
#include "bsp_buzzer.h"
+#include "bsp_w25q.h"
/*开关控制电平,使用同一的电平控制方式*/
#define BUZZER_GPIO_ON GPIO_PIN_SET
@@ -14,6 +15,7 @@ static void bsp_buzzer_on(void);
static void bsp_buzzer_off(void);
static void bsp_buzzer_enable(void);
static void bsp_buzzer_disable(void);
+static void bsp_buzzer_flash_data_load(void);
bsp_buzzer_t buzzer =
{
@@ -35,11 +37,40 @@ static void bsp_buzzer_init(void)
{
BUZZER_OFF;
p_buzzer->p_flash_data = &flash_data;
+ bsp_buzzer_flash_data_load();
}
static void bsp_buzzer_flash_data_save(void)
{
-
+ // 擦除整个扇区(地址是扇区起始)
+ w25q32_sector_erase(W25Q32_BUZZER_STATE_ADDR);
+ w25q32.write(W25Q32_BUZZER_STATE_ADDR, (uint8_t*)&flash_data, sizeof(bsp_buzzer_flash_data_t));
+}
+
+static void bsp_buzzer_flash_data_load(void)
+{
+ w25q32.read(W25Q32_BUZZER_STATE_ADDR, (uint8_t*)&flash_data, sizeof(bsp_buzzer_flash_data_t));
+
+ // 检查是否全为0xFF(首次使用)
+ uint8_t *p = (uint8_t*)&flash_data;
+ u8 all_ff = 1;
+ for (u8 i = 0; i < sizeof(bsp_buzzer_flash_data_t); i++) {
+ if (p[i] != 0xFF) {
+ all_ff = 0;
+ break;
+ }
+ }
+
+ if (all_ff) {
+ // 首次使用,默认关闭蜂鸣器
+ flash_data.sw = USR_DISABLE;
+ bsp_buzzer_flash_data_save();
+ }
+
+ // 根据加载的状态设置蜂鸣器使能
+ if (flash_data.sw == USR_ENABLE) {
+ p_buzzer->p_flash_data->sw = flash_data.sw;
+ }
}
static void bsp_buzzer_task(void)
diff --git a/leakage_system/usr/bsp/bsp_uart.c b/leakage_system/usr/bsp/bsp_uart.c
index 61ac7f4..527c078 100644
--- a/leakage_system/usr/bsp/bsp_uart.c
+++ b/leakage_system/usr/bsp/bsp_uart.c
@@ -57,7 +57,7 @@ static void bsp_uart_rx_task(bsp_uart_t *p_uart);
static void bsp_uart_rx_time_start(bsp_uart_t *p_uart);
static void bsp_uart_tx_dma_tc_int(bsp_uart_t *p_uart);
static void bsp_uart_dma_send(bsp_uart_t *p_uart, u8 *p_data, u16 len);
-static void bsp_uart_baud_rate_set(bsp_uart_t *p_uart,u16 baud_rate);
+static void bsp_uart_baud_rate_set(bsp_uart_t *p_uart,u32 baud_rate);
/* 外部HAL句柄声明 */
extern UART_HandleTypeDef huart1;
@@ -269,7 +269,7 @@ static void bsp_uart_init(bsp_uart_t *p_uart)
HAL_UARTEx_ReceiveToIdle_DMA(p_uart->uart, p_uart->rx_addr, p_uart->rx_dma_len);
}
-static void bsp_uart_baud_rate_set(bsp_uart_t *p_uart,u16 baud_rate)
+static void bsp_uart_baud_rate_set(bsp_uart_t *p_uart,u32 baud_rate)
{
p_uart->uart->Init.BaudRate = baud_rate;
HAL_UART_Init(p_uart->uart);
diff --git a/leakage_system/usr/bsp/bsp_uart.h b/leakage_system/usr/bsp/bsp_uart.h
index 1027655..a17e082 100644
--- a/leakage_system/usr/bsp/bsp_uart.h
+++ b/leakage_system/usr/bsp/bsp_uart.h
@@ -61,7 +61,7 @@ struct bsp_uart_t
struct
{
- void (*baud_rate)(bsp_uart_t *,u16);
+ void (*baud_rate)(bsp_uart_t *,u32);
}set;
void (*init)(bsp_uart_t *); /* 初始化函数指针 */
diff --git a/leakage_system/usr/bsp/bsp_w25q.h b/leakage_system/usr/bsp/bsp_w25q.h
index 5f29c8f..d227b83 100644
--- a/leakage_system/usr/bsp/bsp_w25q.h
+++ b/leakage_system/usr/bsp/bsp_w25q.h
@@ -49,6 +49,12 @@ void w25q32_sector_erase(uint32_t sector_addr);
#define MAX_HISTORY_ALARM_RECORDS (1000) /* 最大历史报警记录数 */
#define HISTORY_ALARM_SECTORS_NEEDED ((MAX_HISTORY_ALARM_RECORDS * HISTORY_ALARM_RECORD_SIZE + W25Q32_SECTOR_SIZE - 1) / W25Q32_SECTOR_SIZE)
+/* COM口波特率存储地址 - 使用独立扇区(扇区13) */
+#define W25Q32_COM_BAUDRATE_ADDR 0x00D000 /*存储4个COM口波特率枚举值(4字节)*/
+
+/* 蜂鸣器状态存储地址 - 使用独立扇区(扇区14) */
+#define W25Q32_BUZZER_STATE_ADDR 0x00E000 /*存储蜂鸣器状态(1字节)*/
+
/* w25q32 对象结构体 */
typedef struct {
void (*init)(void);
diff --git a/leakage_system/usr/gui/gui_tjc_hmi.c b/leakage_system/usr/gui/gui_tjc_hmi.c
index 6622205..ce66976 100644
--- a/leakage_system/usr/gui/gui_tjc_hmi.c
+++ b/leakage_system/usr/gui/gui_tjc_hmi.c
@@ -66,15 +66,13 @@ static char *hmi_proto_string_com[] =
/*字符名称 波特率*/
static char *hmi_proto_string_baudrate[] =
{
+ "2400",
"4800",
"9600",
- "19200",
- "57600",
"115200",
};
-
static bsp_uart_t * p_rx_uart = NULL;
gui_tjc_hmi_t tjc_hmi =
@@ -127,6 +125,8 @@ static void gui_tjc_hmi_read_password_from_w25q(void)
/*将密码保存到W25Q32*/
static void gui_tjc_hmi_save_password_to_w25q(void)
{
+ uint32_t erase_addr = W25Q32_PASSWORD_ADDR & ~(W25Q32_SECTOR_SIZE - 1);
+ w25q32_sector_erase(erase_addr);
/*将4字节密码写入W25Q32*/
w25q32.write(W25Q32_PASSWORD_ADDR, p_tjc_hmi->password, 4);
}
@@ -158,6 +158,23 @@ static void gui_tjc_hmi_save_device_info_to_w25q(void)
DEVICE_INFO_STORAGE_SIZE);
}
+/*解析网络函数*/
+static void parse_ip_string(u8 *str, u8 len, u8 *ip)
+{
+ u8 i = 0, part = 0, val = 0;
+ while (i < len) {
+ if (str[i] == '.') {
+ ip[part++] = val;
+ val = 0;
+ } else if (str[i] >= '0' && str[i] <= '9') {
+ val = val * 10 + (str[i] - '0');
+ }
+ i++;
+ }
+ ip[part] = val; // 最后一个部分
+}
+
+
/*设置对应的控件
x:第几行
y:第几个
@@ -225,12 +242,42 @@ static void gui_tjc_hmi_main_send(u8 cmd,u8 opa,u8 *p_data)
DS1302.Time.Second);
len += gui_tjc_hmi_tx_text_display(0,0,(char *)&hmi_tx_buffer[len],"%s",time);
+ /*IP地址*/
+ len += gui_tjc_hmi_tx_text_display(0,1,(char *)&hmi_tx_buffer[len],
+ "%d.%d.%d.%d",
+ W5500.IP_Addr[0],
+ W5500.IP_Addr[1],
+ W5500.IP_Addr[2],
+ W5500.IP_Addr[3]);
+
+ /*蜂鸣器状态*/
+ u8 buzzer_state = (buzzer.p_flash_data->sw == USR_ENABLE) ? 11 : 13;
+ /*构造 "sw0.val=x" 指令(x 为 0 或 1)*/
+ len += sprintf((char*)&hmi_tx_buffer[len], "p4.pic=%d", buzzer_state);
+ for (u8 i = 0; i < 3; i++)
+ {
+ hmi_tx_buffer[len + i] = 0xFF;
+ }
+ len += 3;
+
if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
{
switch(opa)
{
case 0x01:/*读取区域信息*/
{
+ if (leakage.region_num == 0)
+ {
+ for (j = 0; j < MAIN_PAGE_SUB_DEVICE_NUM; j++)
+ {
+ for (y = 0; y < 5; y++)
+ {
+ len += gui_tjc_hmi_tx_text_display(j+1, y+1, (char *)&hmi_tx_buffer[len], "");
+ }
+ }
+ break;
+ }
+
if(p_tjc_hmi->page.main_index == page_num - 1 && remain_region_num >0)/*显示剩余区域*/
{
for(j=0;jsub_device_num / DETAIL_MAIN_NUM;
- remain_device_num = region_data->sub_device_num % DETAIL_MAIN_NUM;
- if (remain_device_num > 0)
- {
- page_num++;
- }
+// /* 计算详情页面数量:每页显示4个设备 */
+// page_num = region_data->sub_device_num / DETAIL_MAIN_NUM;
+// remain_device_num = region_data->sub_device_num % DETAIL_MAIN_NUM;
+// if (remain_device_num > 0)
+// {
+// page_num++;
+// }
if (HMI_PROTO_CMD_GET == cmd) /* 获取数据 */
{
@@ -610,61 +721,39 @@ static void gui_tjc_hmi_detail_main_send(u8 cmd, u8 opa, u8 *p_data)
{
case 0x01: /* 获取设备详情信息 */
{
- /* 从指令中获取区域索引 (p_data[0] = 相对区域索引,从1开始,对应当前主界面的1-4) */
u8 relative_region_idx = p_data[0];
-
if (relative_region_idx < 1 || relative_region_idx > 4)
- {
- /* 相对区域索引无效,默认显示第一个 */
-// relative_region_idx = 1;
return;
- }
-
- /* 计算全局区域索引: 全局索引 = 主界面页码 * 4 + 相对索引 - 1 */
+
+ /* 计算全局区域索引 */
region_idx = p_tjc_hmi->page.main_index * 4 + (relative_region_idx - 1);
-
- /* 检查区域索引是否有效 */
if (region_idx >= leakage.region_num)
- {
- /* 区域索引越界,尝试显示第一个区域 */
-// region_idx = 0;
return;
- }
-
- /* 判断是否切换了区域 */
+
+ /* 切换区域时重置详情页码 */
if (region_idx != p_tjc_hmi->page.deliniter_main_index)
- {
- p_tjc_hmi->page.detail_main_index = 0;
- }
-
- /* 保存当前区域索引和主界面页码,翻页时使用 */
+ p_tjc_hmi->page.detail_main_index = 0;
+
p_tjc_hmi->page.deliniter_main_index = region_idx;
-
- /* 获取区域数据 */
region_data = &leakage.region_data[region_idx];
-
- /* 获取当前详情页面的设备数据 */
+
+ /* 计算页面参数 */
+ page_num = region_data->sub_device_num / DETAIL_MAIN_NUM;
+ remain_device_num = region_data->sub_device_num % DETAIL_MAIN_NUM;
+ if (remain_device_num > 0) page_num++;
+ if (page_num == 0) page_num = 1;
+
u8 start_index = p_tjc_hmi->page.detail_main_index * DETAIL_MAIN_NUM;
-
- if (p_tjc_hmi->page.detail_main_index == page_num - 1 && remain_device_num > 0)
- {
- display_count = remain_device_num;
- }
- else
- {
- display_count = DETAIL_MAIN_NUM;
- }
+ display_count = (p_tjc_hmi->page.detail_main_index == page_num - 1 && remain_device_num > 0)
+ ? remain_device_num : DETAIL_MAIN_NUM;
for (i = 0; i < display_count; i++)
{
index = start_index + i;
-
if (index >= region_data->sub_device_num)
break;
-
- /* 获取设备的全局索引 */
sub_device_index = region_data->sub_device_index[index];
- x = i; /* 0-3表示当前详情页面的4个设备位置 */
+ x = i;
/* 设备ID: t(x+1)_1 */
y = 0;
@@ -692,19 +781,28 @@ static void gui_tjc_hmi_detail_main_send(u8 cmd, u8 opa, u8 *p_data)
break;
}
}
- if (comm_state)
+ if(leakage.sub_device_data[sub_device_index].flash_data.shield == UNBLOCKED)
{
- len += gui_tjc_hmi_tx_text_display(x+1, y+1,
- (char *)&hmi_tx_buffer[len],
- "超时");
- }
- else
+ if (comm_state)
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1,
+ (char *)&hmi_tx_buffer[len],
+ "超时");
+ }
+ else
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1,
+ (char *)&hmi_tx_buffer[len],
+ "正常");
+ }
+ }else
{
len += gui_tjc_hmi_tx_text_display(x+1, y+1,
(char *)&hmi_tx_buffer[len],
"正常");
}
+
/* 通道1-4状态 */
for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
{
@@ -713,68 +811,120 @@ static void gui_tjc_hmi_detail_main_send(u8 cmd, u8 opa, u8 *p_data)
/* 漏液状态 */
y = 3 + (ch * 3);
- if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
+ if(leakage.sub_device_data[sub_device_index].flash_data.shield == UNBLOCKED)
{
- len += gui_tjc_hmi_tx_text_display(x+1, y+1,
- (char *)&hmi_tx_buffer[len],
- "漏液");
- }
- else
+ if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1,
+ (char *)&hmi_tx_buffer[len],
+ "漏液");
+ }
+ else
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1,
+ (char *)&hmi_tx_buffer[len],
+ "正常");
+ }
+ }else
{
len += gui_tjc_hmi_tx_text_display(x+1, y+1,
(char *)&hmi_tx_buffer[len],
"正常");
}
+
/* 断带状态 */
y = 4 + (ch * 3);
- if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_OPEN)
+ if(leakage.sub_device_data[sub_device_index].flash_data.shield == UNBLOCKED)
{
- len += gui_tjc_hmi_tx_text_display(x+1, y+1,
- (char *)&hmi_tx_buffer[len],
- "断带");
- }
- else
+ if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_OPEN)
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1,
+ (char *)&hmi_tx_buffer[len],
+ "断带");
+ }
+ else
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1,
+ (char *)&hmi_tx_buffer[len],
+ "正常");
+ }
+ }else
{
len += gui_tjc_hmi_tx_text_display(x+1, y+1,
(char *)&hmi_tx_buffer[len],
"正常");
}
+
/* 漏液位置 */
y = 5 + (ch * 3);
- if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
+ if(leakage.sub_device_data[sub_device_index].flash_data.shield == UNBLOCKED)
+ {
+ if (ch_state & APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1,
+ (char *)&hmi_tx_buffer[len],
+ "%d",
+ ch_distance);
+ }
+ else
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1,
+ (char *)&hmi_tx_buffer[len],
+ "0");
+ }
+ }else
{
len += gui_tjc_hmi_tx_text_display(x+1, y+1,
- (char *)&hmi_tx_buffer[len],
- "%d",
- ch_distance);
- }
- else
- {
- len += gui_tjc_hmi_tx_text_display(x+1, y+1,
- (char *)&hmi_tx_buffer[len],
- "0");
+ (char *)&hmi_tx_buffer[len],
+ "0");
}
+
}
+ /* 屏蔽状态显示: t(x+1)_16 */
+ y = 15; // 第16列对应y=15
+ if (leakage.sub_device_data[sub_device_index].flash_data.shield == BLOCKED)
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1, (char *)&hmi_tx_buffer[len], "禁用中");
+ }
+ else
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, y+1, (char *)&hmi_tx_buffer[len], "启用中");
+ }
+ }
+
+ /*清空未使用的*/
+ for (; i < DETAIL_MAIN_NUM; i++)
+ {
+ x = i;
+ len += gui_tjc_hmi_tx_text_display(x+1, 1, (char *)&hmi_tx_buffer[len], "");
+ len += gui_tjc_hmi_tx_text_display(x+1, 2, (char *)&hmi_tx_buffer[len], "");
+ len += gui_tjc_hmi_tx_text_display(x+1, 3, (char *)&hmi_tx_buffer[len], "");
+ for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
+ {
+ len += gui_tjc_hmi_tx_text_display(x+1, 4 + (ch*3), (char *)&hmi_tx_buffer[len], "");
+ len += gui_tjc_hmi_tx_text_display(x+1, 5 + (ch*3), (char *)&hmi_tx_buffer[len], "");
+ len += gui_tjc_hmi_tx_text_display(x+1, 6 + (ch*3), (char *)&hmi_tx_buffer[len], "");
+ }
+ len += gui_tjc_hmi_tx_text_display(x+1, 16, (char *)&hmi_tx_buffer[len], "");
}
}
break;
case 0x03: /* 翻页 */
{
- /* 使用之前保存的全局区域索引 */
- region_idx = p_tjc_hmi->page.deliniter_main_index;
-
- /* 检查区域索引是否有效 */
- if (region_idx >= leakage.region_num)
- {
- return; /* 区域索引越界 */
- }
-
- /* 获取区域数据 */
+ region_idx = p_tjc_hmi->page.deliniter_main_index;
+ if (region_idx >= leakage.region_num) return;
+
region_data = &leakage.region_data[region_idx];
+ /*重新计算页数*/
+ page_num = region_data->sub_device_num / DETAIL_MAIN_NUM;
+ remain_device_num = region_data->sub_device_num % DETAIL_MAIN_NUM;
+ if (remain_device_num > 0) page_num++;
+ if (page_num == 0) page_num = 1;
+
if(0x01 == p_data[0]) /* 下一页 */
{
if(page_num - 1 <= p_tjc_hmi->page.detail_main_index)
@@ -814,7 +964,63 @@ static void gui_tjc_hmi_detail_main_send(u8 cmd, u8 opa, u8 *p_data)
{
case 0x01: /* */
{
-
+ u8 len_id = 0;
+ u8 device_id = 0;
+
+ /* 解析设备ID:从p_data[0]开始,直到遇到分隔符 */
+ while (p_data[len_id] != HMI_PROTO_ASCII_RX_DELINITER) {
+ if (p_data[len_id] < '0' || p_data[len_id] > '9') {
+ return; /* 非法字符 */
+ }
+ len_id++;
+ if (len_id > 3) { /* ID最多3位数字(0-255) */
+ return;
+ }
+ }
+ if (len_id == 0) {
+ return; /* ID不能为空 */
+ }
+
+ /* 将ASCII数字串转换为数值 */
+ char id_str[4] = {0}; /* 最多3位数字加'\0' */
+ memcpy(id_str, p_data, len_id);
+ id_str[len_id] = '\0';
+ int temp_id = atoi(id_str);
+ if (temp_id < 0 || temp_id > 255) {
+ return; /* ID超出范围 */
+ }
+ device_id = (u8)temp_id;
+
+ /* 检查操作码及其后的分隔符 */
+ u8 op_index = len_id + 1; /* 操作码位置 */
+ u8 delim_index = len_id + 2; /* 操作码后的分隔符位置 */
+ if (p_data[delim_index] != HMI_PROTO_ASCII_RX_DELINITER) {
+ return;
+ }
+ u8 operation = p_data[op_index]; /* 操作码直接作为数值 */
+
+ /* 遍历所有使能的设备,查找匹配的modbus_id */
+ u8 found = 0;
+ for (u8 i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++) {
+ if (leakage.sub_device_data[i].flash_data.state == ENABLE &&
+ leakage.sub_device_data[i].flash_data.modbus_id == device_id) {
+ if (operation == 0x01) {
+ leakage.sub_device_data[i].flash_data.shield = BLOCKED; /* 屏蔽 */
+ } else if (operation == 0x02) {
+ leakage.sub_device_data[i].flash_data.shield = UNBLOCKED; /* 恢复 */
+ } else {
+ return;
+ }
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ {
+ /*将修改后的设备信息保存到 Flash*/
+ gui_tjc_hmi_save_device_info_to_w25q();
+ }
+ return;
}
break;
@@ -828,53 +1034,56 @@ static void gui_tjc_hmi_login_send(u8 cmd,u8 opa,u8 *p_data)
{
u16 len = 0,i;
- if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
+ if(HMI_PROTO_CMD_GET == cmd) /* 获取数据 */
{
switch(opa)
{
- case 0x01:/*读取flash中存储的密码*/
+ case 0x01: /* 读取flash中存储的密码 */
{
- memset(hmi_tx_buffer,0,sizeof(hmi_tx_buffer));
- len = gui_tjc_hmi_tx_text_display(1,1,(char *)hmi_tx_buffer,"%02X%02X%02X%02X",
- p_tjc_hmi->password[0],
- p_tjc_hmi->password[1],
- p_tjc_hmi->password[2],
- p_tjc_hmi->password[3]);
-
- gui_tjc_hmi_data_send(hmi_tx_buffer,len);
-
- }break;
- case 0x02:/*无*/
- {
-
- }break;
- default:return;
+ gui_tjc_hmi_read_password_from_w25q();
+ memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));
+ /* 将密码数值以连续数字形式发送到控件 t22_1 */
+ len = gui_tjc_hmi_tx_text_display(22, 1, (char *)hmi_tx_buffer,
+ "%d%d%d%d",
+ p_tjc_hmi->password[0],
+ p_tjc_hmi->password[1],
+ p_tjc_hmi->password[2],
+ p_tjc_hmi->password[3]);
+ gui_tjc_hmi_data_send(hmi_tx_buffer, len);
+ return; /* 直接返回,避免外层重复发送 */
+ } break;
+ case 0x02: /* 无操作 */
+ default:
+ return;
}
- len = strlen((char *)hmi_tx_buffer);
- gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
- else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
+ else if(HMI_PROTO_CMD_SET == cmd) /* 设置数据 */
{
switch(opa)
{
- case 0x01:/*将密码存入flash中*/
+ case 0x01: /* 将密码存入flash */
{
- for(i=0; i<4; i++)
+ /* 将ASCII码转换为数值('0'~'9') */
+ for(i = 0; i < 4; i++)
{
- p_tjc_hmi->password[i] = p_data[i];
+ if(p_data[i] >= '0' && p_data[i] <= '9')
+ {
+ p_tjc_hmi->password[i] = p_data[i] - '0';
+ }
+ else
+ {
+ p_tjc_hmi->password[i] = 0; /* 非法字符时清零 */
+ }
}
-
- /*保存到W25Q32*/
+ /* 保存到W25Q32 */
gui_tjc_hmi_save_password_to_w25q();
- }break;
- case 0x02:/*无*/
- {
-
- }break;
- default:return;
+ /* 设置命令无需响应,直接返回 */
+ return;
+ } break;
+ case 0x02: /* 无操作 */
+ default:
+ return;
}
- len = strlen((char *)hmi_tx_buffer);
- gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
}
@@ -955,11 +1164,11 @@ static void gui_tjc_hmi_history_alarm_send(u8 cmd,u8 opa,u8 *p_data)
"%d",
history_record.device_id);
- /* 设备名称: t(i+1)_3 */
- len += gui_tjc_hmi_tx_text_display(i+1, 3,
- (char *)&hmi_tx_buffer[len],
- "%s",
- history_record.device_name);
+ /*通道信息:t(i+1)_3*/
+ len += gui_tjc_hmi_tx_text_display(i+1,3,
+ (char *)&hmi_tx_buffer[len],
+ "%d",
+ history_record.channel);
/* 报警类型: t(i+1)_4 */
alarm_type_str[0] = '\0';
@@ -975,18 +1184,11 @@ static void gui_tjc_hmi_history_alarm_send(u8 cmd,u8 opa,u8 *p_data)
"%s",
alarm_type_str);
- /* 开始时间: t(i+1)_5 */
- uint16_t year = (history_record.start_time[0] << 8) | history_record.start_time[1];
- sprintf(time_str, "%04d-%02d-%02d %02d:%02d",
- year,
- history_record.start_time[2],
- history_record.start_time[3],
- history_record.start_time[4],
- history_record.start_time[5]);
+ /* 设备名称: t(i+1)_5 */
len += gui_tjc_hmi_tx_text_display(i+1, 5,
(char *)&hmi_tx_buffer[len],
"%s",
- time_str);
+ history_record.device_name);
/* 漏液距离: t(i+1)_6 (如果是漏液报警才显示) */
if(history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
@@ -1002,6 +1204,20 @@ static void gui_tjc_hmi_history_alarm_send(u8 cmd,u8 opa,u8 *p_data)
(char *)&hmi_tx_buffer[len],
"0");
}
+
+ /* 开始时间: t(i+1)_7 */
+ uint16_t year = (history_record.start_time[0] << 8) | history_record.start_time[1];
+ sprintf(time_str, "%04d-%02d-%02d %02d:%02d:%02d",
+ year,
+ history_record.start_time[2],
+ history_record.start_time[3],
+ history_record.start_time[4],
+ history_record.start_time[5],
+ history_record.start_time[6]);
+ len += gui_tjc_hmi_tx_text_display(i+1, 7,
+ (char *)&hmi_tx_buffer[len],
+ "%s",
+ time_str);
}
else
{
@@ -1069,6 +1285,24 @@ static void gui_tjc_hmi_history_alarm_send(u8 cmd,u8 opa,u8 *p_data)
case 0x01:/*清空*/
{
history.clean_history();
+ p_tjc_hmi->page.history_alarm_index = 0; // 重置页码
+
+ memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));
+ len = 0;
+
+// // 清空所有15行的7列数据
+// for(i = 0; i < HISTORY_ALARM_PER_PAGE; i++)
+// {
+// len += gui_tjc_hmi_tx_text_display(i+1, 1, (char *)&hmi_tx_buffer[len], ""); // 区域名
+// len += gui_tjc_hmi_tx_text_display(i+1, 2, (char *)&hmi_tx_buffer[len], ""); // 设备ID
+// len += gui_tjc_hmi_tx_text_display(i+1, 3, (char *)&hmi_tx_buffer[len], ""); // 通道
+// len += gui_tjc_hmi_tx_text_display(i+1, 4, (char *)&hmi_tx_buffer[len], ""); // 报警类型
+// len += gui_tjc_hmi_tx_text_display(i+1, 5, (char *)&hmi_tx_buffer[len], ""); // 设备名称
+// len += gui_tjc_hmi_tx_text_display(i+1, 6, (char *)&hmi_tx_buffer[len], ""); // 漏液距离
+// len += gui_tjc_hmi_tx_text_display(i+1, 7, (char *)&hmi_tx_buffer[len], ""); // 时间
+// }
+
+ gui_tjc_hmi_data_send(hmi_tx_buffer, len);
}break;
case 0x02:/*无*/
{
@@ -1116,13 +1350,13 @@ static void gui_tjc_hmi_tcp_config_send(u8 cmd,u8 opa,u8 *p_data)
W5500.Gateway_IP[1],
W5500.Gateway_IP[2],
W5500.Gateway_IP[3]);
- len += gui_tjc_hmi_tx_text_display(1,4,(char *)&hmi_tx_buffer[len],"%s","114.114.114.114");
+ len += gui_tjc_hmi_tx_text_display(1,4,(char *)&hmi_tx_buffer[len],"%s","5000");
}else if(p_data[0] == 0x00)
{
len += gui_tjc_hmi_tx_text_display(1,1,(char *)&hmi_tx_buffer[len],"%s","192.168.100.100");
len += gui_tjc_hmi_tx_text_display(1,2,(char *)&hmi_tx_buffer[len],"%s","255.255.255.0");
len += gui_tjc_hmi_tx_text_display(1,3,(char *)&hmi_tx_buffer[len],"%s","192.168.50.1");
- len += gui_tjc_hmi_tx_text_display(1,4,(char *)&hmi_tx_buffer[len],"%s","114.114.114.114");
+ len += gui_tjc_hmi_tx_text_display(1,4,(char *)&hmi_tx_buffer[len],"%s","5000");
}
}break;
case 0x02:/*无*/
@@ -1141,56 +1375,63 @@ static void gui_tjc_hmi_tcp_config_send(u8 cmd,u8 opa,u8 *p_data)
case 0x01:/*添加网络配置,并将网络配置信息存入flash*/
{
u8 field_count = 0;
- u8 *current_pos = p_data;
-
- /*解析IP地址*/
- for(i=0; i<16; i++)
- {
- if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
- {
- memcpy(W5500.IP_Addr, current_pos, i);
- current_pos += (i + 1);
- field_count++;
- break;
+ u8 *current_pos = p_data;
+ u8 ip_str[16], mask_str[16], gw_str[16], dns_str[16];
+ u8 ip_len, mask_len, gw_len, dns_len;
+
+ /* 解析IP地址 */
+ for (i = 0; i < 16; i++) {
+ if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER) {
+ ip_len = i;
+ memcpy(ip_str, current_pos, ip_len);
+ ip_str[ip_len] = '\0';
+ current_pos += (i + 1);
+ field_count++;
+ break;
+ }
}
- }
-
- /*解析子网掩码*/
- for(i=0; i<16; i++)
- {
- if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
- {
- memcpy(W5500.Sub_Mask, current_pos, i);
- current_pos += (i + 1);
- field_count++;
- break;
+
+ /* 解析子网掩码 */
+ for (i = 0; i < 16; i++) {
+ if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER) {
+ mask_len = i;
+ memcpy(mask_str, current_pos, mask_len);
+ mask_str[mask_len] = '\0';
+ current_pos += (i + 1);
+ field_count++;
+ break;
+ }
}
- }
-
- /*解析网关*/
- for(i=0; i<16; i++)
- {
- if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
- {
- memcpy(W5500.Gateway_IP, current_pos, i);
- current_pos += (i + 1);
- field_count++;
- break;
+
+ /* 解析网关 */
+ for (i = 0; i < 16; i++) {
+ if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER) {
+ gw_len = i;
+ memcpy(gw_str, current_pos, gw_len);
+ gw_str[gw_len] = '\0';
+ current_pos += (i + 1);
+ field_count++;
+ break;
+ }
}
- }
-
- /*解析DNS服务器*/
- for(i=0; i<16; i++)
- {
- if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
- {
-// memcpy(p_tjc_hmi->network_config.dns, current_pos, i);
-// p_tjc_hmi->network_config.dns[i] = '\0';
- field_count++;
- break;
+
+ /* 解析DNS服务器 */
+ for (i = 0; i < 16; i++) {
+ if (current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER) {
+ dns_len = i;
+ memcpy(dns_str, current_pos, dns_len);
+ dns_str[dns_len] = '\0';
+ current_pos += (i + 1);
+ field_count++;
+ break;
+ }
+ }
+
+ if (field_count == 4) {
+ parse_ip_string(ip_str, ip_len, W5500.IP_Addr);
+ parse_ip_string(mask_str, mask_len, W5500.Sub_Mask);
+ parse_ip_string(gw_str, gw_len, W5500.Gateway_IP);
}
- }
-
}break;
case 0x02:/*无*/
@@ -1217,22 +1458,6 @@ static void gui_tjc_hmi_device_config_send(u8 cmd,u8 opa,u8 *p_data)
memset(hmi_tx_buffer,0,sizeof(hmi_tx_buffer));
-
-
- /*计算总页数*/
- page_num = enabled_device_count / DEVICES_PER_PAGE;
- remain_region_num = enabled_device_count % DEVICES_PER_PAGE;
- if(remain_region_num > 0)
- {
- page_num++;
- }
-
- /*确保页码在有效范围内*/
- if(p_tjc_hmi->page.device_config_index >= page_num)
- {
- p_tjc_hmi->page.device_config_index = 0;
- }
-
if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
{
switch(opa)
@@ -1253,9 +1478,32 @@ static void gui_tjc_hmi_device_config_send(u8 cmd,u8 opa,u8 *p_data)
enabled_device_count++;
}
}
-
+
+ /*计算总页数*/
+ page_num = enabled_device_count / DEVICES_PER_PAGE;
+ remain_region_num = enabled_device_count % DEVICES_PER_PAGE;
+ if(remain_region_num > 0)
+ {
+ page_num++;
+ }
+
+ /*确保页码在有效范围内*/
+ if(p_tjc_hmi->page.device_config_index >= page_num)
+ {
+ p_tjc_hmi->page.device_config_index = 0;
+ }
+
if(enabled_device_count == 0)
{
+ for(i = 0; i < DEVICES_PER_PAGE; i++)
+ {
+ len += gui_tjc_hmi_tx_text_display(i+1, 1, (char *)&hmi_tx_buffer[len], "");
+ len += gui_tjc_hmi_tx_text_display(i+1, 2, (char *)&hmi_tx_buffer[len], "");
+ len += gui_tjc_hmi_tx_text_display(i+1, 3, (char *)&hmi_tx_buffer[len], "");
+ len += gui_tjc_hmi_tx_text_display(i+1, 4, (char *)&hmi_tx_buffer[len], "");
+ }
+ len = strlen((char *)hmi_tx_buffer);
+ gui_tjc_hmi_data_send(hmi_tx_buffer, len);
return;
}
@@ -1353,8 +1601,53 @@ static void gui_tjc_hmi_device_config_send(u8 cmd,u8 opa,u8 *p_data)
}break;
+ case 0x02: /*读取四个COM口的波特率*/
+ {
+ u8 baud_vals[4];
+ for (i = 0; i < 4; i++) {
+ baud_vals[i] = app_com.com[i].flash_data.baudrate;
+ }
+
+ len = 0;
+ len += sprintf((char*)&hmi_tx_buffer[len], "cb0.val=%d", baud_vals[0]);
+ for (i = 0; i < 3; i++) hmi_tx_buffer[len + i] = 0xFF;
+ len += 3;
+
+ len += sprintf((char*)&hmi_tx_buffer[len], "cb1.val=%d", baud_vals[1]);
+ for (i = 0; i < 3; i++) hmi_tx_buffer[len + i] = 0xFF;
+ len += 3;
+
+ len += sprintf((char*)&hmi_tx_buffer[len], "cb2.val=%d", baud_vals[2]);
+ for (i = 0; i < 3; i++) hmi_tx_buffer[len + i] = 0xFF;
+ len += 3;
+
+ len += sprintf((char*)&hmi_tx_buffer[len], "cb3.val=%d", baud_vals[3]);
+ for (i = 0; i < 3; i++) hmi_tx_buffer[len + i] = 0xFF;
+ len += 3;
+
+ gui_tjc_hmi_data_send(hmi_tx_buffer, len);
+ return;
+ } break;
+
case 0x03:/*翻页功能,每页显示8个设备*/
{
+ enabled_device_count = 0;
+ for (i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
+ {
+ if (leakage.sub_device_data[i].flash_data.state == ENABLE)
+ {
+ enabled_device_count++;
+ }
+ }
+
+ page_num = enabled_device_count / DEVICES_PER_PAGE;
+ remain_region_num = enabled_device_count % DEVICES_PER_PAGE;
+ if (remain_region_num > 0)
+ {
+ page_num++;
+ }
+ if (page_num == 0) page_num = 1;
+
if(0x01 == p_data[0]) /*下一页*/
{
if(page_num - 1 <= p_tjc_hmi->page.device_config_index)
@@ -1452,6 +1745,45 @@ static void gui_tjc_hmi_device_config_send(u8 cmd,u8 opa,u8 *p_data)
}
}
+// /*解析波特率*/
+// for(i = 0; i < 10; i++) // 波特率最大为115200
+// {
+// if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
+// {
+// if(i == 0)
+// {
+// /*波特率不能为空*/
+// return;
+// }
+
+// char baud_str[10] = {0};
+// memcpy(baud_str, current_pos, i);
+// baud_str[i] = '\0';
+
+// /*将字符串波特率转换为数值*/
+// if(strcmp(baud_str, "2400") == 0)
+// {
+// new_device.baudrate = 0;
+// }
+// else if(strcmp(baud_str, "4800") == 0)
+// {
+// new_device.baudrate = 1;
+// }
+// else if(strcmp(baud_str, "9600") == 0)
+// {
+// new_device.baudrate = 2;
+// }
+// else if(strcmp(baud_str, "115200") == 0)
+// {
+// new_device.baudrate = 3;
+// }
+
+// current_pos += (i + 1);
+// field_count++;
+// break;
+// }
+// }
+
/*解析区域名*/
for(i = 0; i < APP_LEAKAGE_STRING_NANE_LEN; i++)
{
@@ -1508,6 +1840,8 @@ static void gui_tjc_hmi_device_config_send(u8 cmd,u8 opa,u8 *p_data)
if (leakage.sub_device_data[x].flash_data.modbus_id == new_device.modbus_id)
{
new_device.state = ENABLE;
+ new_device.baudrate = app_com.com[new_device.com].flash_data.baudrate;
+ new_device.shield = UNBLOCKED;
leakage.sub_device_data[x].flash_data = new_device;
gui_tjc_hmi_save_device_info_to_w25q();
gui_tjc_hmi_class_update();
@@ -1522,15 +1856,31 @@ static void gui_tjc_hmi_device_config_send(u8 cmd,u8 opa,u8 *p_data)
/*设置默认状态为启用*/
new_device.state = ENABLE;
+ /*波特率设置*/
+ new_device.baudrate = app_com.com[new_device.com].flash_data.baudrate;
+
+ new_device.shield = UNBLOCKED;
+
/*添加到app_leakage的设备列表中*/
leakage.sub_device_data[empty_slot_index].flash_data = new_device;
+ /*清空通道数据*/
+ memset(leakage.sub_device_data[empty_slot_index].ch_data, 0,
+ sizeof(leakage.sub_device_data[empty_slot_index].ch_data));
+
/*保存到W25Q32*/
gui_tjc_hmi_save_device_info_to_w25q();
/*重新分类区域*/
gui_tjc_hmi_class_update();
+// if (new_device.com < APP_COM_NUM && new_device.baudrate < 4) {
+// app_com.com[new_device.com].set.baud_rate(
+// &app_com.com[new_device.com],
+// new_device.baudrate
+// );
+// }
+
}
else
{
@@ -1568,64 +1918,94 @@ static void gui_tjc_hmi_device_config_send(u8 cmd,u8 opa,u8 *p_data)
return;
}
- /*遍历8个选中框字节,删除被选中的设备*/
- u8 deleted_count = 0; /*记录删除的设备数量*/
- u8 shift_offset = 0; /*偏移量,用于处理删除后设备索引的变化*/
-
- for(i = 0; i < 8; i++)
+ /*遍历8个选中框字节,删除被选中的设备(从后往前删除)*/
+ u8 deleted_count = 0;
+ for(i = page_device_count; i > 0; i--)
{
- /*只处理当前页实际存在的设备*/
- if(i >= page_device_count)
+ u8 idx = i - 1;
+ if(p_data[idx] == 0x01)
{
- break;
- }
-
- /*检查设备是否被选中删除*/
- if(p_data[i] == 0x01)
- {
- /*计算实际要删除的设备在app_leakage中的索引*/
- u8 actual_index = page_device_indices[i] - shift_offset;
-
- /*直接删除设备:将后面的设备向前移动*/
+ u8 actual_index = page_device_indices[idx]; // 直接使用原始索引
+ /*将后面的设备向前移动*/
for(j = actual_index; j < APP_LEAKAGE_SUB_DEVICE_NUM - 1; j++)
{
leakage.sub_device_data[j].flash_data = leakage.sub_device_data[j + 1].flash_data;
}
-
/*最后一个设备清空*/
- memset(&leakage.sub_device_data[APP_LEAKAGE_SUB_DEVICE_NUM - 1].flash_data, 0,
+ memset(&leakage.sub_device_data[APP_LEAKAGE_SUB_DEVICE_NUM - 1].flash_data, 0,
sizeof(app_leakage_sub_device_flash_data_t));
leakage.sub_device_data[APP_LEAKAGE_SUB_DEVICE_NUM - 1].flash_data.state = DISABLE;
- /*删除设备后,后面的设备索引会变化,更新偏移量*/
- shift_offset++;
- deleted_count++;
+ /*清空通道数据*/
+ memset(leakage.sub_device_data[APP_LEAKAGE_SUB_DEVICE_NUM - 1].ch_data, 0,
+ sizeof(leakage.sub_device_data[APP_LEAKAGE_SUB_DEVICE_NUM - 1].ch_data));
- /*重新计算当前页的设备索引,设备前移*/
- for(u8 k = i + 1; k < page_device_count; k++)
- {
- page_device_indices[k]--;
- }
+ deleted_count++;
}
}
-
+
if(deleted_count > 0)
{
/*保存到W25Q32*/
gui_tjc_hmi_save_device_info_to_w25q();
-
/*重新分类区域*/
gui_tjc_hmi_class_update();
-
- /*发送确认响应*/
+ /*可选:发送确认响应*/
}
else
{
/*没有选中任何设备*/
- return;
+ return;
}
- }break;
- default:return;
+ }break;
+
+ case 0x03: /*设置波特率,波特率1对应COM1的*/
+ {
+ u8 *ptr = p_data;
+ u8 baud_vals[APP_COM_NUM];
+ char temp_buf[10]; /*临时存储ASCII字符串*/
+
+ for (i = 0; i < APP_COM_NUM; i++) {
+ u8 temp_len = 0;
+ // 提取直到下一个0xAA分隔符
+ while (*ptr != HMI_PROTO_ASCII_RX_DELINITER && temp_len < sizeof(temp_buf) - 1) {
+ temp_buf[temp_len++] = *ptr++;
+ }
+ if (*ptr != HMI_PROTO_ASCII_RX_DELINITER) {
+ return;
+ }
+ temp_buf[temp_len] = '\0';
+ ptr++; // 跳过分隔符
+
+ // 将ASCII字符串转换为整数波特率
+ u32 baud_int = atoi(temp_buf);
+
+ // 映射到枚举值
+ u8 enum_val;
+ if (baud_int == 4800) enum_val = 0;
+ else if (baud_int == 9600) enum_val = 1;
+ else if (baud_int == 19200) enum_val = 2;
+ else if (baud_int == 57600) enum_val = 3;
+ else if (baud_int == 115200) enum_val = 4;
+ else enum_val = 4;
+
+ baud_vals[i] = enum_val;
+ }
+
+ /*设置每个COM的波特率*/
+ for (i = 0; i < APP_COM_NUM; i++) {
+ if (app_com.com[i].flash_data.baudrate != baud_vals[i]) {
+ app_com.com[i].flash_data.baudrate = baud_vals[i];
+ if (app_com.com[i].set.baud_rate) {
+ app_com.com[i].set.baud_rate(&app_com.com[i], baud_vals[i]);
+ }
+ }
+ }
+ app_com.save_flah();
+ return;
+ } break;
+
+ default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
@@ -1645,41 +2025,48 @@ static void gui_tjc_hmi_time_set_send(u8 cmd,u8 opa,u8 *p_data)
{
case 0x01: /* 设置时间 */
{
- /* 检查数据长度 */
- if(p_data[4] != 0xAA || /* 年后的分隔符 */
- p_data[7] != 0xAA || /* 月后的分隔符 */
- p_data[10] != 0xAA || /* 日后的分隔符 */
- p_data[13] != 0xAA) /* 时后的分隔符 */
+ int idx = 0; /*数据索引*/
+ int field = 0; /*当前字段编号(0:年,1:月,2:日,3:时,4:分)*/
+ char temp_buf[5];
+ int value;
+
+ while (field < 5)
+ {
+ int len = 0;
+ /*收集当前字段的ASCII字符直到遇到分隔符0xAA*/
+ while (p_data[idx] != 0xAA)
+ {
+ if (len >= 4)
+ {
+ return;
+ }
+ temp_buf[len++] = p_data[idx++];
+ }
+
+ if (len == 0)
{
return;
}
-
- /* 解析年份 (4个字节ASCII码) */
- memcpy(temp_buf, &p_data[0], 4);
- temp_buf[4] = '\0'; /* 添加结束符 */
- new_time.Year = atoi(temp_buf)%2000;
-
- /* 解析月份 (2个字节ASCII码) */
- memcpy(temp_buf, &p_data[5], 2);
- temp_buf[2] = '\0'; /* 添加结束符 */
- new_time.Month = atoi(temp_buf);
-
- /* 解析日期 (2个字节ASCII码) */
- memcpy(temp_buf, &p_data[8], 2);
- temp_buf[2] = '\0'; /* 添加结束符 */
- new_time.Day = atoi(temp_buf);
-
- /* 解析小时 (2个字节ASCII码) */
- memcpy(temp_buf, &p_data[11], 2);
- temp_buf[2] = '\0'; /* 添加结束符 */
- new_time.Hour = atoi(temp_buf);
-
- /* 解析分钟 (2个字节ASCII码) */
- memcpy(temp_buf, &p_data[14], 2);
- temp_buf[2] = '\0'; /* 添加结束符 */
- new_time.Minute = atoi(temp_buf);
-
- DS1302.Set(&new_time);
+
+ temp_buf[len] = '\0';
+ value = atoi(temp_buf);
+
+ /* 根据字段序号赋值*/
+ switch (field)
+ {
+ case 0: new_time.Year = value % 2000; break; // 年份取后两位
+ case 1: new_time.Month = value; break;
+ case 2: new_time.Day = value; break;
+ case 3: new_time.Hour = value; break;
+ case 4: new_time.Minute = value; break;
+ }
+
+ /*跳过当前分隔符0xAA,准备下一个字段*/
+ idx++;
+ field++;
+ }
+
+ DS1302.Set(&new_time);
}
break;
diff --git a/leakage_system/usr/protocol/proto_modbus_master_leakage.c b/leakage_system/usr/protocol/proto_modbus_master_leakage.c
index a515d40..bd0c5fa 100644
--- a/leakage_system/usr/protocol/proto_modbus_master_leakage.c
+++ b/leakage_system/usr/protocol/proto_modbus_master_leakage.c
@@ -68,7 +68,7 @@ static void proto_leakage_init(proto_leakage_t *p_leakage)
}
else if(p_leakage == &modbus_leakage[APP_COM4])
{
- com_to_uart[APP_COM3]->rx_data_analysis = proto_leakage_rx_task;
+ com_to_uart[APP_COM4]->rx_data_analysis = proto_leakage_rx_task;
}
/*绑定modbus_id和对应的索引在app_com中完成*/
}
@@ -251,7 +251,8 @@ static void proto_leakage_rx_task(u8 *p_data,u16 len,void *other_data)
{
/*计算当前设备索引*/
u8 sensor_index = p_sensor->comm.leakage_data_index;
- u16 ch_addr_offset[4] = {0,4,8,11}; /*漏液待数据地址偏移*/
+// u16 ch_addr_offset[4] = {0,4,8,11}; /*漏液待数据地址偏移*/
+ u16 ch_addr_offset[4] = {0,8,16,22}; /*漏液待数据地址偏移*/
u16 temp;
if(sensor_index >= APP_LEAKAGE_SUB_DEVICE_NUM)
diff --git a/leakage_system/usr/protocol/proto_modbus_tcp_slave_ex.c b/leakage_system/usr/protocol/proto_modbus_tcp_slave_ex.c
index a52e715..73356a5 100644
--- a/leakage_system/usr/protocol/proto_modbus_tcp_slave_ex.c
+++ b/leakage_system/usr/protocol/proto_modbus_tcp_slave_ex.c
@@ -265,7 +265,16 @@ static u16 proto_modbus_data_read(u16 addr)
{
case 0:/*端口&ID*/
{
- data = (leakage.sub_device_data[sensor_index].flash_data.com + 1)<< 8 | leakage.sub_device_data[sensor_index].flash_data.modbus_id;
+// data = (leakage.sub_device_data[sensor_index].flash_data.com + 1)<< 8 | leakage.sub_device_data[sensor_index].flash_data.modbus_id;
+ u16 value = (leakage.sub_device_data[sensor_index].flash_data.com + 1) << 8;
+ value |= leakage.sub_device_data[sensor_index].flash_data.modbus_id;
+ if (leakage.sub_device_data[sensor_index].flash_data.shield == BLOCKED) {
+ value |= 0x8000; /*最高位表示屏蔽*/
+ }
+ if (leakage.sub_device_data[sensor_index].flash_data.state == ENABLE) {
+ value |= 0x4000; /*次高位表示使能*/
+ }
+ data = value;
}break;
case 1 ... 5:/*区域名*/
{