EMS 知识库
首页 / knowledge/代码解析/hmi

lcd.h

源文件路径:hmi/lcd.h 所属模块:hmi(人机界面) 代码行数:434

1. 文件职责

本文件是 EMS 字符型 LCD 人机界面的类型与全局状态声明头,不包含任何函数实现。它声明了两件核心内容:界面窗口 ID 枚举 ui_page(77 个 ID)、语言枚举 LANGUAGE_E,以及 HMI 全局运行时数据库结构 struct LCD_Display 和它的唯一实例 extern struct LCD_Display LCD_RTDB;(hmi/lcd.h:427)。

它在数据流中处于"定义共享内存契约"的位置:所有 ui_*.c 界面、hmi/key.c 按键逻辑、hmi/lcd.c 调度器、data/system_config/system_config.c 配置落盘、net/server.c 与 midware/interface/modbus/modbus.c 的远程参数入口都通过这个头文件读写同一块 LCD_RTDB。

被驱动方式:包含本头文件的文件全部由 uCOS-II 的 HMI 任务 task_hmi_parse(优先级 21,10 ms 节拍)在 hmi/key.c 中间接触发,配置类字段则在系统配置任务与网络任务中被动改写。此外公共宏 Lag(UCOSII/uCOS-CONFIG/includes.h:27)直接依赖本头文件声明的 LCD_RTDB 与 English。

2. 关键数据结构与宏

名称类型说明
__LCD_H__宏(包含卫士)头文件防重复包含(hmi/lcd.h:10-11)
ui_page枚举77 个 LCD 界面/窗口 ID,从 mWindowMain = 0 顺序编号(hmi/lcd.h:20-111);LCD_RTDB.ui.bCurrWindow 的取值域,被 hmi/lcd.c 的 switch 与 hmi/key.c 的 193 处赋值使用
LANGUAGE_E枚举English = 0, German, Language_Max(hmi/lcd.h:114-119);Language_Max 同时充当语言文本表 disp_buf[Language_Max][N] 的维度,各 ui_*.c 用它做越界保护
struct POWER_Factor结构体功率因数(PF)设定:PF_mode、PF_Value、Q_Value、上/下限与功率上/下限标志(hmi/lcd.h:122-131)
struct LCD_Window结构体窗口游标:bCurrWindow、bLastWindow、bCurrCursor(行光标)、bCurrSubCursor(列/子光标),全为 u8(hmi/lcd.h:134-140)
struct LCD_Display结构体HMI 显示运行数据库主结构,约 250 个字段(hmi/lcd.h:143-424),唯一实例见 LCD_RTDB
RTC_DateTime结构体(外部)LCD_RTDB.LCD_DATETIME 的类型,定义于 hardware/pcf8563/pcf8563.h:236,字段 bSeconds/bMinutes/bHours/bDays/bMonths/bYears
BACKUP_BOX_CONFIG_T结构体(外部)LCD_RTDB.backupbox 的类型,定义于 midware/meter/backupbox.h:31,ui_setting_backupbox.c 通过它显示/写入备电箱配置
LCD_RTDB全局变量(extern)extern struct LCD_Display LCD_RTDB;(hmi/lcd.h:427),实体定义在 hmi/lcd.c:23,是 HMI 模块唯一的全局共享状态
Lag宏(外部,includes.h:27)#define Lag (LCD_RTDB.u8_language == English)?,界面双语文本选择,间接依赖本头文件

struct LCD_Display 字段分组

