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

key.h

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

1. 文件职责

key.h 是 HMI 按键/登录模块的对外契约头文件,只做三件事:定义身份与显示类型的枚举、定义登录有效期结构体 LOGIN_IN_T、以及用大量 *_MAX/*_MIN/*_DEFAULT 宏集中声明"界面上可编辑参数的取值范围"。

它处在配置写入链的最前端:hmi/key.c 的所有数值编辑都从本文件取上下限(例如 Button_Handle(..., GRID_VAC_VOLT_MAX, GRID_VAC_VOLT_MIN)),因此本文件实际上承担了"设置页参数合法性第一道闸门"的角色——改这里的宏就会改变现场可调范围。

同时它把三个密码常量(用户/管理员/安装商)定义在这里,hmi/key.c 的认证状态机与 data/system_config/system_config.c:106,1160 的出厂初值都引用它们,是密码策略的唯一常量源。

本文件不定义任何函数、不定义任何变量(只有两个 extern 声明),本身不含逻辑,由 hmi/key.c 单向包含。

2. 关键数据结构与宏

名称类型说明
DEBUG_HMI宏 = 0(hmi/key.h:15)HMI 任务运行计数调试开关;hmi/key.c:8981 用它决定是否累加 g_t_task_run_status.u32_task_hmi_cnt
PLUS / SUB宏 = 0 / 1(:17-18)传给 Button_Handle() 的加/减方向标志,取代裸 0/1
USER_PASSWORD宏 = 1234(:20)用户密码出厂值;运行期为 g_t_system_base_info.u16_user_password(system_config.c:106 用它初始化)
ADMIN_PASSWORD宏 = 1397570(:21)管理员 7 位密码;hmi/key.c 以 ADMIN_PASSWORD / 10000(139,输入为 0139)和 ADMIN_PASSWORD % 10000(7570)分两次校验
INSTALLER_PASSWORD宏 = 1111(:22)安装商密码;system_config.c:1160 用它把"被改成安装商密码的用户密码"复位为 USER_PASSWORD
POWER_FACTORY_MODE_OFF…POWER_FACTORY_MODE_PF_P_CURVE宏 = 0…6(:25-31)无功/功率因数响应模式:0 关闭、1 PF 过励、2 PF 欠励、3 Q 过励、4 Q 欠励、5 Q-U 曲线、6 PF-P 曲线;被 hmi/key.c:2806-:2839 的模式轮转与 hmi/ui/ui_control_exception.c:87 的复位逻辑引用
GRID_VAC_VOLT_MAX/MIN宏 = 3000 / 1400(:34-35)电网电压保护点范围(0.1 V,即 300.0 V / 140.0 V)
GRID_FAC_FREQ_MAX/MIN宏 = 5500 / 4500(:37-38)电网频率保护点范围(0.01 Hz,即 55.00 / 45.00 Hz)
GRID_TIME_VAC_MAX/MIN宏 = 65535 / 0(:40-41)电压保护动作时间范围(ms)
GRID_TIME_FAC_MAX/MIN宏 = 65535 / 0(:43-44)频率保护动作时间范围(ms)
GRID_TIME_PRO_TH_MAX/MIN宏 = 65535 / 0(:46-47)保护阈值类时间(并网等待、重连延时、GFCI 阈值)范围
GRID_OVER_FREQ_START_MAX/MIN宏 = 5050 / 5020(:49-50)AS4777 过频降载起始点范围
GRID_OVER_FREQ_STOP_MAX/MIN宏 = 5200 / 5100(:52-53)过频降载终止点范围
GRID_UNDER_FREQ_START_MAX/MIN宏 = 4990 / 4900(:55-56)欠频降载起始点范围
GRID_UNDER_FREQ_STOP_MAX/MIN宏 = 4900 / 4700(:58-59)欠频降载终止点范围
GRID_FREQ_DROOPRATE_MAX/MIN宏 = 12 / 2(:61-62)频率下垂率范围(全工程无引用,死宏)
GRID_OF_REDUCE_POWER_DELAY_TIME_MAX/MIN宏 = 1000 / 0(:64-65)过频降功率延时范围(全工程无引用,死宏)
PF_LOCK_OUT_POINT_MAX/MIN、PF_LOCK_IN_POINT_MAX/MIN宏 = 98/90、10/5(:67-70)PF 曲线锁定/解锁点范围
PU_POWER_LOWER_LIMIT_MAX/MIN宏 = 100 / 0(:72-73)P-U 曲线发电下限百分比
PU_CHARGE_POWER_UPPER_LIMIT_MAX/MIN宏 = 2300 / 2160(:75-76)P-U 曲线充电上限(1.1 p.u. = 253 V 附近)
PU_VOLTAGE1..4_MAX/MIN宏(:78-88)P-U 曲线 4 个拐点电压:2000/2100、2160/2300、2400/2550、2530/2650
QU_UNDER_EXCITED_VAR_MAX/MIN、QU_OVER_EXCITED_VAR_MAX/MIN宏 = 100/0(:90-:94)Q-U 曲线欠励/过励无功百分比
QU_COMPAREVOLT_V1..V4_MAX/MIN宏(:96-:106)Q-U 曲线 4 个比较电压,范围与 PU_VOLTAGE 相同
TN_TO_WGRA_UP_MAX/MIN、TN_TO_WGRA_DOWN_MAX/MIN宏 = 1200 / 0(:108-112)功率变化率 Tn→Wgra 上升/下降时间(ms)
REACTIVE_POWER_POINT_MAX/MIN宏 = 80 / 0(:114-115)DRM 无功设定点百分比
PF_VALUE_OVER_EXCITED_MAX/MIN、PF_VALUE_UNDER_EXCITED_MAX/MIN宏 = 100/90(:117-:121)非 AS4777 安规下的 PF 设定值范围
PF_VALUE_OVER_EXCITED_AS4777_MAX/MIN、PF_VALUE_UNDER_EXCITED_AS4777_MAX/MIN宏 = 100/80(:123-:127)AS4777 安规下的 PF 设定值范围(下限放宽到 80)
Q_VALUE_MAX/MIN宏 = 2760 / 0(:129-:130)Q 模式无功设定值范围(0.01 kVar 量级)
QU_VOLT_UP_MAX/MIN、QU_VOLT_LOW_MAX/MIN宏 = 110/100、100/90(:132-:136)Q-U 曲线电压上/下限百分比
CURVE_UPPER_LIMIT_MAX/MIN、CURVE_LOW_LIMIT_MAX/MIN宏 = 100/90(:138-:142)PF-P 曲线功率上/下限百分比
CURVE_POWER_UPPER_MAX/MIN、CURVE_POWER_LOWER_MAX/MIN宏 = 100/0(:144-:148)PF-P 曲线功率上下限
INVERTER_POWER_PERCENT_LIMIT_MAX/MIN宏 = 100 / 0(:150-151)逆变器功率百分比限制(全工程无引用,死宏)
PV_CAPACITY_MAX/MIN/DEFAULT宏 = 99999/0/0(:153-155)储能侧 PV 装机容量范围与越界回落值
PV_CAPACITY_GRID_MAX/MIN/DEFAULT宏 = 99999/0/0(:157-:159)并网侧 PV 装机容量范围与越界回落值
CURRENT_LIMIT_MAX/MIN/DEFAULT宏 = 99999/0/16(:161-:163)并网功率限制电流范围(A),缺省 16 A
USER_FORCE_CHARGE_CUT_SOC_MAX/MIN/DEFAULT宏 = 100/0/100(:165-:167)用户一键强充截止 SOC
GENERATOR_RATE_POWER_LIMIT_MAX/MIN宏 = 99999 / 0(:169-:170)油机额定功率范围(W)
GENERATOR_RATE_PERCENT_LIMIT_MAX/MIN宏 = 100 / 0(:171-:172)油机降额百分比
GENERATOR_SOC_LIMIT_MAX/MIN宏 = 100 / 0(:173-:174)油机 SOC 起停阈值
GENERATOR_TIME_LIMIT_MAX/MIN宏 = 24 / 0(:175-:176)油机 TOU 起止小时
GENERATOR_CHARGE_POWER_LIMIT_MAX/MIN宏 = 99999 / 0(:177-:178)油机充电功率
CT_RATE_MAX/MIN/DEFAULT宏 = 999 / 1 / 1(:180-:183)CT 变比范围(下限为 1,因为 0 会成为除数)
DISPLAY_TYPE_E枚举(:186-195)显示外设类型:DISPLAY_NONE_E=0、DISPLAY_LCD_CHARACTER_E(LCD 字符屏)、DISPLAY_LED_LAMP_STRIP_E(四代机灯条)、DISPLAY_LED_BICOLOR_E(双色小灯板)、DISPLAY_LED_LAMP_PANEL_E(五代机亚克力灯板)、DISPLAY_LCD_PARAGRAPH_E(五代机一体机 LED 屏)、DISPLAY_LCD_RKP_E(林内项目)
ID_E枚举(:198-204)身份等级:id_none=0、id_user、id_installer、id_admin;顺序即权限序,hmi/key.c 依赖 id_none == 0 把身份值当布尔用
LED_LAMP_PANE_ID_E枚举(:206-219)灯板点位索引:LED_RED、LED_BLUE、LED_DB0…LED_DB7,末尾 LED_NUM 作遍历上界
LOGIN_IN_T结构体(:221-225)登陆记忆:u8 id_setting_into_last(上次身份)、u32 time_setting_into_last(OSTimeGet() tick);实例为 g_t_ui_login

3. 函数清单

本文件不定义任何函数,仅声明 9 个函数原型。下表列出全部原型及其在本工程中的真实定义位置与调用方:

函数名作用域说明
n_power(u8 num, u8 n)全局(hmi/key.h:232 声明)定义于 hmi/key.c:135;整数幂,仅被 hmi/key.c 内部调用
Key_Handle_Up(void)全局(:233)定义于 hmi/key.c:1732
Key_Handle_Down(void)全局(:234)定义于 hmi/key.c:4084
Key_Handle_Enter(void)全局(:235)定义于 hmi/key.c:6574
Key_Handle_Cancel(void)全局(:236)定义于 hmi/key.c:206
Key_Handle(void)全局(:237)定义于 hmi/key.c:8762;由 task_hmi_parse 每 10 ms 调用
Button_ChangeEthernetSettingLiteral(u8 *Number, u8 AddSubFlag)全局(:239)定义于 hmi/key.c:1624;IP/掩码/网关段编辑
Button_Get_SystemTime(void)全局(:240)本工程无对应的全局定义;同名实现是 hmi/ui/ui_setting_user_sys_date.c:11 的 static 函数,该原型为失效声明
Button_Handle(u32 *data, u8 bit_index, u8 flag, u32 max, u32 min)全局(:241)定义于 hmi/key.c:158;位权加减 + 上下限回绕,flag 取 PLUS/SUB
task_hmi_parse(void *p_arg)全局(:243)定义于 hmi/key.c:8888;被 user/main.c:310 以 OSTaskCreateExt 创建

未在本文件声明、但在 hmi/key.c 中定义为全局函数的还有 Last_ID_Legal_Handle、Button_Get_ErrorLogInfo、Factory_Mode_Setting(三者均无非 static 的对外使用,却缺少原型);Backlight_Reload 的原型意外放在 hmi/lcd.h:430 而不是本文件。

4. 核心逻辑解析

本文件是纯声明文件,没有状态机、算法、通信帧或定时逻辑。以下说明这些声明在运行时的实际作用路径。

4.1 取值范围宏如何形成"参数合法性第一道闸门"

所有可编辑数值的边界都来自本文件,hmi/key.c 的调用模式统一为:

button_data_buf = (u32)LCD_RTDB.<字段>;
Button_Handle(&button_data_buf, <位权>, PLUS|SUB, <本文件的 MAX 宏>, <本文件的 MIN 宏>);
LCD_RTDB.<字段> = (u16|u32)button_data_buf;

分单位约定可从宏值反推(hmi/key.c 的注释与换算处佐证):

物理量宏单位证据
电压0.1 V(GRID_VAC_VOLT_MAX = 3000 → 300.0 V)hmi/key.c:1918-1922 直接下发同值
频率0.01 Hz(GRID_FAC_FREQ_MAX = 5500 → 55.00 Hz)hmi/key.c:2211-2215
时间ms(GRID_TIME_VAC_MAX = 65535)hmi/key.c:1988-1992
功率限制宏存 A,落盘时乘 230*3(CURRENT_LIMIT_MAX = 99999)hmi/key.c:3097、:5543、:7870
油机时间小时(GENERATOR_TIME_LIMIT_MAX = 24)hmi/key.c:3650

Button_Handle() 会无条件信任这组宏,内部没有任何针对 max 的防护,所以本文件的宏值必须满足 10^bit_index < max(bit_index 由 行位数 - bCurrSubCursor 得到,见 hmi/key.c:158-197)。

4.2 密码常量如何被消费

三个常量之间没有互相约束检查:若把 USER_PASSWORD 或 INSTALLER_PASSWORD 改成与 ADMIN_PASSWORD % 10000(7570)相同,hmi/key.c:6822-:6837 的掩码判定(0x05/0x06 分支)会导致身份判定歧义。

4.3 枚举类型的运行时用途

4.4 LOGIN_IN_T 的生命周期

阶段动作位置
记录密码校验成功时 set_ui_login_info(identity) 写 id_setting_into_last 与 OSTimeGet()hmi/key.c:53-57,调用点 :6743、:6778、:6831、:6845
消费主菜单进"设置"时若 is_last_id_legal() 非 0 则按记忆身份直达设置页(免密)hmi/key.c:6597-6618
失效Last_ID_Legal_Handle() 在 admin/installer 超 3600000 tick(1 h)、user 超 1800000 tick(30 min)时清零hmi/key.c:76-93;主循环调用点 :8962
主动注销设置退出页勾选"退出并注销"时 id_setting_into_last = id_nonehmi/key.c:321-:326

5. 对外接口

本文件导出的内容

类别符号主要使用方
类型LOGIN_IN_T、ID_E、DISPLAY_TYPE_E、LED_LAMP_PANE_ID_Ehmi/key.c、hmi/led.c、hmi/led/*、midware/interface/modbus/modbus.h(DISPLAY_LED_LAMP_PANE_CTROL_U 用同名点位语义)
变量extern LOGIN_IN_T g_t_ui_login;(:228)仅 hmi/key.c(实测无其它引用者)
变量extern struct RTC_DateTime SYSTEM_DATETIME;(:229)本工程无引用者(hmi/key.c 用的是 LCD_RTDB.LCD_DATETIME 与 Set_RTC()),属遗留声明
宏三个密码常量hmi/key.c、data/system_config/system_config.c
宏全部 *_MAX/*_MIN/*_DEFAULT 编辑范围宏仅 hmi/key.c(GRID_FREQ_DROOPRATE_*、GRID_OF_REDUCE_POWER_DELAY_TIME_*、INVERTER_POWER_PERCENT_LIMIT_* 三组全工程零引用)
函数原型9 个(见第 3 节)hmi/key.c(全部实现)、user/main.c(仅 task_hmi_parse)

本文件调用的外部内容

6. 依赖关系

依赖

被依赖(#include "key.h" 或使用其符号)

7. 备注与风险点

  1. Button_Get_SystemTime 是失效且冲突的原型(hmi/key.h:240):本工程只有 hmi/ui/ui_setting_user_sys_date.c:11 的 static void Button_Get_SystemTime(void),该文件在同名签名下再加 extern 声明会触发链接/编译期冲突,且类型不一致时(现在恰好一致)无编译告警。建议删除。
  2. extern struct RTC_DateTime SYSTEM_DATETIME;(hmi/key.h:229)全工程无引用,是历史遗留;extern 变量放在头文件里还会让每个包含者都产生一次外部引用。
  3. 三组死宏:GRID_FREQ_DROOPRATE_MAX/MIN(:61-62)、GRID_OF_REDUCE_POWER_DELAY_TIME_MAX/MIN(:64-65)、INVERTER_POWER_PERCENT_LIMIT_MAX/MIN(:150-151)全工程零引用,说明对应界面已被注释掉(对照 hmi/key.c:649-:686、:831-:846 的整段注释)。
  4. LOGIN_IN_T 的时间域是 u32 tick,未处理回绕:OSTimeGet() 在 1000 tick/s 下约 49.7 天回绕,hmi/key.c:81/:88 用 OSTimeGet() - time_setting_into_last 直接比较,跨回绕瞬间会得到极大差值并立即清身份(仅表现为需重新输密码,但属未处理边界)。
  5. 密码常量互相之间无约束校验:见 4.2。若 USER_PASSWORD 或 INSTALLER_PASSWORD 与 7570 相同,hmi/key.c:6822-:6837 的 0x07 掩码判定会出现"用户密码对但同时被当成管理员低位"的歧义分支。
  6. ID_E 的枚举顺序有隐式语义:id_none 必须为 0(hmi/key.c:339、:1469、:6597 等把返回身份当布尔用);id_admin 在 id_user/id_installer 之后但不依赖大小比较,权限判断全部是 ==,再加新身份时需检查所有分派点。
  7. LED_LAMP_PANE_ID_E 与硬件点位的对应是"约定式"的:led_get_bit_state/led_hw_control(hmi/key.c:8840-8881)依赖枚举值 0…9 与 g_t_ate_ctrol 位域顺序、gpio 函数名一一对应,任一侧插值都会静默错位。
  8. 范围宏与界面实际拆位不匹配的隐患:GENERATOR_TIME_LIMIT_MAX = 24(2 位十进制,位权最高 10),hmi/key.c:3650 用位权 2 - bCurrSubCursor 是对的,但 :6147 用 3 - bCurrSubCursor 会得到位权 100 > 24,触发 Button_Handle 的"越下限"分支直接归零。根因是本文件只提供上下限、不校验调用方传的位权。
  9. #define DEBUG_HMI 用值而非 #ifdef 判断:hmi/key.c:8981 写 #if (DEBUG_HMI == 1),所以宏必须始终有定义(当前为 0),删掉定义会退化。写法本身没问题,但注释里没有说明这一点。
  10. 头文件缺少 extern "C" 包裹:本工程为纯 C(Keil MDK + uCOS-II),当前无影响;但若将来有 C++ 测试桩会立即出问题。
  11. 无 include guard 命名冲突风险:__KEY_H__(:9)属常见名,与同为 __*_H__ 风格的其它模块头文件并存,若第三方库也定义同名宏会静默吞掉整个头文件内容(当前工程未见冲突)。