Files
Leakage-Control/leakage_system/usr/gui/gui_tjc_hmi.c
2026-02-24 09:58:06 +08:00

1805 lines
65 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "GUI_tjc_hmi.h"
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include "proto_modbus_lib.h"
#include "bsp_w25q.h" // 添加Flash操作
#include "bsp_W5500.h"
#include "bsp_uart.h"
#include "bsp_DS1302.h"
#include "app_leakage.h"
/*串口发送缓冲区*/
#define HMI_TX_BUFFER_NUM (2048)
/*字符发送拼接 缓冲区*/
#define GUI_TJC_HMI_TEXT_BUFFER_NUM (256)
/*帧头*/
#define HMI_PROTO_FRAME_HEADER1 (0xAA)
#define HMI_PROTO_FRAME_HEADER2 (0x55)
/*操作*/
#define HMI_PROTO_CMD_GET (0x03) /*获取数据数据*/
#define HMI_PROTO_CMD_SET (0x10) /*设置信息*/
/*界面*/
#define HMI_PROTO_GUI_MAIN (0x10)/*主界面 */
#define HMI_PROTO_GUI_CURR_ALARM (0x11)/*实时报警界面 */
#define HMI_PROTO_GUI_DETAIL_MAIN (0x12)/*主界面_详细信息 */
#define HMI_PROTO_GUI_LOGIN (0x13)/*登录界面 */
#define HMI_PROTO_GUI_HISTORY_ALARM (0x14)/*历史报警界面 */
#define HMI_PROTO_GUI_TCP_CONFIG (0x15)/*网络配置界面 */
#define HMI_PROTO_GUI_DEVICE_CONFIG (0x16)/*设备配置界面 */
#define HMI_PROTO_GUI_HELP (0x17)/*帮助界面 */
#define HMI_PROTO_GUI_TIME (0x18)/*时间设置界面*/
#define HMI_PROTO_ASCII_RX_DELINITER (0xAA)/*接收分隔符*/
#define HMI_PROTO_ASCII_TX_DELINITER (0xFF)/*发送分隔符*/
#define HMI_PROTO_ASCII_TX_DELINITER_NUM (3)/*发送分隔符数量*/
#define W25Q32_PASSWORD_ADDR (W25Q32_USER_DATA_ADDR)/*密码存储地址*/
static void gui_tjc_hmi_init(void);
static void gui_tjc_hmi_communication_data_analysis(u8 *p_data, u16 len, void *rx_uart);
static void gui_tjc_hmi_read_device_info_from_w25q(void);
/*串口发送缓冲区*/
static u8 hmi_tx_buffer[HMI_TX_BUFFER_NUM];
/*字符发送拼接 缓冲区*/
static char gui_tjc_hmi_text_buffer[GUI_TJC_HMI_TEXT_BUFFER_NUM];
/*字符名称 端口号*/
static char *hmi_proto_string_com[] =
{
"COM1",
"COM2",
"COM3",
"COM4"
};
/*字符名称 波特率*/
static char *hmi_proto_string_baudrate[] =
{
"4800",
"9600",
"19200",
"57600",
"115200",
};
static bsp_uart_t * p_rx_uart = NULL;
gui_tjc_hmi_t tjc_hmi =
{
.init = gui_tjc_hmi_init,
};
gui_tjc_hmi_t *p_tjc_hmi = &tjc_hmi;
/*屏幕协议初始化*/
static void gui_tjc_hmi_init(void)
{
com_uart1.rx_data_analysis = gui_tjc_hmi_communication_data_analysis;
gui_tjc_hmi_read_device_info_from_w25q();
history.init_history();
}
/*发送接口*/
static void gui_tjc_hmi_data_send(u8 *p_data,u16 len)
{
if(p_rx_uart != NULL)
{
p_rx_uart->send(p_rx_uart,p_data,len);
}
}
static void gui_tjc_hmi_read_password_from_w25q(void)
{
/*直接读取4字节密码*/
w25q32.read(W25Q32_PASSWORD_ADDR, p_tjc_hmi->password, 4);
/*检查数据有效性如果全部为0xFF说明是首次使用清空密码*/
if(p_tjc_hmi->password[0] == 0xFF &&
p_tjc_hmi->password[1] == 0xFF &&
p_tjc_hmi->password[2] == 0xFF &&
p_tjc_hmi->password[3] == 0xFF)
{
memset(p_tjc_hmi->password, 0, 4);
}
}
/*将密码保存到W25Q32*/
static void gui_tjc_hmi_save_password_to_w25q(void)
{
/*将4字节密码写入W25Q32*/
w25q32.write(W25Q32_PASSWORD_ADDR, p_tjc_hmi->password, 4);
}
/* 从W25Q32读取设备信息到app_leakage */
static void gui_tjc_hmi_read_device_info_from_w25q(void)
{
/* 创建一个临时缓冲区 */
app_leakage_sub_device_flash_data_t temp_buffer[APP_LEAKAGE_SUB_DEVICE_NUM];
/* 一次性读取所有设备信息 */
w25q32.read(W25Q32_DEVICE_INFO_ADDR,
(uint8_t*)temp_buffer,
DEVICE_INFO_STORAGE_SIZE);
/* 检查数据有效性 */
uint8_t data_valid = 1;
for(int i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
{
/* 如果所有字段都是0xFF说明是空数据 */
if(temp_buffer[i].state == 0xFF &&
temp_buffer[i].com == 0xFF &&
temp_buffer[i].modbus_id == 0xFF)
{
data_valid = 0;
break;
}
}
if(data_valid)
{
/* 复制到app_leakage结构体中 */
for(int i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
{
leakage.sub_device_data[i].flash_data = temp_buffer[i];
}
}
else
{
/* Flash为空初始化设备信息为默认值 */
for(int i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
{
memset(&leakage.sub_device_data[i].flash_data, 0,
sizeof(app_leakage_sub_device_flash_data_t));
leakage.sub_device_data[i].flash_data.state = DISABLE;
}
}
/* 重新分类区域 */
app_leakage_region_classify();
}
/* 将设备信息从app_leakage保存到W25Q32 */
static void gui_tjc_hmi_save_device_info_to_w25q(void)
{
/* 创建一个临时缓冲区 */
app_leakage_sub_device_flash_data_t temp_buffer[APP_LEAKAGE_SUB_DEVICE_NUM];
/* 从app_leakage结构体复制到临时缓冲区 */
for(int i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
{
temp_buffer[i] = leakage.sub_device_data[i].flash_data;
}
/* 添加Flash擦除操作 - 必须擦除后才能写入 */
uint32_t erase_addr = W25Q32_DEVICE_INFO_ADDR;
/* 确保地址是4K对齐W25Q32_SECTOR_SIZE = 4096 */
erase_addr &= ~(W25Q32_SECTOR_SIZE - 1);
/* 擦除整个扇区 */
w25q32_sector_erase(erase_addr);
/* 一次性写入所有设备信息 */
w25q32.write(W25Q32_DEVICE_INFO_ADDR,
(uint8_t*)temp_buffer,
DEVICE_INFO_STORAGE_SIZE);
}
/*设置对应的控件
x第几行
y第几个
buffer写入的buffer
format格式化输入
...:不定长
*/
static u16 gui_tjc_hmi_tx_text_display(u16 x,u16 y,char *buffer,const char *format,...)
{
u16 i,len;
s16 state;
va_list arg;
/*清空缓冲区*/
memset(gui_tjc_hmi_text_buffer,0,sizeof(gui_tjc_hmi_text_buffer));
va_start(arg,format);
/*格式化转成字符串*/
state = vsnprintf(gui_tjc_hmi_text_buffer,GUI_TJC_HMI_TEXT_BUFFER_NUM,format,arg);
if(-1 == state || state > GUI_TJC_HMI_TEXT_BUFFER_NUM)
{
va_end(arg);
printf("Length REEOR");
return 0;
}
/*拼接字符串*/
sprintf(buffer,"t%d_%d.txt=\"%s\"",x,y,gui_tjc_hmi_text_buffer);
len = strlen(buffer);
for(i=0;i<HMI_PROTO_ASCII_TX_DELINITER_NUM;i++)
{
buffer[len + i] = HMI_PROTO_ASCII_TX_DELINITER;
}
va_end(arg);
return len + 3;
}
/*主界面响应*/
static void gui_tjc_hmi_main_send(u8 cmd,u8 opa,u8 *p_data)
{
/*每页显示的区域数量*/
#define MAIN_PAGE_SUB_DEVICE_NUM (4)
u16 len = 0,i,j,x,y,index;
u8 page_num,remain_region_num;
memset(hmi_tx_buffer,0,sizeof(hmi_tx_buffer));
/*计算页面数量*/
page_num = leakage.region_num / MAIN_PAGE_SUB_DEVICE_NUM;
remain_region_num = leakage.region_num % MAIN_PAGE_SUB_DEVICE_NUM;/*剩余区域数量*/
if(remain_region_num > 0)
{
page_num++;
}
char time[20];
sprintf(time,"20%d-%02d-%02d %02d:%02d",
DS1302.Time.Year,
DS1302.Time.Month,
DS1302.Time.Day,
DS1302.Time.Hour,
DS1302.Time.Minute);
len += gui_tjc_hmi_tx_text_display(0,0,(char *)&hmi_tx_buffer[len],"%s",time);
if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
{
switch(opa)
{
case 0x01:/*读取区域信息*/
{
if(p_tjc_hmi->page.main_index == page_num - 1 && remain_region_num >0)/*显示剩余区域*/
{
for(j=0;j<remain_region_num;j++)
{
index = p_tjc_hmi->page.main_index * MAIN_PAGE_SUB_DEVICE_NUM + j;
x = j;
/*名称*/
y = 0;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%s",leakage.region_data[index].name);
/*区域内设备总数量*/
y = 1;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].sub_device_num);
/*漏液数量*/
y = 2;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].leakage_num);
/*断带*/
y = 3;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].open_num);
/*通讯*/
y = 4;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].time_out_num);
}
}
else
{
for(j=0;j<MAIN_PAGE_SUB_DEVICE_NUM;j++)
{
index = p_tjc_hmi->page.main_index*MAIN_PAGE_SUB_DEVICE_NUM + j;
x = j;
/*名称*/
y = 0;
len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%s",leakage.region_data[index].name);
/*区域内设备总数量*/
y = 1;
len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].sub_device_num);
/*漏液数量*/
y = 2;
len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].leakage_num);
/*断带*/
y = 3;
len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].open_num);
/*通讯*/
y = 4;
len = gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.region_data[index].time_out_num);
}
}
}break;
case 0x03:/*翻页*/
{
if(0x01 == p_data[5])
{
if(page_num - 1 <= p_tjc_hmi->page.main_index)
{
p_tjc_hmi->page.main_index = 0;
}
else
{
p_tjc_hmi->page.main_index++;
}
}
else
{
if(0 == p_tjc_hmi->page.main_index)
{
p_tjc_hmi->page.main_index = page_num - 1;
}
else
{
p_tjc_hmi->page.main_index--;
}
}
}
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
{
switch(opa)
{
case 0x01:/*蜂鸣器开关*/
{
if(0x01 == p_data[0])
{
/*01打开蜂鸣器*/
}
else
{
/*00关闭蜂鸣器*/
}
}
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
}
/*实时报警响应*/
static void gui_tjc_hmi_curr_alarm_send(u8 cmd,u8 opa,u8 *p_data)
{
/*每页显示的报警设备数量*/
#define REAL_ALARM_PAGE_NUM (4)
u16 len = 0,i,j,x,y,device_index,ch,index;
u8 page_num,remain_alrm_device_num,display_count;
u8 alarm_device_count;
u8 alarm_device_index[APP_LEAKAGE_SUB_DEVICE_NUM];
memset(hmi_tx_buffer,0,sizeof(hmi_tx_buffer));
/*计算报警设备数量*/
alarm_device_count = 0;
for(i = 0;i<APP_LEAKAGE_SUB_DEVICE_NUM;i++)
{
if(ENABLE != leakage.sub_device_data[i].flash_data.state)
{
continue ;
}
for(ch=0;ch<APP_LEAKAGE_SUB_DEVICE_CH_NUM;ch++)
{
u16 ch_state = leakage.sub_device_data[i].ch_data[ch].state;
if(ch_state & (APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT | APP_LEAKAGE_SUB_DEVICE_STATE_OPEN | APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE))
{
alarm_device_index[alarm_device_count] = i;
alarm_device_count++;
break;
}
}
}
if(alarm_device_count == 0)
{
return;
}
/*计算页面数量*/
page_num = alarm_device_count / REAL_ALARM_PAGE_NUM;
remain_alrm_device_num = alarm_device_count % REAL_ALARM_PAGE_NUM;
if(remain_alrm_device_num > 0)
{
page_num++;
}
if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
{
switch(opa)
{
case 0x01:/*获取实时报警信息*/
{
if(p_tjc_hmi->page.real_alarm_index == page_num - 1 && remain_alrm_device_num > 0)
{
for(j=0;j<remain_alrm_device_num;j++)
{
index = p_tjc_hmi->page.real_alarm_index * REAL_ALARM_PAGE_NUM + j;
device_index = alarm_device_index[index];
x = j;
/*区域名称*/
y = 0;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%s",leakage.sub_device_data[index].flash_data.region_name);
/*设备ID*/
y = 1;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.sub_device_data[index].flash_data.modbus_id);
/*设备名称*/
y = 2;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%s",leakage.sub_device_data[index].flash_data.device_name);
/*通讯状态*/
y =3;
u16 comm_state = 0;
for(ch=0;ch<APP_LEAKAGE_SUB_DEVICE_CH_NUM;ch++)
{
if(leakage.sub_device_data[device_index].ch_data[ch].state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
{
comm_state = APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT;
break;
}
}
if(comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
{
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(ch=0;ch<APP_LEAKAGE_SUB_DEVICE_CH_NUM;ch++)
{
u16 ch_state = leakage.sub_device_data[device_index].ch_data[ch].state;
u16 ch_distance = leakage.sub_device_data[device_index].ch_data[ch].distance;
y = 4 + (ch * 3);
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],"正常");
}
y =5 + (ch * 3);
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],"正常");
}
y = 6 + (ch * 3);
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
{
for(j=0;j<REAL_ALARM_PAGE_NUM;j++)
{
index = p_tjc_hmi->page.real_alarm_index * REAL_ALARM_PAGE_NUM + j;
device_index = alarm_device_index[index];
x = j;
/*区域名称*/
y = 0;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%s",leakage.sub_device_data[device_index].flash_data.region_name);
/*设备ID*/
y = 1;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%d",leakage.sub_device_data[index].flash_data.modbus_id);
/*设备名称*/
y = 2;
len += gui_tjc_hmi_tx_text_display(x+1,y+1,(char *)&hmi_tx_buffer[len],"%s",leakage.sub_device_data[index].flash_data.device_name);
/*通讯状态*/
y =3;
u16 comm_state = 0;
for(ch=0;ch<APP_LEAKAGE_SUB_DEVICE_CH_NUM;ch++)
{
if(leakage.sub_device_data[device_index].ch_data[ch].state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
{
comm_state = APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT;
break;
}
}
if(comm_state & APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
{
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(ch=0;ch<APP_LEAKAGE_SUB_DEVICE_CH_NUM;ch++)
{
u16 ch_state = leakage.sub_device_data[device_index].ch_data[ch].state;
u16 ch_distance = leakage.sub_device_data[device_index].ch_data[ch].distance;
y = 4 + (ch * 3);
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],"正常");
}
y =5 + (ch * 3);
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],"正常");
}
y = 6 + (ch * 3);
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");
}
}
}
}
}break;
case 0x03:/*翻页*/
{
if(0x01 == p_data[0])
{
if(page_num - 1 <= p_tjc_hmi->page.real_alarm_index)
{
p_tjc_hmi->page.real_alarm_index = 0;
}
else
{
p_tjc_hmi->page.real_alarm_index++;
}
}
else
{
if(0 == p_tjc_hmi->page.real_alarm_index)
{
p_tjc_hmi->page.real_alarm_index = page_num - 1;
}
else
{
p_tjc_hmi->page.real_alarm_index--;
}
}
}
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
{
switch(opa)
{
case 0x01:
{
}break;
case 0x02:
{
}break;
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
}
/*主界面详情*/
static void gui_tjc_hmi_detail_main_send(u8 cmd, u8 opa, u8 *p_data)
{
#define DETAIL_MAIN_NUM (4) /* 每页显示4个设备 */
u16 len = 0, i, sub_device_index, ch, x, y, index;
u8 page_num, remain_device_num, display_count;
u8 region_idx; /* 区域索引 */
app_leakage_region_data_class_t *region_data;
memset(hmi_tx_buffer, 0, sizeof(hmi_tx_buffer));
/* 计算详情页面数量每页显示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) /* 获取数据 */
{
switch (opa)
{
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.deliniter_main_index = region_idx;
/* 获取区域数据 */
region_data = &leakage.region_data[region_idx];
/* 获取当前详情页面的设备数据 */
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;
}
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个设备位置 */
/* 设备ID: t(x+1)_1 */
y = 0;
len += gui_tjc_hmi_tx_text_display(x+1, y+1,
(char *)&hmi_tx_buffer[len],
"%d",
leakage.sub_device_data[sub_device_index].flash_data.modbus_id);
/* 设备名称: t(x+1)_2 */
y = 1;
len += gui_tjc_hmi_tx_text_display(x+1, y+1,
(char *)&hmi_tx_buffer[len],
"%s",
leakage.sub_device_data[sub_device_index].flash_data.device_name);
/* 通讯状态: t(x+1)_3 */
y = 2;
u8 comm_state = 0;
for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
{
if (leakage.sub_device_data[sub_device_index].ch_data[ch].state &
APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
{
comm_state = 1;
break;
}
}
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],
"正常");
}
/* 通道1-4状态 */
for (ch = 0; ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM; ch++)
{
u16 ch_state = leakage.sub_device_data[sub_device_index].ch_data[ch].state;
u16 ch_distance = leakage.sub_device_data[sub_device_index].ch_data[ch].distance;
/* 漏液状态 */
y = 3 + (ch * 3);
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],
"正常");
}
/* 断带状态 */
y = 4 + (ch * 3);
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],
"正常");
}
/* 漏液位置 */
y = 5 + (ch * 3);
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");
}
}
}
}
break;
case 0x03: /* 翻页 */
{
/* 使用之前保存的全局区域索引 */
region_idx = p_tjc_hmi->page.deliniter_main_index;
/* 检查区域索引是否有效 */
if (region_idx >= leakage.region_num)
{
return; /* 区域索引越界 */
}
/* 获取区域数据 */
region_data = &leakage.region_data[region_idx];
if(0x01 == p_data[0]) /* 下一页 */
{
if(page_num - 1 <= p_tjc_hmi->page.detail_main_index)
{
p_tjc_hmi->page.detail_main_index = 0;
}
else
{
p_tjc_hmi->page.detail_main_index++;
}
}
else /* 上一页 */
{
if(0 == p_tjc_hmi->page.detail_main_index)
{
p_tjc_hmi->page.detail_main_index = page_num - 1;
}
else
{
p_tjc_hmi->page.detail_main_index--;
}
}
return;
}
break;
default:
return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
else if (HMI_PROTO_CMD_SET == cmd) /* 设置命令 */
{
switch (opa)
{
case 0x01: /* */
{
}
break;
default:
return;
}
}
}
/*登录界面*/
static void gui_tjc_hmi_login_send(u8 cmd,u8 opa,u8 *p_data)
{
u16 len = 0,i;
if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
{
switch(opa)
{
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;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
{
switch(opa)
{
case 0x01:/*将密码存入flash中*/
{
for(i=0; i<4; i++)
{
p_tjc_hmi->password[i] = p_data[i];
}
/*保存到W25Q32*/
gui_tjc_hmi_save_password_to_w25q();
}break;
case 0x02:/*无*/
{
}break;
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
}
/*历史报警界面*/
static void gui_tjc_hmi_history_alarm_send(u8 cmd,u8 opa,u8 *p_data)
{
#define HISTORY_ALARM_PER_PAGE (15) /* 每页15条历史报警数据 */
u16 len = 0, i, j;
u8 page_num, remain_records, display_count;
u32 total_records, start_index, record_index;
app_leakage_history_alarm_t history_record;
char time_str[20];
char alarm_type_str[20];
/* 获取总记录数 */
total_records = leakage.history_metadata.total_records;
if(total_records == 0)
{
return;
}
/* 计算页面数量 */
page_num = total_records / HISTORY_ALARM_PER_PAGE;
remain_records = total_records % HISTORY_ALARM_PER_PAGE;
if(remain_records > 0)
{
page_num++;
}
if(HMI_PROTO_CMD_GET == cmd) /* 获取数据 */
{
switch(opa)
{
case 0x01: /* 读取历史报警信息 */
{
/* 获取当前页码对应的记录 */
u8 current_page = p_tjc_hmi->page.history_alarm_index;
/* 计算起始记录索引(按时间倒序显示,最新的在前面) */
start_index = current_page * HISTORY_ALARM_PER_PAGE;
/* 计算本页显示记录数 */
if(current_page == page_num - 1 && remain_records > 0)
{
display_count = remain_records;
}
else
{
display_count = HISTORY_ALARM_PER_PAGE;
}
/* 显示历史报警记录 */
for(i = 0; i < display_count; i++)
{
/* 计算记录索引(从最新的开始) */
if(total_records > start_index + i)
{
record_index = total_records - 1 - (start_index + i);
}
else
{
break;
}
/* 读取历史报警记录 */
if(history.read_history(record_index, &history_record))
{
/* 区域名: t(i+1)_1 */
len += gui_tjc_hmi_tx_text_display(i+1, 1,
(char *)&hmi_tx_buffer[len],
"%s",
history_record.region_name);
/* 设备ID: t(i+1)_2 */
len += gui_tjc_hmi_tx_text_display(i+1, 2,
(char *)&hmi_tx_buffer[len],
"%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)_4 */
alarm_type_str[0] = '\0';
if(history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
strcat(alarm_type_str, "漏液");
else if(history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_OPEN)
strcat(alarm_type_str, "断带");
else if(history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_TIME_OUT)
strcat(alarm_type_str, "通讯超时");
len += gui_tjc_hmi_tx_text_display(i+1, 4,
(char *)&hmi_tx_buffer[len],
"%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]);
len += gui_tjc_hmi_tx_text_display(i+1, 5,
(char *)&hmi_tx_buffer[len],
"%s",
time_str);
/* 漏液距离: t(i+1)_6 (如果是漏液报警才显示) */
if(history_record.alarm_type == APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE)
{
len += gui_tjc_hmi_tx_text_display(i+1, 6,
(char *)&hmi_tx_buffer[len],
"%d",
history_record.leak_distance);
}
else
{
len += gui_tjc_hmi_tx_text_display(i+1, 6,
(char *)&hmi_tx_buffer[len],
"0");
}
}
else
{
/* 读取失败,显示空 */
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 += 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], "");
}
}
/* 如果本页不足15条记录清空剩余行 */
for(; 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], "");
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 = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer, len);
}
break;
case 0x03: /* 翻页 */
{
if(0x01 == p_data[0]) /* 下一页 */
{
if(p_tjc_hmi->page.history_alarm_index >= page_num - 1)
{
p_tjc_hmi->page.history_alarm_index = 0;
}
else
{
p_tjc_hmi->page.history_alarm_index++;
}
}
else /* 上一页 */
{
if(p_tjc_hmi->page.history_alarm_index == 0)
{
p_tjc_hmi->page.history_alarm_index = page_num - 1;
}
else
{
p_tjc_hmi->page.history_alarm_index--;
}
}
}
break;
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
{
switch(opa)
{
case 0x01:/*清空*/
{
history.clean_history();
}break;
case 0x02:/*无*/
{
}break;
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
}
/*网络配置界面*/
static void gui_tjc_hmi_tcp_config_send(u8 cmd,u8 opa,u8 *p_data)
{
u16 len = 0,i;
memset(hmi_tx_buffer,0,sizeof(hmi_tx_buffer));
if(HMI_PROTO_CMD_GET == cmd)/*获取数据*/
{
switch(opa)
{
case 0x01:/*读取网络配置信息p_data[0]=0x01为读取设置的网络配置00为读取默认的,网络IP,子网掩码,网关,DNS服务器*/
{
if(p_data[0] == 0x01)
{
len += gui_tjc_hmi_tx_text_display(1,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]);
len += gui_tjc_hmi_tx_text_display(1,2,(char *)&hmi_tx_buffer[len],
"%d.%d.%d.%d",
W5500.Sub_Mask[0],
W5500.Sub_Mask[1],
W5500.Sub_Mask[2],
W5500.Sub_Mask[3]);
len += gui_tjc_hmi_tx_text_display(1,3,(char *)&hmi_tx_buffer[len],
"%d.%d.%d.%d",
W5500.Gateway_IP[0],
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");
}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");
}
}break;
case 0x02:/*无*/
{
}break;
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
{
switch(opa)
{
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;
}
}
/*解析子网掩码*/
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)
{
memcpy(W5500.Gateway_IP, current_pos, i);
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;
}
}
}break;
case 0x02:/*无*/
{
}break;
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
}
/*设备配置界面 */
static void gui_tjc_hmi_device_config_send(u8 cmd,u8 opa,u8 *p_data)
{
#define DEVICES_PER_PAGE (8)
u16 len = 0,i,j;
u8 found_empty_slot = 0,enabled_device_count,field_count,page_num,remain_region_num;
u8 empty_slot_index = 0;
u8 *current_pos = NULL;
app_leakage_sub_device_flash_data_t new_device;
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)
{
case 0x01:/*读取已存在的设备显示区域端口设备ID,设备名,*/
{
u8 page_device_indices[DEVICES_PER_PAGE] = {0}; /*存储当前页8个设备在app_leakage中的索引*/
u8 page_device_count = 0; /*当前页实际启用的设备数量*/
u8 current_enabled_index = 0; /*当前是第几个启用的设备*/
u8 device_index;
/*计算启用的设备数量*/
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++;
}
}
if(enabled_device_count == 0)
{
return;
}
/*获取当前页的设备索引*/
for(i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM && page_device_count < DEVICES_PER_PAGE; i++)
{
if(leakage.sub_device_data[i].flash_data.state == ENABLE)
{
current_enabled_index++;
/*判断这个设备是否在当前页*/
u8 device_page = (current_enabled_index - 1) / DEVICES_PER_PAGE;
if(device_page == p_tjc_hmi->page.device_config_index)
{
page_device_indices[page_device_count] = i;
page_device_count++;
}
}
}
if(page_device_count == 0)
{
/*当前页没有设备,发送空数据*/
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
return;
}
/*显示当前页的设备信息*/
for(i = 0; i < page_device_count; i++)
{
device_index = page_device_indices[i];
/*区域名: t(i+1)_1 */
len += gui_tjc_hmi_tx_text_display(i+1, 1,
(char *)&hmi_tx_buffer[len],
"%s",
leakage.sub_device_data[device_index].flash_data.region_name);
/*端口号: t(i+1)_2 */
u8 com_port = leakage.sub_device_data[device_index].flash_data.com;
if(com_port < 4) /*确保端口号在有效范围内*/
{
len += gui_tjc_hmi_tx_text_display(i+1, 2,
(char *)&hmi_tx_buffer[len],
"%s",
hmi_proto_string_com[com_port]);
}
else
{
len += gui_tjc_hmi_tx_text_display(i+1, 2,
(char *)&hmi_tx_buffer[len],
"未知");
}
/*设备ID: t(i+1)_3 */
len += gui_tjc_hmi_tx_text_display(i+1, 3,
(char *)&hmi_tx_buffer[len],
"%d",
leakage.sub_device_data[device_index].flash_data.modbus_id);
/*设备名称: t(i+1)_4 */
len += gui_tjc_hmi_tx_text_display(i+1, 4,
(char *)&hmi_tx_buffer[len],
"%s",
leakage.sub_device_data[device_index].flash_data.device_name);
}
/*如果当前页不足8个设备清空剩余的设备显示位置*/
if(page_device_count < DEVICES_PER_PAGE)
{
for(i = page_device_count; 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],
"");
/*清空设备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],
"");
}
}
}break;
case 0x03:/*翻页功能每页显示8个设备*/
{
if(0x01 == p_data[0]) /*下一页*/
{
if(page_num - 1 <= p_tjc_hmi->page.device_config_index)
{
p_tjc_hmi->page.device_config_index = 0;
}
else
{
p_tjc_hmi->page.device_config_index++;
}
}
else /*上一页*/
{
if(0 == p_tjc_hmi->page.device_config_index)
{
p_tjc_hmi->page.device_config_index = page_num - 1;
}
else
{
p_tjc_hmi->page.device_config_index--;
}
}
/*翻页后需要重新获取数据并显示,这里不直接发送数据*/
return;
}break;
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
else if(HMI_PROTO_CMD_SET == cmd)/*设置*/
{
switch(opa)
{
case 0x01:
{
found_empty_slot = 0;
for(i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM; i++)
{
if(leakage.sub_device_data[i].flash_data.state == DISABLE)
{
found_empty_slot = 1;
empty_slot_index = i;
break;
}
}
if(!found_empty_slot)
{
/*设备数量已满*/
return;
}
field_count = 0;
current_pos = p_data;
memset(&new_device, 0, sizeof(new_device));
/*解析端口号*/
for(i = 0; i < 10; i++)
{
if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
{
if(i == 0)
{
/*端口号不能为空*/
return;
}
char port_str[10] = {0};
memcpy(port_str, current_pos, i);
port_str[i] = '\0';
/*将字符串端口号转换为数值*/
if(strcmp(port_str, "COM1") == 0)
{
new_device.com = 0;
}
else if(strcmp(port_str, "COM2") == 0)
{
new_device.com = 1;
}
else if(strcmp(port_str, "COM3") == 0)
{
new_device.com = 2;
}
else if(strcmp(port_str, "COM4") == 0)
{
new_device.com = 3;
}
current_pos += (i + 1);
field_count++;
break;
}
}
/*解析区域名*/
for(i = 0; i < APP_LEAKAGE_STRING_NANE_LEN; i++)
{
if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
{
memcpy(new_device.region_name, current_pos, i);
new_device.region_name[i] = '\0';
current_pos += (i + 1);
field_count++;
break;
}
}
/*解析设备ID */
for(i = 0; i < 10; i++)
{
if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
{
if(i == 0)
{
/*设备ID不能为空*/
return;
}
/*设备ID是数字字符串转换为数值*/
char id_str[10] = {0};
memcpy(id_str, current_pos, i);
id_str[i] = '\0';
new_device.modbus_id = atoi(id_str);
current_pos += (i + 1);
field_count++;
break;
}
}
/*解析设备名称*/
for(i = 0; i < APP_LEAKAGE_STRING_NANE_LEN; i++)
{
if(current_pos[i] == HMI_PROTO_ASCII_RX_DELINITER)
{
memcpy(new_device.device_name, current_pos, i);
new_device.device_name[i] = '\0';
field_count++;
break;
}
}
/*相同id时覆盖之前的*/
if(field_count == 4)
{
for(u8 x = 0; x < APP_LEAKAGE_SUB_DEVICE_NUM; x++)
{
if (leakage.sub_device_data[x].flash_data.modbus_id == new_device.modbus_id)
{
new_device.state = ENABLE;
leakage.sub_device_data[x].flash_data = new_device;
gui_tjc_hmi_save_device_info_to_w25q();
app_leakage_region_classify();
field_count++;
}
}
}
/*添加到设备列表*/
if(field_count == 4)
{
/*设置默认状态为启用*/
new_device.state = ENABLE;
/*添加到app_leakage的设备列表中*/
leakage.sub_device_data[empty_slot_index].flash_data = new_device;
/*保存到W25Q32*/
gui_tjc_hmi_save_device_info_to_w25q();
/*重新分类区域*/
app_leakage_region_classify();
}
else
{
/*发送错误响应*/
return;
}
}break;
case 0x02:/*删除设备将设备信息从w25q中删除*/
{
u8 page_device_indices[8] = {0}; /*存储当前页8个设备在app_leakage中的索引*/
u8 page_device_count = 0; /*当前页实际启用的设备数量*/
u8 current_enabled_index = 0; /*当前是第几个启用的设备*/
for(i = 0; i < APP_LEAKAGE_SUB_DEVICE_NUM && page_device_count < DEVICES_PER_PAGE; i++)
{
if(leakage.sub_device_data[i].flash_data.state == ENABLE)
{
current_enabled_index++;
/*判断这个设备是否在当前页*/
u8 device_page = (current_enabled_index - 1) / DEVICES_PER_PAGE;
if(device_page == p_tjc_hmi->page.device_config_index)
{
page_device_indices[page_device_count] = i;
page_device_count++;
}
}
}
if(page_device_count == 0)
{
/*当前页没有设备*/
return;
}
/*遍历8个选中框字节删除被选中的设备*/
u8 deleted_count = 0; /*记录删除的设备数量*/
u8 shift_offset = 0; /*偏移量,用于处理删除后设备索引的变化*/
for(i = 0; i < 8; i++)
{
/*只处理当前页实际存在的设备*/
if(i >= page_device_count)
{
break;
}
/*检查设备是否被选中删除*/
if(p_data[i] == 0x01)
{
/*计算实际要删除的设备在app_leakage中的索引*/
u8 actual_index = page_device_indices[i] - shift_offset;
/*直接删除设备:将后面的设备向前移动*/
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,
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++;
/*重新计算当前页的设备索引,设备前移*/
for(u8 k = i + 1; k < page_device_count; k++)
{
page_device_indices[k]--;
}
}
}
if(deleted_count > 0)
{
/*保存到W25Q32*/
gui_tjc_hmi_save_device_info_to_w25q();
/*重新分类区域*/
app_leakage_region_classify();
/*发送确认响应*/
}
else
{
/*没有选中任何设备*/
return;
}
}break;
default:return;
}
len = strlen((char *)hmi_tx_buffer);
gui_tjc_hmi_data_send(hmi_tx_buffer,len);
}
}
/*设置时间界面*/
static void gui_tjc_hmi_time_set_send(u8 cmd,u8 opa,u8 *p_data)
{
u16 i, len = 0;
char temp_buf[5];
bsp_DS1302_Time_t new_time;
if(HMI_PROTO_CMD_SET == cmd) /* 设置命令 */
{
switch(opa)
{
case 0x01: /* 设置时间 */
{
/* 检查数据长度 */
if(p_data[4] != 0xAA || /* 年后的分隔符 */
p_data[7] != 0xAA || /* 月后的分隔符 */
p_data[10] != 0xAA || /* 日后的分隔符 */
p_data[13] != 0xAA) /* 时后的分隔符 */
{
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);
}
break;
default:
break;
}
}
}
/*屏幕指令解析*/
static void gui_tjc_hmi_communication_data_analysis(u8 *p_data, u16 len, void *rx_uart)
{
u8 cmd,data,gui_id,opa,*p_offset_data;
u16 i,modbus_crc16,check_crc16;
/*长度不足*/
if(len < 5)
{
return ;
}
/*检测帧头*/
if(p_data[0] != HMI_PROTO_FRAME_HEADER1 || p_data[1] != HMI_PROTO_FRAME_HEADER2)
{
return ;
}
/*校验位*/
check_crc16 = p_data[len-2] << 8 | p_data[len-1];
modbus_crc16 = modbus_lib_crc16(p_data,len-2);
modbus_crc16 = (modbus_crc16 >> 8) | (modbus_crc16 << 8);
if(modbus_crc16 != check_crc16)
{
return ;
}
/*CMD*/
cmd = p_data[2];
if(cmd != HMI_PROTO_CMD_GET && cmd != HMI_PROTO_CMD_SET)
{
return ;
}
gui_id = p_data[3]; /*gui_id*/
opa = p_data[4]; /*操作码*/
p_offset_data = &p_data[5]; /*附带数据*/
p_rx_uart = (bsp_uart_t *)rx_uart; /*串口指针*/
switch(gui_id)
{
case HMI_PROTO_GUI_MAIN :
{
gui_tjc_hmi_main_send(cmd,opa,p_offset_data);
}break;
case HMI_PROTO_GUI_CURR_ALARM :
{
gui_tjc_hmi_curr_alarm_send(cmd,opa,p_offset_data);
}break;
case HMI_PROTO_GUI_DETAIL_MAIN :
{
gui_tjc_hmi_detail_main_send(cmd,opa,p_offset_data);
}break;
case HMI_PROTO_GUI_LOGIN :
{
gui_tjc_hmi_login_send(cmd,opa,p_offset_data);
}break;
case HMI_PROTO_GUI_HISTORY_ALARM :
{
gui_tjc_hmi_history_alarm_send(cmd,opa,p_offset_data);
}break;
case HMI_PROTO_GUI_TCP_CONFIG :
{
gui_tjc_hmi_tcp_config_send(cmd,opa,p_offset_data);
}break;
case HMI_PROTO_GUI_DEVICE_CONFIG :
{
gui_tjc_hmi_device_config_send(cmd,opa,p_offset_data);
}break;
case HMI_PROTO_GUI_HELP :
{
//gui_tjc_hmi_help_send(cmd,opa,p_offset_data);
}break;
case HMI_PROTO_GUI_TIME :
{
gui_tjc_hmi_time_set_send(cmd,opa,p_offset_data);
}
}
}