1766 lines
64 KiB
C
1766 lines
64 KiB
C
#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 "bsp_buzzer.h"
|
||
|
||
#include "app_leakage.h"
|
||
#include "app_com.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 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_class_update(void)
|
||
{
|
||
leakage.class_update();
|
||
app_com.class_update();
|
||
}
|
||
|
||
|
||
|
||
/*屏幕协议初始化*/
|
||
static void gui_tjc_hmi_init(void)
|
||
{
|
||
com_uart1.rx_data_analysis = gui_tjc_hmi_communication_data_analysis;
|
||
}
|
||
|
||
|
||
/*发送接口*/
|
||
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);
|
||
}
|
||
|
||
/* 将设备信息从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:%02d",
|
||
DS1302.Time.Year,
|
||
DS1302.Time.Month,
|
||
DS1302.Time.Day,
|
||
DS1302.Time.Hour,
|
||
DS1302.Time.Minute,
|
||
DS1302.Time.Second);
|
||
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打开蜂鸣器*/
|
||
buzzer.set.enable();
|
||
}
|
||
else
|
||
{
|
||
/*00关闭蜂鸣器*/
|
||
buzzer.set.disable();
|
||
}
|
||
}
|
||
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();
|
||
gui_tjc_hmi_class_update();
|
||
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();
|
||
|
||
/*重新分类区域*/
|
||
gui_tjc_hmi_class_update();
|
||
|
||
}
|
||
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();
|
||
|
||
/*重新分类区域*/
|
||
gui_tjc_hmi_class_update();
|
||
|
||
/*发送确认响应*/
|
||
}
|
||
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);
|
||
}
|
||
}
|
||
}
|