行号分组主要字段说明
145窗口ui(struct LCD_Window)界面调度状态
147时间LCD_DATETIMERTC 时间缓存,ui_setting_user_sys_date.c 与 net 校时使用
149-154语言/密码/超时u8_language、bClearMainBody、bPassword[4]、wDispPassword、wPassword、wLcdJumpMainCntwLcdJumpMainCnt 是实现"无操作回主界面"的计数器(阈值判断在 ui_control_exception.c:98)
156-161PV 容量与功率限制PV_Capacity_Storage、PV_Capacity_Grid、current_limit、power_limit_enable、force_charge_user、force_charge_cut_soc_user用户侧 PV 容量/并网限流/强制充电设置
164-166备电箱SetBackupBox、backupbox、SetParametersErr备电箱配置与参数写入错误标志
169-174CT 计量u8_grid_meter_or_ct、grid_use_ct、grid_ct_rate、u8_pv_meter_or_ct、pv_use_ct、pv_ct_rate电网/PV 侧"电表或 CT"选择与变比
176调试门Admin_Debug为 1 时 Lcd_Handler() 跳过异常自恢复(hmi/lcd.c:38)
178-182网络IPmethod、bIpAddress[4]、bSubnetMask[4]、bDefaultGateway[4]、bMAC_Address[13]以太网设置页缓存,ui_setting_user_sys_ethernet.c 读写
184-190电池u8_bat_ready、u8_bat_close_mos、set_bat_close_mos、bBatteryBlink、wSetBattery1_ReadyFlag、Set_ForceCharge、Force_Charge_Local电池就绪/合离 MOS/闪烁标志
192-194故障日志bErrorLogDrawBuffer[10][17]、bErrorLogValue[10]、wErrorDescribe故障日志页 10 行×17 字符的绘制缓冲
196系统模式u8_system_modeAC / DC / Hybrid(类型为 u16,见风险点)
198-208电网充电时段bChargeFromGridFlag1/2、bChargerStartTime1/EndTime1、bChargerStartTime2/EndTime2 的时/分、Charger_Cut_SOC两段式"电网充电"时间窗
210-218放电时段bDischargerStartTime1/EndTime1、bDischargerStartTime2/EndTime2 的时/分、UPS_Reserve_SOC两段式放电时间窗与放电截止 SOC
220-223复位请求bFactoryReset、MachineReset、bResetMeter、bResetEnergy出厂复位/整机复位/电表清零/电量清零的请求标志
225-268电网保护阈值u16_grid_ovp1/uvp1/ofp1/ufp1 三档 _trip_value 与 _trip_adj_time、u16_grid_ovp_10mini_avg_*、u16_grid_ovp/uvp/ofp/ufp_Res_value、u16_start_connect_delay_time、u16_reconnect_delay_time、GFCI 30/60/150/300 mA 阈值安规参数集,由管理员安规页设置、由 ui_setting_admin_safety.c 展示
270-274使能位u8_over_freq_derating_rate_enable、u8_under_freq_derating_rate_enable、u8_gfci_detect_enable、u8_n_line_relays_detect_enable、u8_npe_short_enable安规使能开关
276安规等级bSafety安规标准选择(取值域 Safety_Max)
279-283并机/油机控制器u8_ac_parallel_state、u8_dc_parallel_state、u8_gc_controller_enable交/直流并机状态、发电机控制器使能
286-298油机u8_generator_enable、_gcats_enable、_mode、_output_mode、s32_generator_rated_power、u8_generator_rate_percent、soc_start/end、时间窗时/分、s32_generator_charge_power11 个油机相关字段,对应 6 个油机设置界面
300构网u8_grid_forming_enableGrid Forming 使能
302-305功率因数bPowerLimit、POWER_FACTOR、PfLockInPoint、PfLockOutPointPF 设定与锁入/锁出工作点
307-321过/欠频降载Grid_OF_Reduce_Power_StartPoint_Freq/StopPoint_Freq、Grid_UF_Reduce_ChargerPower_StartPoint_Freq、Grid_UF_Reduce_ChargePower_StopPoint_Freq、Grid_OF_Reduce_Power_Freq、_Rate、_DelayTime、wQuVrateUp、wQuVrateLow频率-功率降载曲线参数
323-327曲线标志位FlagGrid_OF_...、FlagFreqSetPoint、FlagFreqDroopRate、FlagQuVrateUp/Low、FlagFreDroopDelayTime标记上述曲线参数是否已被本帧绘制/置位
329-349PQ 曲线Tn_To_Wgra_up/down、Muilt_Mode、Reactive_Power_point、Pu_Gen_Power_Limit_Enable、Pu_Gen_Lower_Power、Pu_Cons_Power_Limit_Enable、Pu_Cons_Upper_Volt、Pu_V1~V4、Qu_Enable、Qu_Upper/Lower_SetPoint、Qu_V1~V4IEEE 1547 / 澳大利亚式 Volt-Watt、Volt-Var 曲线顶点,对应 5 个 PQ 界面
351保存标志bSettingSaveFlag设置项修改后是否需落盘的通用标志
353-423参数写入标志位(约 55 个)u8_set_grid_ovp1_trip_value_flag 系列、bSettingTn_To_Wgra_upFlag 系列、Setting_PowerFactor_Mode_FLag、Setting_PV_Capacity_*、Setting_Exit_Flag每个可编辑参数一个标志,界面/按键在用户确认后置位,配置任务据此回写 flash;全部由 ui_control_exception.c 的 Lcd_Reset_LCD_RTDB() 统一清零

3. 函数清单

本文件不定义任何函数,只做函数声明:

函数名作用域说明
Backlight_Reload全局声明(hmi/lcd.h:430)重载背光保持计时;实现却位于 hmi/key.c:8751(T_Turn_On_s = OSTimeGet();),不在本模块内
Lcd_Handler全局声明(hmi/lcd.h:431)LCD 界面调度入口,实现于 hmi/lcd.c:36

另导出 1 个全局变量:LCD_RTDB(hmi/lcd.h:427,extern)。

4. 核心逻辑解析

4.1 界面 ID 枚举与调度器的对应关系

ui_page 的编号是隐式递增的(mWindowMain = 0 起逐个 +1,未显式赋值),因此枚举顺序一旦插入新成员,其后所有 ID 的数值全部平移。这是本头文件最关键的约束:

枚举分组与源码注释一一对应(hmi/lcd.h:25-108):status(6 个)、history(7 个)、password、restart、settings(约 60 个)、information。注意 mWindowRestartSystem(hmi/lcd.h:47)被放在 password 之后、settings 之前,与 hmi/lcd.c 中把它和 mWindowMachineReset/mWindowFactoryReset 放在一起处理的位置不同。

4.2 语言维度

LANGUAGE_E 只定义 English / German 两种语言,Language_Max = 2。所有 ui_*.c 都以 const char* disp_buf[Language_Max][N] 建表并统一在函数开头做 if (Language >= Language_Max) { return; } 保护(例如 hmi/ui/ui_ct_rate.c:25、hmi/ui/ui_setting_user_sys_language.c:19)。

u8_language 的完整数据通路:

环节位置说明
上电同步hmi/key.c:8912:LCD_RTDB.u8_language = g_t_system_base_info.u8_language;从系统基础配置装载
默认值data/system_config/system_config.c:266、:107出厂默认 English
界面修改hmi/key.c:8567-8569:LCD_RTDB.u8_language = LCD_RTDB.ui.bCurrCursor; save_job_post(SYSTEM_BASE_PARA_PAGE);语言页两个选项,光标 0/1 直接当语言号,随后投递配置保存任务
落盘data/system_config/system_config.c:271、:2938把 LCD_RTDB.u8_language 写回 g_t_system_base_info.u8_language
远程写入net/server.c:4179-4183(有 < Language_Max 校验)、midware/interface/modbus/modbus.c:6915(无校验)云端 JSON EmsLanguage / Modbus 寄存器 REG_SYSTEM_LAGUAGE_E

4.3 状态机(窗口/光标模型)

struct LCD_Window 定义了四级光标模型,其迁移完全在 hmi/key.c 中实现,本头文件只提供存储:

4.4 参数写入标志位的"写—清"协议

hmi/lcd.h:353-423 的约 55 个 *_flag 字段构成一套手工维护的脏标志协议:

  1. 用户在某个设置界面确认修改 → hmi/key.c 同时写 LCD_RTDB.<参数> 与 LCD_RTDB.<参数>_flag = 1,并常伴随 LCD_RTDB.bSettingSaveFlag = 1 与 save_job_post(...);
  2. 配置任务(data/system_config/system_config.c 中 20 处引用 LCD_RTDB)读取这些标志,把值搬进 g_t_ems_info / g_t_system_base_info 等持久化结构;
  3. 复位/超时回主界面时由 Lcd_Reset_LCD_RTDB() 一次性全部清 0(hmi/ui/ui_control_exception.c:39 起的连续赋值区)。

该协议没有任何集中式的字段表或循环:每个字段的名字、类型、清零语句都要人工三处同步维护(头文件、key.c、ui_control_exception.c)。新增一个可编辑参数时漏掉第三处会导致标志残留。

4.5 定时/调度与 uCOS-II 的配合

本头文件本身不涉及调度,但它定义的状态由 task_hmi_parse(hmi/key.c:8888,user/main.c:310 创建,TASK_HMI_PRIO = 21u、TASK_HMI_STK_SIZE = 512u,见 UCOSII/uCOS-CONFIG/app_cfg.h:72、:99)驱动:KeyPro() → Key_Handle() → Last_ID_Legal_Handle() → Lcd_Handler() → OSTimeDlyHMSM(0,0,0,10)。

wLcdJumpMainCnt(hmi/lcd.h:154)是唯一带时间语义的字段:hmi/key.c:8768-8775 在无按键时自增、有按键时清零,hmi/ui/ui_control_exception.c:98 在 >= 900 时把界面拉回主界面并复位数据库。不使用信号量或邮箱,共享内存靠"同任务串行 + 下一帧纠正"维护。

5. 对外接口

本文件导出

导出项消费方
struct LCD_Display、struct LCD_Window、struct POWER_Factor、ui_page、LANGUAGE_E全部 hmi/ui/ui_*.c(77 个文件)、hmi/key.c、hmi/lcd.c、data/system_config/system_config.c、net/ems.c、net/server.c
LCD_RTDB(extern)同上,共 87 个文件引用,其中 hmi/key.c 3512 处、ui_setting_user_func_grid_voltage.c 117 处
Lcd_Handler() 声明hmi/key.c:8963
Backlight_Reload() 声明hmi/key.c:8783、:8790、:8797、:8804

本文件依赖的外部声明

类型/变量来源
RTC_DateTimehardware/pcf8563/pcf8563.h:236(本头文件 #include "pcf8563.h")
BACKUP_BOX_CONFIG_Tmidware/meter/backupbox.h:31(#include "backupbox.h")
Lcd_Init / Lcd_Clear_Screen / Lcd_Draw_* 等驱动原型hardware/lcd_driver/lcd_driver.h(#include "lcd_driver.h")
u8/u16/u32/s8/s16/s32 等基础类型UCOSII/uCOS-CONFIG/includes.h、chip.h

6. 依赖关系

7. 备注与风险点

  1. 枚举值无对应 case:mWindowSettingsUserFuncGridFreqLimitSustainedOp(hmi/lcd.h:60)在 hmi/lcd.c 的 76 个 case 中不存在,进入该窗口只会得到空白屏。同时它与紧随其后的 mWindowSettingsUserFuncGridFreqLimitSustainedOp_AS4777(:61)语义重叠,疑似 AS4777 版本升级后遗留的废弃成员,但因为没有 = 显式赋值,不能直接删除——删除会让其后的所有枚举值平移,而 ui_control_exception.c:17-18 是按 0 硬编码的(虽然恰好指向 mWindowMain 仍成立),配置区若有按数值存储的界面 ID 则会错乱。
  1. u8_language 无范围钳制的一个进口:midware/interface/modbus/modbus.c:6915 把 Modbus 寄存器值直接赋给 g_t_system_base_info.u8_language,而该函数的入参是 u16 value(modbus.c:69),即 u16→u8 截断;net/server.c:4179 则有正确的 < Language_Max 判断。若写入非 0/1 的值,字段会持久化,下次上电 hmi/key.c:8912 装载后所有 ui_*.c 都会在开头的 Language >= Language_Max 处直接 return,表现为整机 LCD 全空白(不越界,但功能不可用),只能靠 Modbus/云端改回或复位恢复。
  1. 类型与命名前缀不一致:
    • u16 u8_system_mode;(hmi/lcd.h:196)—— 名字是 u8_ 前缀却是 u16;
    • u32 s32_generator_rated_power;(:290)、u32 s32_generator_charge_power;(:298)—— s32_ 前缀却是无符号;
    • u8 wSetBattery1_ReadyFlag;(:188)—— w(word)前缀却是 u8;
    • u16 Muilt_Mode;(:331)、u16 Pu_Gen_Power_Limit_Enable;(:334)—— 前者是 "Multi_Mode" 的拼写错误,后者用 u16 承载布尔量。

这些不影响运行,但会让 sizeof/有符号性判断出错。

  1. 同一语义的两套表示:密码同时存在 u8 bPassword[4](逐位十进制,供界面输入)与 u16 wPassword / wDispPassword(供比较),两者在 hmi/key.c 中分别维护,存在不同步的可能;ui_control_exception.c:21-23 只清了 bPassword[4]。
  1. 魔法数字:bErrorLogDrawBuffer[10][17](10 行 × 17 字符)、bIpAddress[4]、bMAC_Address[13](12 字符 + 结束符)、wLcdJumpMainCnt 阈值 900(写在 ui_control_exception.c:98 而非本头文件)均为裸数字,没有与之对应的宏;改动 LCD 行宽或故障日志条数时需要全工程搜索。
  1. Backlight_Reload 声明归属错误:声明在 hmi/lcd.h:430,实现却在 hmi/key.c:8751(操作的是 key.c 内部的静态 T_Turn_On_s)。任何只想用 Lcd_Handler 的模块都会被顺带引入 key 模块的符号。
  1. 约 55 个 *_flag 字段靠人工三处同步:头文件声明、hmi/key.c 置位、ui_control_exception.c 清零。字段数量已接近 struct LCD_Display 的一半,且没有注释分组表,是本结构体最大的维护风险;新增参数若漏写清零语句,会使旧标志跨界面残留并触发重复落盘。
  1. 无 volatile / 无临界区:LCD_RTDB 被 HMI 任务(含 hmi/key.c、hmi/lcd.c、ui_*.c)、系统配置任务(data/system_config/system_config.c)、网络任务(net/ems.c、net/server.c)跨任务读写,但字段既非 volatile 也未在任何临界区内整体保护。当前多数访问是 u8/u16 单次读写,在 Cortex-M4 上不会撕裂,但"读标志—改参数—写标志"这类多步操作没有原子性保证。