logic.c
task_system_logic_control(logic.c:2902–2959)4.2 系统数据采集与限值计算:logic_sys_running_info_handle(logic.c:914–1168)4.3 序列控制模式状态机:ongrid_logic_handle(logic.c:2189–2339)4.4 时间段控制:logic_control_by_time / logic_comparing_time_periods4.5 并网取电限值的两个累加器4.6 英国 G100 防逆流状态机:uk_g100_handle(logic.c:372–542)4.7 德国 §14a EnWG:deu_14a_enwg_handle(logic.c:160–298)4.8 SOC 校准状态机4.9 CSIP-AUS / DNSP ramp 渐进限幅:dnsp_ramp_control_handle(logic.c:2779)4.10 智能化(PV 超充)控制与光伏优先4.11 Backup 与 EPO4.12 全局变量的读写与触发条件5. 对外接口5.1 导出的函数(在 logic.h 中声明,供外部调用)5.2 导出的全局变量5.3 本文件调用的外部函数/变量(按模块)6. 依赖关系6.1 依赖(本文件 include 或使用的外部模块)6.2 被依赖(哪些文件会用到它)7. 备注与风险点源文件路径:
logic/logic.c所属模块:logic(能量调度核心) 代码行数:3522
1. 文件职责
本文件是 EMS 能量调度的主入口与总装配层。它由 uCOS-II 任务 task_system_logic_control(logic.c:2902)驱动,周期约 280 ms 运行一次,先把逆变器/电表/BMS/并机/充电桩的实时数据一次性采集进全局结构 g_t_logic_info.t_logic_control_parameter(logic_sys_running_info_handle,logic.c:914),再据此判定当前应进入哪一种「序列控制模式」u8_sequencecontrol_mode(ongrid_logic_handle,logic.c:2189),最后把该模式分发到 dc_control.c / ac_control.c / dispatch.c / generator.c / handle_priority.c 等下游模块计算 AC 侧与 DC 侧的设定功率,结果写回 g_t_logic_info.s32_ac_* / s32_dc_*,供逆变器任务组装下发报文。除主调度外,本文件还自持若干独立子系统:英国 G100 防逆流状态机、德国 §14a EnWG 可控设备功率预算、CSIP-AUS(南澳)DNSP ramp 渐进限幅、SOC 校准、削峰填谷、智能化(PV 超充)控制、EPO 与 Backup 保护。它处在数据流的「采集 → 决策 → 功率设定输出」中间的决策环节,向 g_t_logic_info 单向写入,被 inverter/parallel/net 等模块读取。
2. 关键数据结构与宏
| 名称 | 类型 | 说明 |
|---|---|---|
g_t_logic_info | 全局变量(LOGIC_TABLE_T) | 本模块唯一的全局数据总线,定义于 logic.c:34,声明于 logic.h:646。上层的实时采样、下层的功率设定、所有配置镜像、G100/14a/SOC 校准等运行态全部放在这里 |
LOGIC_TABLE_T | 结构体(logic.h:494) | 顶层聚合体,内含 4 张 Flash 配置表 + 1 张 t_logic_control_parameter 运行参数表 + u_self_test_result + 约 90 个跨模块控制字段(CSIP-AUS、DC/AC 设定功率、削峰填谷、SOC 校准、DNSP 旧值/ramp 值等) |
LOGIC_CONFIG_TAB_T | 结构体(logic.h:288) | 主逻辑配置表,含时间段强充/允放(旧版)、油机(GC)、RRCR/EZA 馈网百分比、G100 表、SOC 校准表、削峰填谷、智能化控制、EPO 配置字节 u8_epo_config_en、u8_reserved[83]、u16_crc_code |
LOGIC_CONTROL_PARAMETER_T | 结构体(logic.h:138) | 系统运行参数镜像表:逆变器特性/规格/运行信息、电池规格与运行信息、电表信息、调节参数(馈网限值、充放电限值、电流限值、各类计算间隔 tick)。本文件的主要「写目标」 |
LOGIC_CONFIG_EXTEND1_TAB_T / EXTEND2_TAB_T / EXTEND3_TAB_T | 结构体(logic.h:437 / 446 / 455) | 新版时间段配置:EXTEND1/2 各 14 段充/放电时间段,EXTEND3 为 6 段强制电池馈网时间段 |
LOGIC_TIME_CONTROL_TAB_T | 结构体(logic.h:399) | 单个时间段条目:周标记、起止分钟数、截止 SOC、功率 |
LOGIC_TIME_BAT_FEEDIN_CONTROL_TAB_T | 结构体(logic.h:418) | 单个强制电池馈网时间段条目 |
TIME_CONTROL_RUN_TAB_T | 结构体(logic.h:430) | EXTEND1+EXTEND2 的运行期合并视图(本文件未直接使用) |
UK_G100_TABLE_T | 结构体(logic.h:252) | G100 持久化状态:u8_system_state、u8_state_reason、u32_tick_state2[3]、u32_tick_state3[3](三次历史事件时间戳环形表) |
SOC_CALIBRATION_TABLE_T | 结构体(logic.h:263) | SOC 校准配置:使能、周期使能、周期天数、下次/上次校准年月日分钟 |
SMART_CONTROL_TABLE_T | 结构体(logic.h:278) | 智能化控制配置:充电截止 SOC、超充起止时间、PV 最大功率、生效日期 |
SELF_TEST_RESULT_U | 联合体 + 位域(logic.h:466) | 自检结果位域(grid/pv 电表缺相、接反等),本文件仅作为 t_logic_info.u_self_test_result 的成员被聚合,不直接读写 |
SEQUENCE_CONTROL_MODE_E | 枚举(logic.h:41) | 核心状态机状态集,共 20 项:NOT_SEQUEN_CECONTROL、GC_CECONTROL、NO_BAT_CECONTROL、CMD_FORCE_CHARGE_MODE、SYS_FORCE_CHARGE_MODE、BAT_FORCE_CHARGE_MODE、DISPATCH_BAT_MODE、DISPATCH_FREQ_MODE、DISPATCH_MODE、TIME_FORCE_CHARGE_MODE、TIME_FORBID_DISCHG_MODE、SELFUSE_MODE、USER_FORCE_CHARGE_MODE、FORCE_BAT_FEEDIN_MODE、TIME_PRECHARGE_MODE、TIME_ALLOW_DISCHG_MODE、SELF_TEST_CHARGE_MODE、SOC_CALIBRATIONG_MODE、TIME_PEAK_SHAVING_MODE、SMART_CONTROL_MODE |
UK_G100_STATE_E | 枚举(logic.h:90) | G100 状态机 4 态:STATE1_NORMAL(=1)、STATE2_OVER_LIMIT、STATE3_FOBID_FEEDIN、STATE4_LOCK |
UK_G100_STATE_REASON_E | 枚举(logic.h:78) | G100 状态触发原因 7 项:OVER_STATE1_NOTH、OVER_STATE2_0S_15S、OVER_STATE2_15S_60S、OVER_STATE3_15S_60S、OVER_STATE3_MORE60S、OVER_STATE4_3TIMES_30D、OVER_STATE3_COM_FAULT |
DER_CONTROL_STATUS_E | 枚举(logic.h:71) | CSIP-AUS DER 控制态:DER_NORMAL=0、DER_CONTROL、DER_CONTROL_DEFAULT |
SMART_CONTROL_STATE_E | 枚举(logic.h:131) | 智能化控制两态:STATE_NORMAL=0、STATE_OVERMATCH |
RRCR_EZA_STATUS_E | 枚举(logic.h:114) | 德国 RRCR/EZA 远程功率限值态:ALL_DISABLE=0、RRCR_ENABLE、EZA_ENABLE |
PEAKSHVING_STATE_E / EPO_STATUS_E / RESERVE_SOC_EN_E / LOGIC_CONTROL_SPECIAL_INV_TYPE_E | 枚举 | 削峰填谷状态、EPO 状态、预留 SOC 使能、特殊机型标记;本文件基本不直接使用(仅作类型存在) |
FAST_DISPATCH_FLAG_E | 枚举(logic.h:121) | 快速调度标志位集,与 g_t_fast_dispatch_flag 事件标志组配合:POST_PEND_FAST_ENABLE=1、POST_LOGIC_CALCULATE_DONE=2、PEND_LOGIC_CALCULATE_DONE=3、POST_INV_CALCULATE_DONE=4、PEND_INV_CALCULATE_DONE=7 |
PV_PRIORITY_AC_CONTORL_STATE | 枚举(外部 logic/handle_priority.h:15) | 光伏优先 AC 控状态机状态集,本文件 pp_total_power_ac_control_state_handle(logic.c:1876)负责迁移判定,pp_total_power_ac_control(logic.c:1939)负责分发 |
LOGIC_CONTROL_SPECIAL_HANDLE_T | 结构体(logic.h:240) | 特殊机型调节速度参数,本文件以数组 para_tables[LOGIC_CTROL_SPECIAL_MAX_COUNT](logic.c:52)实例化 2 组常量 |
ENWG_MIN_POWER | 宏(logic.c:36,值 4200) | 注释标注为「§14a 单设备保底功率」,定义后在全文件中未被引用(实际代码用字面量 4200) |
DEBUG_LOGIC | 宏(logic.h:17,值 0) | 调试打印总开关,控制大量 #if (DEBUG_LOGIC) 打印块 |
SENCOND_1S / SENCOND_5S / SENCOND_15S / SENCOND_60S | 宏(外部 net/ems.h:24/27/29/31) | 以 ms 为单位的秒常量,用于 G100 状态计时与充电功率限值调节周期 |
OS_TICKS_PER_SEC | 宏(外部 UCOSII/uCOS-CONFIG/os_cfg.h:51,值 1000) | 系统滴答率,SOC 校准 20 s 等待用到 |
PHASE_L1/L2/L3/PHASE_A/B/C/PHASE_T | 宏 | 相索引,本文件 logic_read_*_three_phase_set_inv_power 等按相索引取值 |
| 模块级可写全局 | 变量 | g_s32_bat_charge_power_limit(logic.c:74)、g_s32_bat_charge_power_inv_limit(logic.c:75)、s32_set_inverter_setgradw / s32_old_set_inverter_setgradw(logic.c:51) |
3. 函数清单
共 83 个函数定义(含 19 个 static),另有 9 条 static 前置原型声明(logic.c:40–logic.c:50)。
| 函数名 | 作用域 | 说明 |
|---|---|---|
evc_count_controllable_active | static | 统计处于 14a 可控状态(chgsts 3/4 且 SPECIFIED_POWER)的活动充电桩数量,并机时累加所有 EVC_II 桩 |
enwg_device_limit_power | 全局 | 按德国 §14a 公式计算受控多设备总功率上限(4200 W 保底 + GFZ 递减系数) |
deu_14a_enwg_handle | 全局 | §14a EnWG 主处理:判定是否真正生效,计算电池/EV 各自的功率上限并写入 g_t_logic_info |
get_14a_enwg_active | 全局 | 返回 u8_14a_enwg_active,供 EV/EV_II 模块做总额度限幅 |
uk_g100_over_set_power | static | 判断电表功率是否超过英国 G100 规定的馈出/取入限值(含 2% 裕度) |
logic_apparent_power_limit | 全局 | 逆变视在功率限制:仅在 AS4777 安规下允许使能,使能后压低 s32_inv_rated_output_power |
uk_g100_handle | static | 英国 G100 四态状态机主处理,含 15 s/60 s/10 min/24 h/30 天多级升级与通讯故障降级 |
time_peakshaving_command | 全局 | 削峰填谷入口:按标志调用 AC/DC 削峰或填谷命令函数,再串接功率限制 |
smart_control_status_detect | 全局 | 按逆变器 PV 功率与 u32_pv_max_power 比较判定 STATE_NORMAL / STATE_OVERMATCH |
handle_smart_control_normal_state | 全局 | 智能化控制常规态:SOC 达充电截止值时清零充电限值,然后跑自发自用 |
handle_smart_control_overmatch_state | 全局 | 智能化控制光伏超动态:转光伏优先模式 |
handle_smart_control_mode | 全局 | 智能化控制状态机外壳,带 s_u8_pre_status 记录上一状态 |
sys_grid_input_max_single_phase_cur | static | 由电网侧功率限值反算单相最大输入电流(0.1 A 单位,减 cur_margin 裕度) |
sys_grid_input_power_limit | static | 电网侧取电限值的增量式 PI 型累加器,周期 5 s(CSIP ramp 下 1 s),输出累积到 g_s32_bat_charge_power_limit |
sys_inv_grid_input_power_limit | static | 由逆变器市电侧过载系数、空开规格、CSIP 负载限值反算电池从 AC 端取电的功率上限,累加到 g_s32_bat_charge_power_inv_limit |
logic_sys_running_info_handle | static | 系统数据总采集:把逆变器/电池/电表/并机的数百项数据搬进 t_logic_control_parameter,再计算馈网限值、充放电限值、电流限值、电池使能标志 |
calculation_next_calibration_time | static | 按配置周期天数推算下一次 SOC 校准年月日(含闰年与跨月),并 post Flash 保存 |
sys_get_soc_calibration_flag | 全局 | SOC 校准状态机(0 空闲 / 1 校准充电 / 2 校准放电),返回当前校准阶段 |
logic_comparing_time_periods | static | 时间段判定:返回 0 段内、1 段外、2 无效,支持跨天与周日~周六位掩码 |
logic_control_by_time | static | 处理全部时间段类配置(强制馈网、削峰填谷、强充、允放/禁放),把结果刷进 g_t_logic_info 的对应标志与 SOC/功率 |
logic_charge_dischg_power_limit | 全局 | 功率限制总入口,按 INV_DC_CTRL / INV_AC_CTRL 条件编译调用 DC/AC 总功率与三相不均衡功率限制 |
bat_force_charge | 全局 | 强充模式:调 DC/AC 强充功率计算后接功率限制 |
bat_force_discharge | 全局 | 强放模式:调 DC/AC 强放功率计算后接功率限制 |
bat_power_control | 全局 | 指令功率控制模式:调 DC/AC 电池功率控制计算后接功率限制 |
self_use_funtion | 全局 | 自发自用(含无电表降级、无 PV 功率支撑补偿、强制馈网偏置)后调 DC/AC 自发自用计算 |
pp_total_power_ac_control_state_handle | 全局 | 光伏优先状态迁移判定:按 PV 状态、电池状态、电表功率相对 -50 W/自耗功率/馈网上限 ±200 W 决定下一状态 |
pp_total_power_ac_control | 全局 | 光伏优先状态分发,按 PV_PRIORITY_AC_CONTORL_STATE 调 handle_priority_*.c 中对应处理函数 |
ac_control_total_power_photovoltaic_priority_calculate | 全局 | 光伏优先计算外壳,含 u32_calculation_ac_total_inv_tick 软定时限速 |
photovoltaic_priority_funtion | 全局 | 光伏优先模式入口(与自发自用同级),处理无电表降级后调 AC 计算与功率限制 |
no_bat_logic_control | 全局 | 无电池(BMS 未 ready)模式:调 DC/AC 无电池计算,并按软启动/硬件限流开关回填设定功率 |
calculate_gc_chgpower | 全局 | 油机充电功率计算入口(并网且模式为 GC_CECONTROL 时),油机未启动时清零取电与充电限值 |
get_smart_control_mode | 全局 | 智能化控制时段判定:使能且时间有效且当前处于超充时段内时返回 TRUE |
other_logic_handle | 全局 | 非并网工况下把所有 DC/AC 设定功率清零(注释写 static 但实际为全局定义) |
ongrid_logic_handle | static | 序列控制模式状态机:优先级链判定 u8_sequencecontrol_mode,再按模式分发到各执行函数 |
inv_backup_basic_protect | 全局 | Backup 基础负载保护:按离网频率/电网故障/最大放电能力/预留容量决定使能或禁止 backup |
ups_cutoff_wakeup_soc_control | 全局 | 离网带载 SOC 控制:按 u8_cutoff_soc / u8_wakeup_soc 决定 backup 关断与唤醒 |
backup_control_flag_handle | static | Backup 控制总入口:先 SOC 控制再基础保护,最后 set_inverter_backup_enable(与并机 backup 状态取或) |
handle_logic_soc_calibration_tick | 全局 | 非并网/油机工况下 SOC 校准的补偿处理:等待 20 s 后按循环/单次模式推进校准时间 |
dnsp_ramp_ac_control_handle | static | AC 侧 DNSP ramp 渐进限幅:逆变总功率按 step,电池充/放限值增按 step*1.1、减按 step*0.9,并做 BMS/并机上限钳位 |
dnsp_ramp_ac_rebase_to_real_power | static | AC ramp 基准对齐:逆变以 s32_pinvt 为起点、电池以当前限值为起点,重置 ramp tick |
dnsp_ramp_dc_control_handle | static | DC 侧 DNSP ramp 渐进限幅:逆变/馈网/电池三路均按 step 渐进(1.1/0.9 倍率被注释掉) |
dnsp_ramp_dc_rebase_to_real_power | static | DC ramp 基准对齐:以电表功率、s32_pinvt、电池总功率为起点 |
dnsp_ramp_control_handle | static | DNSP ramp 总控:判定使能、检测序列模式与 DER 控制模式切换并 rebase,按累积 1000 ms 触发一次 AC/DC ramp |
handle_logic_smart_tick | 全局 | 智能化控制「单日有效」处理:日期变化即清除使能并 post 保存 |
task_system_logic_control | 全局 | uCOS-II 任务体:等待快速调度标志、周期采集+决策、社会校准/智能化/backup 次任务、发布计算完成标志并唤醒逆变器任务 |
logic_read_sequencecontrol_mode | 全局 | 读当前序列控制模式 |
logic_set_sequencecontrol_mode | 全局 | 强制设置序列控制模式(供 SunSpec/并机模块覆盖) |
logic_read_mppt_percentage | 全局 | 读 MPPT 百分比,AC 控且 SunSpec WSet 使能且刷新标志置位时改用 SunSpec 值 |
logic_read_max_feedin_power | 全局 | 读系统最大允许馈网功率(返回 u32,源字段为 s32) |
logic_read_gc_charger_cut_soc | 全局 | 油机 SOC 模式下返回 GCSOCEnd,否则 100 |
logic_read_user_charger_cut_soc | 全局 | 读用户自定义强充截止 SOC |
logic_read_charger_cut_soc | 全局 | 读时间段强充截止 SOC |
logic_read_feedin_cut_soc | 全局 | 读强制电池馈网截止 SOC |
logic_read_peakshving_discharge_cut_soc | 全局 | 读削峰填谷放电截止 SOC |
logic_read_ups_reserve_soc | 全局 | 读 UPS 预留 SOC(取自配置表) |
logic_read_allow_discharge_cut_soc | 全局 | 读允许放电截止 SOC |
logic_read_ups_reserve_flag | 全局 | 读 UPS 预留 SOC 使能标志 |
logic_read_dc_total_set_bat_power | 全局 | 读 DC 侧电池设定功率,DNSP ramp 生效时返回 ramp 值 |
logic_read_dc_total_set_inv_power | 全局 | 读 DC 侧逆变设定功率,DNSP ramp 生效时返回 ramp 值 |
logic_read_dc_total_set_grid_power | 全局 | 读 DC 侧馈网设定功率,DNSP ramp 生效时返回 ramp 值 |
logic_read_dc_three_phase_set_bat_power | 全局 | 读 DC 侧三相不均衡电池设定功率 |
logic_read_dc_three_phase_set_inv_power | 全局 | 按相索引读 DC 侧三相不均衡逆变设定功率 |
logic_read_ac_total_set_inv_power | 全局 | 读 AC 侧逆变设定功率,DNSP ramp 生效时返回 ramp 值 |
logic_read_ac_total_set_bat_charge_limit_power | 全局 | 读 AC 侧电池充电限值,DNSP ramp 生效时返回 ramp 值 |
logic_read_ac_total_set_bat_dischg_limit_power | 全局 | 读 AC 侧电池放电限值,DNSP ramp 生效时返回 ramp 值 |
logic_read_ac_total_set_bat_forced_charge_en | 全局 | 读 AC 侧总功率强充使能 |
logic_read_ac_three_phase_set_inv_power | 全局 | 按相索引读 AC 侧三相不均衡逆变设定功率 |
logic_read_ac_three_phase_set_bat_charge_limit_power | 全局 | 读 AC 侧三相不均衡电池充电限值 |
logic_read_ac_three_phase_set_bat_dischg_limit_power | 全局 | 读 AC 侧三相不均衡电池放电限值 |
logic_read_ac_three_phase_set_bat_forced_charge_en | 全局 | 读 AC 侧三相不均衡强充使能 |
logic_read_grid_meter_connect | 全局 | 读电网电表连接状态 |
epo_set_config_enable | 全局 | 写 EPO 使能位(bit0),保护激活期间拒绝修改,变更后 post 保存 |
epo_read_config_enable | 全局 | 读 EPO 使能位(低半字节是否为 1) |
epo_set_protect_enable | 全局 | 写 EPO 保护标志位(bit4),保持其他位不变 |
epo_read_protect_enable | 全局 | 读 EPO 保护标志位(bit4) |
epo_set_signal_status | 全局 | 设置 EPO 外接短路信号状态(仅存于运行态,不落盘) |
epo_read_signal_status | 全局 | 读 EPO 外接短路信号状态 |
get_enwg_bat_charge_limit | 全局 | §14a 电池买电功率限制读取接口 |
get_enwg_evc_power_limit | 全局 | §14a 充电桩功率限制读取接口 |
logic_read_time_force_chg_flag | 全局 | 读时间段强充标志 |
logic_comparing_time | 全局 | 判断当前时刻是否落在 05:00–18:00 之间(只比较时分) |
sys_limited_by_csip_judge | 全局 | 判断当前是否处于南澳 CSIP 调度受限模式(调频模式或 u8_dercontrol == DER_NORMAL 时返回 FALSE) |
get_maxfeedin_priority_flag | 全局 | 判断是否 concess maxfeedin 优先(配置位或 DNSP 自动置位) |
4. 核心逻辑解析
4.1 任务调度:task_system_logic_control(logic.c:2902–2959)
任务体是一个无限循环,每个周期依次做四件事:
- 等待快速调度标志:
OSFlagPend(g_t_fast_dispatch_flag, POST_PEND_FAST_ENABLE, OS_FLAG_WAIT_SET_ALL, 20, &err)(logic.c:2912),超时 20 个 tick(20 ms)。该标志由net/server.c:838在收到云端快速调度请求时OSFlagPost。若拿到标志,先把 5 个功率计算间隔 tick 全部清 0(logic.c:2916–2920),使本周期内所有 DC/AC 计算不受软定时限速而立即执行。 - 周期采集与决策:仅当
inverter_get_sys_ctrl_state() != FALSE(系统控制态)时执行。顺序严格为logic_sys_running_info_handle()→frequency_regulation_detection()→dectect_api_dispatch_comm()→generator_logic(),然后按u8_grid_status分支:- 并网:
ongrid_logic_handle()再dnsp_ramp_control_handle(); - 非并网:
other_logic_handle()(清零所有设定功率)。
- 并网:
注释明确写了「必须放在控制逻辑之前」(logic.c:2927),因为调频/API 调度/油机都会改写模式标志。
- 次任务:
handle_logic_soc_calibration_tick()、handle_logic_smart_tick()、backup_control_flag_handle()(logic.c:2943–2945),这三个不受系统控制态限制。 - 交棒:若本周期拿到了快速调度标志(
os_flag == 0x01 && err == OS_ERR_NONE,logic.c:2951),OSFlagPost(POST_LOGIC_CALCULATE_DONE)并OSTimeDlyResume(TASK_INVERTER_PRIO)立刻唤醒逆变器任务;随后OSTimeDlyHMSM(0, 0, 0, 280)休眠 280 ms。
任务由 user/main.c:211 以 OSTaskCreateExt 静态创建,优先级 TASK_LOGIC_CONTROL_PRIO(UCOSII/uCOS-CONFIG/app_cfg.h:63,值为 12,注释标称间隔 300 ms)。与逆变器任务的握手链为:server.c 置 POST_PEND_FAST_ENABLE → 本任务置 POST_LOGIC_CALCULATE_DONE → inverter.c:1054 等 PEND_LOGIC_CALCULATE_DONE / inverter.c:1185 置 POST_INV_CALCULATE_DONE → inverter.c:1207 等 PEND_INV_CALCULATE_DONE(带 OS_FLAG_CONSUME)。本模块在 logic.c:2908 初始化 u16_mppt_percentage = 10000(即 100.00%)。
4.2 系统数据采集与限值计算:logic_sys_running_info_handle(logic.c:914–1168)
这是全文件的信息枢纽,顺序为:
- 逆变器特性(
logic.c:930–942):从inverter.c/parallel.c读取调节步长、扰动标记、过载系数、AC/DC 计算间隔、微调范围、系统自耗、控制精度、补偿功率、maxfeedin 偏置、三相不平衡最小充电功率、DC 扰动计数。 - 逆变器规格与运行信息(
logic.c:945–979):相数、额定输入/输出/充/放功率;PV/电网状态;三相 Grid/INV/Backup 电压・功率・频率;PV 总功率、逆变侧电池功率与电流。 - 电池与电表(
logic.c:982–1000):电池额定充放功率、SOC、低 SOC 阈值、电压、总功率;电网电表连接状态、三相电压、三相与总功率。 - G100 与 14a(
logic.c:1004–1006):uk_g100_handle()与deu_14a_enwg_handle()在此被调用。 - 馈网上限(
logic.c:1009–1032):若安规为VDE4105_11_18且 RRCR/EZA 使能,用远程百分比覆盖u8_max_feedin_percent;G100STATE3_FOBID_FEEDIN时馈网百分比强制 0;STATE4_LOCK时把逆变额定输入/输出功率都清 0。随后按(PV_Capacity_Grid + PV_Capacity_Storage) * 百分比 / 100得l_s32_maxfeedin_power,储能机侧单独按PV_Capacity_Storage计算l_s32_storage_feedin_power。 - CSIP-AUS(
logic.c:1035–1090):调csip_aus_der_control_process();u8_dercontrol != DER_NORMAL时自动置u8_dnsp_maxfeedin_priority_flag = TRUE;sys_limited_by_csip_judge()为真时若电网状态异常则降级为DER_CONTROL_DEFAULT并清Setup_Config_Extend2状态;再用csip_aus_get_exp_limit()对两个馈网值取小,用csip_aus_get_gen_limit()压低逆变额定输出功率;最后调logic_apparent_power_limit()。 - 电网取电限值链(
logic.c:1092–1118):CSIP + AS4777 时对csip_aus_get_imp_limit()(裕度 0)与配置s32_grid_power_limit(裕度 5)分别算单相电流取小;否则只用配置值。sys_grid_input_power_limit()输出经 §14a(get_enwg_bat_charge_limit())与sys_inv_grid_input_power_limit()三重取小,得到l_s32_inv_grid_input_power_limit。 - 充放电限值与电流限值(
logic.c:1123–1167):放电限值取允放时间段功率与并机最大放电能力的较小值;奥地利远程功率限制使能时按u8_wlv_percent缩放逆变额定输出功率;电池充电限值取并机最大充电能力与上一步限值的较小值;电池需加热(get_bat_heat_forbid_power_flag())时两者强制清零;电流限值 =功率 * 1000 / u16_bat_volt;最后u8_bat_status由 BMS 未 ready、逆变器无电池开警报、充放限值非零三者同时成立决定。
4.3 序列控制模式状态机:ongrid_logic_handle(logic.c:2189–2339)
判定部分是一条严格优先级 if-else 链,先命中先得(logic.c:2193–2285):
| 优先级 | 条件 | 得到模式 |
|---|---|---|
| 1 | get_generator_control_flag() == TRUE | GC_CECONTROL |
| 2 | bms_get_ready_enable() == TRUE | NO_BAT_CECONTROL |
| 3 | u8_self_test_charge != FALSE | SELF_TEST_CHARGE_MODE |
| 4 | sys_get_soc_calibration_flag() != FALSE | SOC_CALIBRATIONG_MODE(充电期直接 bat_force_charge(),放电期带 2000 tick 限速 bat_force_discharge()) |
| 5 | u8_cmd_force_charge != FALSE | CMD_FORCE_CHARGE_MODE |
| 6 | u8_sys_force_charge != FALSE | SYS_FORCE_CHARGE_MODE |
| 7 | u8_user_force_charge != FALSE | USER_FORCE_CHARGE_MODE |
| 8 | u8_bat_force_charge != FALSE | BAT_FORCE_CHARGE_MODE |
| 9 | u8_bat_power_control_flag == TRUE | DISPATCH_BAT_MODE |
| 10 | frequency_regulation_flag() == TRUE | DISPATCH_FREQ_MODE |
| 11 | get_dispatch_enable() == TRUE | DISPATCH_MODE |
| 12 | get_smart_control_mode() == TRUE | SMART_CONTROL_MODE |
| 13 | 以上都不满足 | 进入 logic_control_by_time(),再按 time_force_bat_feedin_flag → FORCE_BAT_FEEDIN_MODE、u8_time_peak_clip_flag/u8_time_valley_fill_flag → TIME_PEAK_SHAVING_MODE、time_force_charge_flag → TIME_FORCE_CHARGE_MODE、time_forbid_dischg_flag → TIME_FORBID_DISCHG_MODE、time_allow_discharge_flag → TIME_ALLOW_DISCHG_MODE,否则 SELFUSE_MODE |
logic_control_by_time() 只在第 13 级被调用,即存在任意更高优先级模式时,时间段类标志不会刷新。
执行部分是一个 switch(logic.c:2287–2338):GC_CECONTROL 空操作(注释说明改到逆变器任务内处理,见 calculate_gc_chgpower 由 inverter.c 调用)、NO_BAT_CECONTROL → no_bat_logic_control()、四种强充模式加 TIME_FORCE_CHARGE_MODE 合并走 bat_force_charge()、SELF_TEST_CHARGE_MODE → system_self_test()(定义在 logic/self_test.c:240)、DISPATCH_BAT_MODE → bat_power_control()、DISPATCH_FREQ_MODE → excute_frequency_regulation_command()、DISPATCH_MODE → excute_system_dispatch_command()、SMART_CONTROL_MODE → handle_smart_control_mode()、TIME_PEAK_SHAVING_MODE → time_peakshaving_command()、FORCE_BAT_FEEDIN_MODE / TIME_FORBID_DISCHG_MODE / TIME_ALLOW_DISCHG_MODE / SELFUSE_MODE 四种合并走 self_use_funtion()。
非并网时 other_logic_handle()(logic.c:2152)把 DC/AC 的总功率与三相不均衡设定值全部清零,保证下发功率为 0。
4.4 时间段控制:logic_control_by_time / logic_comparing_time_periods
logic_comparing_time_periods(week_day, start, end)(logic.c:1386)是唯一的通用时间段判定器:
- 周标记
week_day的 bit0~bit6 对应周日~周六;当前星期由g_t_sys_datetime.RTC_WeekDays左移得到l_system_week_day。 (week_day & 0x7F) == 0→ 返回 2(无效);周标记不匹配 → 返回 1(段外)。start < end视为不跨天,l_system_tick >= start && < end→ 0(段内)。start > end视为跨天,l_system_tick >= start || < end→ 0(段内)。start == end→ 返回 2(无效)。- 传入
0xFF表示每天有效(0xFF & 0x7F != 0,且与任意星期位相与都非零)。
logic_control_by_time(logic.c:1450)依次处理五组配置,全部结果直接刷进 g_t_logic_info:
- 强制电池馈网(
logic.c:1472–1504):u8_bat_time_feedin_en使能时遍历t_config_extend3_data的 6 个时间段,取第一段命中的截止 SOC 与功率;未使能时只把time_force_bat_feedin_flag置 FALSE。 - 削峰填谷(
logic.c:1507–1553):u8_peak_shaving_en使能时各判 2 段削峰(PeakStartTime1/2_minutes)与 2 段填谷(ValleyStartTime1/2_minutes),结果写入u8_time_peak_clip_flag/u8_time_valley_fill_flag,同时把峰值、谷值、回差值、放电截止 SOC 拷到运行态。 - 强充时间段(
logic.c:1558–1625):三种分支——旧版Time_Force_Chg_Enable(2 段,功率取parallel_read_system_max_charge_power_limit());新版weekday_charge_discahrge_en & 0x01(EXTEND1 + EXTEND2 各 14 段,功率/SOC 来自配置);都不满足则只清标志。旧版优先于新版(if / else if)。 - 允放/禁放时间段(
logic.c:1628–1728):同样是旧版(Time_Allow_Dischg_Enable,2 段)优先、新版(weekday_charge_discahrge_en & 0x02,EXTEND1+EXTEND2 各 14 段)其次。逻辑上「段内 →time_allow_discharge_flag」、「段外 →time_forbid_dischg_flag」,两者都不命中则都清(按自发自用处理)。
注意旧版路径的 time_allow_discharge_cut_soc 恒取 logic_read_ups_reserve_soc(),而新版取自配置条目的 discharger_cut_soc(logic.c:1661 vs logic.c:1721)。
4.5 并网取电限值的两个累加器
sys_grid_input_max_single_phase_cur(grid_power_limit, cur_margin)(logic.c:675):
l_s16_meter_max_single_phase_cur = (grid_power_limit * 10 / 230) / 3 - cur_margin * 10
下限 0
返回值单位为 0.1 A;公式里硬编码 230 V,把三相总功率折算到单相电流再扣 cur_margin(单位 A)。
sys_grid_input_power_limit(cur)(logic.c:692):先算电池最大允充功率 = min(电池额定充电功率, 逆变额定充电功率);TIME_FORCE_CHARGE_MODE 下改用 time_force_charge_grid_power + (PV 电表功率 + 逆变侧 PV 功率) 作为上限,否则用最大允充功率。单相取电功率按相数从 s32_pgrid_metera/b/c 取最大值,相电压取三相中最小且不小于 1000(即 100.0 V)的值,换算:
l_s32_meter_grid_max_single_phase_power_set = cur(0.1A) * volt(0.1V) / 100 // → W
然后按周期调节(CSIP ramp 生效时周期为 0,即每次都调;否则 5 s):
diff = (set - 实测单相功率) * 有效相数
|diff| < 100 ? g_s32_bat_charge_power_limit += 10 : g_s32_bat_charge_power_limit += diff
g_s32_bat_charge_power_limit 下限 10
最后取 min(该累加值, 电池最大允充功率)
sys_inv_grid_input_power_limit(logic.c:797):从逆变器侧取电能力反推上限,上限 = u16_overload_factor * s32_inv_rated_input_power / 100;若空开规格使能且未触发告警,再用 (storage_grid_breaker_specs - 5) * 相数 * s16_ugrida 取小;CSIP 模式下再与 csip_aus_get_load_limit() + s32_pbackupt 取小。累加规则与上者相似(周期 5 s,CSIP ramp 生效时 1 s;|diff| < 100 时按 diff / 3 步进),最后钳位到 [0, 电池最大允充功率],输出到 g_s32_bat_charge_power_inv_limit。
两者的累加器 g_s32_bat_charge_power_limit / g_s32_bat_charge_power_inv_limit 都是模块级可写全局(logic.c:74–75),且会在 DNSP ramp 分支里被改写(见 4.9)。
4.6 英国 G100 防逆流状态机:uk_g100_handle(logic.c:372–542)
前置条件:仅当安规为 G98 或 G99 且 g100_read_inv_type() == TRUE 时才运行;否则把运行态强制为 STATE1_NORMAL + OVER_STATE1_NOTH、清空 t_g100_info 并重置超限计时。l_u8_com_fault 由 g_ems_info 中逆变器/电网电表/PV 电表/BMS/并机从机/并机主机失联 6 位或运算得到;l_u8_over_flag = uk_g100_over_set_power()。
uk_g100_over_set_power(logic.c:312)的判据:以电表总功率 g_t_meter.t_grid_info.t_data.s32_actpower[PHASE_T] 为实测值,馈出限值 over_export = -(PV_Capacity_Grid + PV_Capacity_Storage) * u8_max_feedin_percent / 100;取入限值在 u8_grid_power_limit_enable 使能时为 s32_grid_power_limit / 3 * 有效相数,裕度 over_stand = max(|over_export|, over_import) * 2 / 100,判据是 P < over_export - stand || P > over_import + stand;未使能时判据退化为 P < over_export * 102 / 100。
状态迁移(持久化在 t_config_data.t_g100_info,因此掉电保留):
| 当前态 | 条件 | 迁移到 | 记录原因 |
|---|---|---|---|
STATE1_NORMAL | 超限 | STATE2_OVER_LIMIT | OVER_STATE2_0S_15S,记录 s_u32_tick_over_export |
STATE2_OVER_LIMIT | 恢复且持续超限 < 15 s | 回 STATE1_NORMAL | OVER_STATE1_NOTH,s_u32_tick_over_export 前移 |
STATE2_OVER_LIMIT | 恢复且持续超限 15 s–60 s | 回 STATE1_NORMAL | OVER_STATE2_15S_60S;同时把本次时间戳压入 u32_tick_state2[3] 环形表,并判 24 h 内≥3 次或 10 min 内≥2 次则直接进 STATE3_FOBID_FEEDIN(OVER_STATE3_15S_60S,置 s_u8_save_flag) |
STATE2_OVER_LIMIT | 持续超限 > 60 s | STATE3_FOBID_FEEDIN | OVER_STATE3_MORE60S,置 s_u8_save_flag |
STATE3_FOBID_FEEDIN | 30 天内 ≥3 次(s_u8_save_flag == 1 且与 u32_tick_state3[0] 间隔 ≤ 30 天) | STATE4_LOCK | OVER_STATE4_3TIMES_30D |
STATE4_LOCK | 无自动迁移 | 停留 | 需外部置 u8_uk_G100_RebootState != FALSE 才能复位(logic.c:496,会清空两组时间戳环形表并回 STATE1_NORMAL) |
default | 状态值非法 | STATE1_NORMAL | — |
通讯故障降级(logic.c:506):l_u8_com_fault 且当前处于 STATE1_NORMAL 或 STATE2_OVER_LIMIT 时,不写持久化状态,只把运行态 u8_uk_G100_SystemState 临时置为 STATE3_FOBID_FEEDIN、原因 OVER_STATE3_COM_FAULT。
6 级历史缓冲与补发(logic.c:518–541):s_u8_system_state_temp[6] / s_u8_system_reason_temp[6] 记录状态变化;当 get_info_status() & PREVENT_BACKFLOW_STATUS 未置位时,从索引 5 向下找到第一个非零历史项,写入 u8_uk_G100_SystemState_tmpva / u8_uk_G100_StateReason_tmpva(供云端报文补发),并置位 PREVENT_BACKFLOW_STATUS。每次状态变化都会 save_job_post(LOGIC_CONFIG_PAGE) 落盘。
G100 对控制的实际作用体现在 logic_sys_running_info_handle:STATE3_FOBID_FEEDIN → 馈网百分比置 0;STATE4_LOCK → 逆变额定输入/输出功率置 0(logic.c:1021–1029)。
4.7 德国 §14a EnWG:deu_14a_enwg_handle(logic.c:160–298)
总功率上限公式 enwg_device_limit_power()(logic.c:123):设备数 n = (电池是否充电 ? 1 : 0)+ 活动可控 EV 桩数。
n == 0 → 0
n >= 9 → 4200 + (n-1) * 0.45 * 4200
1 <= n <= 8 → 4200 + (n-1) * (0.9 - n*0.05) * 4200
(式中的 4200 是字面量,宏 ENWG_MIN_POWER 未被使用。)
是否真正生效(logic.c:194):u8_14a_enwg_enable == TRUE 且安规为 VDE4105_11_18 且 device_count > 0 三者同时成立。不成立时把 s32_bat_power_limit 与 s32_evc_power_limit 回退到基本限值并复位滤波器。
生效时的预算分配(logic.c:207–282):
- 对
s32_pgrid_metert做一阶 IIR 低通:初值直接取原始值,之后filt += (raw - filt) / 4(α = 1/4,任务 280 ms 周期下约 1 s 时间常数),得P_grid。 cap = enwg_device_limit_power();ev_max取活动可控桩上报的最大能力之和(未上报时回退到基本限值);地板ev_floor = 4200 * 活动桩数,bat_floor = 电池充电时的 §14a 保底功率。budget_ff = cap - P_grid + (EV 活动时的 EV 取电) + 电池充电需求;若budget_ff < cap则抬到cap,保证总地板不低于cap。ev_allow先取min(ev_floor, budget_ff),再允许增长到min(ev_max, budget_ff - bat_floor),最后不超过budget_ff。bat_allow = min(budget_ff - evc_for_budget, bat_basic_power),负值归 0;写入s32_bat_power_limit与s32_evc_power_limit。
EV 未活动时 evc_for_budget = 0,其取电视为不可控负载不计回预算。u8_14a_enwg_active 供 midware/evc/evc.c:891、midware/evc/evc_ii.c:1647/1823 通过 get_enwg_evc_power_limit() 做并机总额度限幅(get_14a_enwg_active 亦为对外接口)。
4.8 SOC 校准状态机
sys_get_soc_calibration_flag()(logic.c:1233)返回 u8_soc_calibration_charge_flag,即校准阶段:0 = 空闲/结束,1 = 校准充电,2 = 校准放电。
- 强制退出条件:
(SOC==0 && 最大充电功率==0)或油机使能 → 清空用户使能、指令标志与阶段,返回 FALSE。 - 触发:配置
u8_soc_calibration_info.u8_soc_calibration_en使能后,比较系统日期与「下次校准」年月日。若已过期:循环模式调calculation_next_calibration_time()跳过本次;单次模式把「下次」抄进「上次」。 - 进入校准:日期时间匹配(年月日相等且系统分钟数 > 下次校准分钟数)时,循环模式直接置开始标志;单次模式则要求「上次 ≠ 下次」(即未触发过)才置开始。
- 满足「到达时间」或「云端撤销校准指令」且当前阶段为 0 时:记录
u16_start_calibration_soc = 当前 SOC,阶段置 1,并估算u16_calibration_times = (容量*(1000-SOC)/1000 * 60 / 额定 AC 充电功率) * 2。 - 阶段 1 且
bms_read_max_charge_power() == 0(满充)→ 阶段置 2。 - 阶段 2 且满足「SOC ≤ 起始 SOC」或「SOC ≤ UPS 预留 SOC*10 + 4」或「最大放电功率 == 0」→ 校准结束,阶段归 0;循环模式算下次时间,单次模式记「上次校准时间」并落盘。
handle_logic_soc_calibration_tick()(logic.c:2447)是对非并网/油机工况的补充:清标志后,若因电网断开进入等待,则等满 OS_TICKS_PER_SEC * 20(20 s)再继续;随后若当前日期时间已过「下次校准」且逆变器不处于 cNormalMode,按循环/单次模式推进校准时间戳。calculation_next_calibration_time()(logic.c:1176)按 {31,28,...} 月表加 u16_calibration_cycle_days,年份能被 4 整除时 2 月为 29 天,跨月最多顺延 2 个月,年底进位到下一年。
4.9 CSIP-AUS / DNSP ramp 渐进限幅:dnsp_ramp_control_handle(logic.c:2779)
使能条件:sys_limited_by_csip_judge() == TRUE 且 csip_aus_get_ramp_enable() 非零;否则把首次进入时备份的 u32_calculation_interval 还原,清累积量与模式记录并返回。
基准对齐(rebase)触发点有三个:首次进入(s_saved_interval == 0xFFFFFFFF)、序列控制模式变化(s_last_sequencecontrol_mode 改变)、DER 控制模式变化(u8_dercontrol 改变)。rebase 内容:
- AC 侧(
logic.c:2634):逆变 ramp 起点 = 实测s32_pinvt;电池充电/放电 ramp 起点 = 当前设定限值。 - DC 侧(
logic.c:2759):馈网起点 = 实测电表功率s32_pgrid_metert;逆变起点 =s32_pinvt;电池起点 = 实测电池总功率s32_bat_total_power。
节拍:每周期把 delta_ms = 本次 tick - u32_calculation_dnsp_ac_dc_tick 累加进 s_accumulated_ms,不足 1000 ms 直接返回;超过则减 1000(保留余数以保持平均 1 s),然后以 max_delta = g_t_csip_aus_der_control.s32_ramp_rate_w_per_sec(负数归 0)为每秒步长执行一次 AC 与 DC ramp。
dnsp_ramp_ac_control_handle(step)(logic.c:2535):三项分别按「目标 − 旧值」的绝对值与步长比较,超过则按步长单向移动,否则直接取目标;移动后把 _old 与目标字段都更新为 ramp 值(即目标被 ramp 值覆盖,形成闭环渐进)。三项的步长规则:
- 逆变总功率:增减均按
step; - 电池充电限值、电池放电限值:增加按
step * 110 / 100,减少按step * 90 / 100。
最后若未并机,用 pvcharger_read_bat_max_charge_power() / max_dischg_power() 钳位;并机时用 parallel_read_system_max_charge_power_limit() / max_dischg_power_limit() 钳位。充电限值还会同步写回 g_s32_bat_charge_power_limit(logic.c:2568)。
dnsp_ramp_dc_control_handle(step)(logic.c:2668):逆变、馈网、电池三路都按 step 渐进(1.1/0.9 倍率那行在 logic.c:2721 被注释掉),电池 ramp 值取负后写入 g_s32_bat_charge_power_limit 与 g_s32_bat_charge_power_inv_limit(logic.c:2732–2733)。
读取侧的开关:所有 logic_read_dc_total_set_* / logic_read_ac_total_set_* 在 csip_aus_get_ramp_enable() && sys_limited_by_csip_judge() 成立时返回 *_ramp 字段,否则返回原始设定字段(logic.c:3124–3335)。
4.10 智能化(PV 超充)控制与光伏优先
get_smart_control_mode()(logic.c:2116):使能、起止时间不倒挂(start > end直接返回 FALSE,即不支持跨天)、当前处于时段内 → TRUE。周掩码传0x7F,即每天有效。handle_logic_smart_tick()(logic.c:2883):u8_ctrl_date != SYSTEM_DATETIME.bDays时更新日期、清u8_smart_control_en并落盘,实现「智能化控制配置单天有效」。handle_smart_control_mode()(logic.c:645):smart_control_status_detect按逆变器 PV 总功率与u32_pv_max_power比较,>= 阈值→STATE_OVERMATCH,否则STATE_NORMAL;两态分别走handle_smart_control_overmatch_state()(光伏优先)与handle_smart_control_normal_state()(SOC 达u8_charge_cutoff_soc * 10时清零充电限值后走自发自用)。- 光伏优先(
logic.c:1876–2014):pp_total_power_ac_control_state_handle的迁移判据 —— PV 有效且电池未使能 →PRIORITY_BAT_OPEN_WITH_PV_STATE;PV 有效、电池使能且电表在馈网(< -50 W)→ 若|电表功率|落在[馈网上限-200, 馈网上限+200]或逆变功率已达额定输出-100则PRIORITY_GRID_TRACK_BACKUP_BELOW_PV_STATE,否则PRIORITY_DEFAULT_STATE;PV 有效、取电且超过系统自耗 →PRIORITY_GRID_TRACK_BACKUP_OVER_PV_STATE;PV 无效 → 电表偏离零点或超过自耗为PRIORITY_GRID_TRACK_WITHOUT_PV_STATE,否则PRIORITY_GRID_ZERO_WITHOUT_PV_STATE。ac_control_total_power_photovoltaic_priority_calculate()用u32_calculation_ac_total_inv_tick与u32_calculation_interval限速。
4.11 Backup 与 EPO
backup_control_flag_handle()(logic.c:2422):先判断 BMS 工作状态与继电器状态,任一不满足直接返回;随后 ups_cutoff_wakeup_soc_control() 与 inv_backup_basic_protect(),最终 set_inverter_backup_enable(),且当本机标志或并机 backup 状态任一为 BACKUP_DISABLE 时禁止(取「或」,即任一禁止即禁止)。
ups_cutoff_wakeup_soc_control(logic.c:2383):仅当inverter_get_sys_ctrl_state()非零时生效。关断判据 =u8_load_cut_out_en使能且低 SOC ≤u8_cutoff_soc * 10,且离网(频率 < 4000,即 < 40.00 Hz)或电网故障;唤醒判据 =u8_load_cut_out_en未使能直接 TRUE,否则低 SOC ≥u8_wakeup_soc * 10;正常运行模式也可唤醒。inv_backup_basic_protect(logic.c:2348):以SOC * 容量 / 1000估算预留电量;BACKUP_ENABLE下若离网/故障且最大放电能力为 0 → 禁止;BACKUP_DISABLE下若回到cNormalMode或预留电量 ≥ 1000 且最大放电能力非 0 → 恢复;其余非法值一律置BACKUP_ENABLE。
EPO 用一个字节 u8_epo_config_en 承载两位:低半字节为使能(epo_read_config_enable 判 & 0x0F == 1),bit4 为保护标志(epo_set_protect_enable 先 &= 0xEF 再 |= value << 4)。epo_set_config_enable 在高半字节非零(保护激活)时直接 return,因此不会误清保护位。运行态短路信号 u8_epo_signal 只存内存、不落盘。
4.12 全局变量的读写与触发条件
| 变量 | 写入者(本文件) | 触发条件 | 读取者 |
|---|---|---|---|
g_t_logic_info.t_logic_control_parameter.* | logic_sys_running_info_handle(每周期全量刷新) | 系统控制态 + 并网/离网均执行 | DC/AC 控、inverter、parallel、net/ems |
g_t_logic_info.u8_sequencecontrol_mode | ongrid_logic_handle;other_logic_handle(非并网清 NOT_SEQUEN_CECONTROL);logic_set_sequencecontrol_mode(外部覆盖) | 每周期按优先级链重算 | logic/dispatch.c、midware/inverter/parallel.c、net/ems.c、hmi/ui/ui_main.c、EVC |
g_t_logic_info.s32_ac_*/s32_dc_* | 下游 DC/AC 控计算函数;other_logic_handle 清零;DNSP ramp 改写 | 模式分发执行时 | 逆变器任务、logic_read_* 接口 |
g_t_logic_info.time_force_bat_feedin_flag / u8_time_peak_clip_flag / u8_time_valley_fill_flag / time_force_charge_flag / time_forbid_dischg_flag / time_allow_discharge_flag | logic_control_by_time | 仅在 ongrid 优先级链落到第 13 级时 | ongrid_logic_handle 自身、logic_read_time_force_chg_flag(midware/bms/bms.c:2230) |
g_t_logic_info.t_config_data.t_g100_info.* | uk_g100_handle | G98/G99 + 专用机型;状态变化即 save_job_post(LOGIC_CONFIG_PAGE) | logic_sys_running_info_handle、云端报文 |
g_t_logic_info.u8_uk_G100_SystemState / _StateReason / _tmpva | uk_g100_handle | 每周期;通讯故障时临时降级 | logic_sys_running_info_handle、net/ems.c |
g_t_logic_info.s32_bat_power_limit / s32_evc_power_limit / u8_14a_enwg_active | deu_14a_enwg_handle | 每周期 | get_enwg_bat_charge_limit、get_enwg_evc_power_limit → EVC/EV_II |
g_t_logic_info.u8_soc_calibration_charge_flag 等 | sys_get_soc_calibration_flag、handle_logic_soc_calibration_tick | 每次调用 | ongrid_logic_handle 选模式 |
g_s32_bat_charge_power_limit | sys_grid_input_power_limit、dnsp_ramp_ac_control_handle | 5 s / 1 s 周期累加;DNSP ramp 直写 | sys_grid_input_power_limit 返回值链 |
g_s32_bat_charge_power_inv_limit | sys_inv_grid_input_power_limit、dnsp_ramp_dc_control_handle | 同上 | 同上 |
g_t_logic_info.u8_time_peak_clip_flag / u8_time_valley_fill_flag | logic_control_by_time | 削峰填谷使能时 | time_peakshaving_command |
5. 对外接口
5.1 导出的函数(在 logic.h 中声明,供外部调用)
调度类:task_system_logic_control(由 user/main.c:211 创建)、logic_charge_dischg_power_limit(logic/ac_control.c)、bat_force_charge / bat_force_discharge / self_use_funtion / no_bat_logic_control(logic/dispatch.c、logic/self_test.c)、calculate_gc_chgpower(midware/inverter/inverter.c)、logic_set_sequencecontrol_mode(midware/interface/modbus/sunspec_business.c、midware/inverter/parallel.c)。
读取类(消费方见括号):logic_read_sequencecontrol_mode(logic/dispatch.c、net/ems.c、midware/evc/*、midware/inverter/parallel*.c、hmi/ui/ui_main.c)、logic_read_mppt_percentage(parallel.c、parallel_sci.c)、logic_read_max_feedin_power(inverter.c)、logic_read_charger_cut_soc / logic_read_feedin_cut_soc / logic_read_peakshving_discharge_cut_soc(midware/evc/evc.c、evc_ii.c、parallel.c)、logic_read_ups_reserve_soc / logic_read_ups_reserve_flag / logic_read_allow_discharge_cut_soc / logic_read_user_charger_cut_soc / logic_read_gc_charger_cut_soc(同上)、logic_read_dc_total_set_* / logic_read_ac_total_set_* / logic_read_ac_three_phase_set_*(parallel.c、net/ems.c)、logic_read_time_force_chg_flag(midware/bms/bms.c)、logic_comparing_time(midware/bms/bms.c)、sys_limited_by_csip_judge(midware/interface/drm/drm.c、inverter.c)、get_maxfeedin_priority_flag(logic/dc_control.c、logic/dispatch.c)、sys_get_soc_calibration_flag、logic_read_grid_meter_connect。
EnWG:enwg_device_limit_power、deu_14a_enwg_handle、get_enwg_bat_charge_limit、get_enwg_evc_power_limit(后两个被 midware/evc/evc.c:891、evc_ii.c:1647/1823 使用)。
EPO:epo_set_config_enable(net/server.c:4966)、epo_read_config_enable(midware/interface/dry_node/dry_node.c、interface.c、net/ems.c:2150)、epo_set_protect_enable / epo_read_protect_enable / epo_read_signal_status(midware/interface/interface.c)、epo_set_signal_status(dry_node.c)。
其他导出但未在 logic.h 中声明(仅靠隐式声明或局部 extern 使用):logic_apparent_power_limit、get_14a_enwg_active、time_peakshaving_command、smart_control_status_detect、handle_smart_control_normal_state、handle_smart_control_overmatch_state、handle_smart_control_mode、pp_total_power_ac_control_state_handle、pp_total_power_ac_control、ac_control_total_power_photovoltaic_priority_calculate、photovoltaic_priority_funtion、get_smart_control_mode、other_logic_handle、inv_backup_basic_protect、ups_cutoff_wakeup_soc_control、handle_logic_soc_calibration_tick、handle_logic_smart_tick。
5.2 导出的全局变量
g_t_logic_info(LOGIC_TABLE_T,logic.c:34,logic.h:646 声明为 extern)、para_tables[LOGIC_CTROL_SPECIAL_MAX_COUNT](LOGIC_CONTROL_SPECIAL_HANDLE_T,logic.c:52,logic.h:647 声明)。
模块内部使用的可写全局(未在任何头文件声明 extern):g_s32_bat_charge_power_limit、g_s32_bat_charge_power_inv_limit、s32_set_inverter_setgradw、s32_old_set_inverter_setgradw。
5.3 本文件调用的外部函数/变量(按模块)
logic/logic.h自身:g_t_logic_info、logic_read_*系列。logic/dc_control.h:dc_control_total_power_limit、dc_control_three_phase_power_limit、dc_control_total_power_bat_force_charge/discharge、dc_control_three_phase_power_bat_force_charge/discharge、dc_control_total_power_bat_power_control、dc_control_total_power_self_use_calculate、dc_control_three_phase_power_self_use_calculate、dc_control_total_power_no_bat_calculate、dc_control_three_phase_power_no_bat_calculate、dc_control_total_power_gc_chgpower_calculate。logic/ac_control.h:ac_control_total_power_limit、ac_control_three_phase_power_limit、ac_control_time_peak_clip_command、ac_control_time_valley_fill_command、ac_control_total_power_bat_force_charge/discharge、ac_control_three_phase_power_bat_force_charge/discharge、ac_control_total_power_bat_power_control、ac_control_total_power_self_use_calculate_new、ac_control_three_phase_power_self_use_calculate、ac_control_total_power_no_bat_calculate、ac_control_three_phase_power_no_bat_calculate、ac_control_total_power_gc_chgpower_calculate。logic/dispatch.h:frequency_regulation_detection、dectect_api_dispatch_comm、frequency_regulation_flag、excute_frequency_regulation_command、get_dispatch_enable、excute_system_dispatch_command。logic/generator.h:generator_logic、get_generator_control_flag、get_generator_start_flag、get_generator_control_flag、SOC_MODE。logic/handle_priority.h:handle_priority_default_state、handle_priority_grid_track_backup_below_pv_state、handle_priority_grid_track_backup_over_pv_state、handle_priority_grid_track_without_pv_state、handle_priority_grid_zero_without_pv_state。logic/csip_aus.h:csip_aus_der_control_process、csip_aus_get_exp_limit、csip_aus_get_gen_limit、csip_aus_get_imp_limit、csip_aus_get_load_limit、csip_aus_get_ramp_enable、csip_aus_get_ramp_rate、g_t_csip_aus_der_control。logic/self_test.c/ 头文件:system_self_test、g_t_self_test。midware/inverter/inverter.h:inverter_read_safety、inverter_read_safety_is_AS4777、inverter_get_phase_number、inverter_get_special_control_inv_type、inverter_get_three_unbalance_mode、inverter_get_grid_breaker_specs_enable、inverter_get_ac_machine_min_charg_power、inverter_get_dc_disturbance_count、inverter_read_pv_power、inverter_read_grid_volt、inverter_read_grid_freq、inverter_read_grid_fault_flag、inverter_read_run_mode、inverter_read_backup_flag、inverter_get_sys_ctrl_state、inverter_read_rated_ac_charge_power、inverter_get_phase_number、get_inv_regulator_speed、get_inv_disturbance_flag、get_inv_calculation_interval、get_inv_power_calculation_time、get_inv_ac_power_fine_tuning_range、get_inv_dc_power_fine_tuning_range、get_inv_feedin_power_fine_tuning_range、get_14a_enwg_bat_min_power、g100_read_inv_type、get_storage_grid_air_switch_specs_state、set_inverter_backup_enable、VDE4105_11_18、G98、G99、cNormalMode、BACKUP_ENABLE/BACKUP_DISABLE、g_t_inv_info。midware/inverter/parallel.h:parallel_read_system_*(自耗、控制精度、补偿功率、maxfeedin 偏置、额定输入/输出/充/放功率、PV/电网状态、三相电压・功率・频率、PV 功率、电池功率电流电压 SOC、max_charge_power_limit、max_dischg_power_limit、inv_pv_power、inv_bat_curr、inv_bat_power、bat_rated_charge/dischg_power、bat_low_soc、system_self_test_flag、cmd/sys/bat/user_force_charge_flag、backup_en)、parallel_set_backup_en、get_bat_heat_forbid_power_flag。midware/meter/…(meter.h):meter_read_connect_status、meter_read_voltage、meter_read_actpower、meter_get_P1_lose_flag、g_t_meter、GRID_METER/PV_METER/PHASE_A/B/C/T。midware/bms/bms.h:bms_read_total_soc、bms_read_total_power、bms_read_battery_capacity、bms_read_max_charge_power、bms_read_max_dischg_power、bms_read_work_status、bms_read_relay_status、bms_get_ready_enable。midware/evc/evc.h/evc_ii.h:get_evc_enable_flag、get_evc_power_total、get_evc_ii_power_total、g_t_evc_run_info、g_t_evc_config_table、g_t_evc_ii_run_info、g_t_evc_ii_single_config、MAX_EVC_II_NUM、EVC_SPECIFIED_POWER、EVC_II_SPECIFIED_POWER、pvcharger_read_bat_max_charge_power/max_dischg_power。net/ems.h/net/:g_t_ems_info、get_info_status、set_info_status、PREVENT_BACKFLOW_STATUS、SENCOND_1S/5S/15S/60S。data/data.h/data/system_config/system_config.h:save_job_post、LOGIC_CONFIG_PAGE、Set_Setup_Config_Extend1_Status、Set_Setup_Config_Extend2_Status。midware/auxiliary/system_aux.h:SYSTEM_DATETIME、g_t_sys_datetime、get_rtc_tick。midware/interface/modbus/sunspec_business.h:sunspec_modbus_Wset_ena_get、sunspec_refresh_flag_get、sunspec_modbus_mppt_percentage_get。includes.h/debug.h/ uCOS-II:OSTimeGet、OSTimeDlyHMSM、OSTimeDlyResume、OSFlagPend、OSFlagPost、OS_TICKS_PER_SEC、g_t_fast_dispatch_flag(user/main.h:62)。
6. 依赖关系
6.1 依赖(本文件 include 或使用的外部模块)
logic.c:12–28 直接 include:logic.h、dc_control.h、ac_control.h、dispatch.h、generator.h、system_aux.h、inverter.h、meter.h、bms.h、ems.h、data.h、system_config.h、evc_ii.h、evc.h、csip_aus.h、handle_priority.h、sunspec_business.h。logic.h(logic.h:13–14)再引入 includes.h 与 debug.h,因此 uCOS-II 与全局类型由 includes.h 统一提供。
6.2 被依赖(哪些文件会用到它)
logic/:ac_control.c、dc_control.c、dispatch.c、generator.c、handle_priority.c、csip_aus.c、self_test.c(均 includelogic.h,并使用g_t_logic_info与logic_read_*)。midware/:inverter/inverter.c、inverter/parallel.c、inverter/parallel_comm/parallel_sci.c、各厂商*_comm_*.c、bms/bms.c、evc/evc.c、evc/evc_ii.c、meter/、interface/interface.c、interface/drm/drm.c、interface/dry_node/dry_node.c、interface/modbus/modbus.c、interface/modbus/sunspec_business.c、interface/modbus/sunspec_modbus.c、auxiliary/system_aux.c。net/:ems.c、server.c。data/:resume_data/flash/flash_data_store.c、system_config/system_config.c(读写LOGIC_CONFIG_PAGE系列 Flash 页)。hmi/:key.c、led.c、led/app_led.c、ui/ui_main.c、ui/ui_factory_mode.c、ui/ui_setting_user_func_grid_power_limit.c、ui/ui_setting_user_func_grid_pq_mode_export_ctrl.c、ui/ui_setting_user_func_work_mode_select.c、ui/ui_setting_user_fun_grid_force_charge.c。user/:main.c(创建任务)、main.h(事件标志组)。
7. 备注与风险点
- 未使用的宏:
ENWG_MIN_POWER(logic.c:36,值 4200)定义后从未引用,enwg_device_limit_power与deu_14a_enwg_handle直接写死字面量4200(logic.c:151、logic.c:250)。修改保底功率时容易漏改。 - 死变量:
s32_set_inverter_setgradw/s32_old_set_inverter_setgradw(logic.c:51)为全局定义,但全工程无任何位置引用(相关赋值在logic.c:1081的inverter_set_dnsp_rate()已被注释掉)。 - 声明但未定义的函数:
logic.h:698声明了uk_g100_state_change,全工程无定义,属遗留声明。 - 注释与实现不符(14a 闭环):
logic.c:187声明s32_pgrid_int(闭环积分)已被注释掉,但logic.c:209、logic.c:252、logic.c:273的注释仍在描述「前馈 + 积分修正」「积分消除植物超调」。当前实现只有 IIR 低通 + 前馈,没有积分项,注释会误导后续维护。 - 魔法数字代替标志位:
logic.c:2951用os_flag == 0x01判断,实际语义是POST_PEND_FAST_ENABLE(值 1),可用具名枚举提高可读性。 sizeof(time_t) * 3用于u32数组清零(logic.c:498、logic.c:500):目标字段是u32 u32_tick_state2[3]/u32_tick_state3[3],若time_t不是 4 字节则清零长度错误。应写sizeof(u32) * 3。- G100 历史队列移位异常(
logic.c:521–524):先写temp[0] = 新值,再memmove(&temp[1], &temp[0], 5),导致新值同时占据索引 0 与 1,真实历史被压缩一级(temp[4]被丢弃)。若期望「新值入队、旧值后移」,应先把移位放在赋值之前。 deu_14a_enwg_handle中ev1_chasts/ev1_runmode(logic.c:128–132)计算后未被使用,属残留代码。u8 i反向循环(logic.c:529):for (u8 i = 5; i >= 1; i--)依赖无符号数在i == 0时退出;写法可运行但极易被误改为i >= 0造成死循环。- SOC 校准触发条件的分组歧义(
logic.c:1252–1258):整个表达式是A || B || (C && 充电标志 != 0),u8_soc_calibration_charge_flag != 0只约束第三个分支(跨年月日之前的过期判断)。从上下文看「校准未开启才跳过本次」的语义应作用于全部过期分支,当前写法可能给出非预期行为。 logic_apparent_power_limit只单向限制(logic.c:343):当使能位从真变假时不会恢复被压低的s32_inv_rated_output_power(该字段每周期由parallel_read_system_rated_output_power()重填,因此实际可恢复,但依赖了外部重填,函数自身不自洽)。dnsp_ramp_*把 ramp 值直接写回目标字段(logic.c:2551、2567、2584、2701、2715、2731):目标变量被覆盖为渐进值,_old与目标同源,因此「目标」不再是外部期望值。若同时有其他模块写同一字段,会互相覆盖。g_s32_bat_charge_power_limit/g_s32_bat_charge_power_inv_limit双用途:既作为 4.5 节的增量累加器,又在 DNSP ramp 中被直接赋值(logic.c:2568、2732、2733)。两条路径共用同一变量,若 DNSP ramp 正在运行时 4.5 的累加仍在进行,二者会互相污染。且这两个全局未在头文件 extern 声明,属跨文件不可见的隐式状态。dnsp_ramp_dc_control_handle与 AC 版规则不一致:AC 版电池限值按 1.1 倍 / 0.9 倍渐进,DC 版的倍率计算被注释掉(logic.c:2721),而函数头注释仍写着「增加按 step*1.1,减少按 step*0.9」,注释与实现不一致。- Flash 写入频率:
uk_g100_handle在STATE2_OVER_LIMIT持续超限分支里每周期都会走到save_job_post(LOGIC_CONFIG_PAGE)(logic.c:444),且状态迁移、时间戳压栈也各自 post。长时间超限场景下对同一 Flash 页的写入频度值得关注。 sizeof(char)级隐式类型转换:logic_read_max_feedin_power()返回u32但源字段是s32(logic.c:3017);uk_g100_over_set_power返回u8但内部按s32计算再比较(logic.c:330)。负值/溢出语义依赖具体调用点。sys_grid_input_max_single_phase_cur中硬编码 230 V(logic.c:679):同文件的其他换算使用实测相电压(logic.c:750–755)。两者对 230 V/400 V 系统的换算基准不一致,低压或异常电压下估值会有偏差。other_logic_handle注释与定义不符(logic.c:2146写static void other_logic_handle(void),实际定义是全局void other_logic_handle(void)),属注释残留;同理logic.c:546的函数头注释把time_peakshaving_command写成「void ... (void)」,实际参数列表为空。- 跨任务数据共享无锁:本文件在逻辑任务中写入
g_t_logic_info,逆变器任务、并机任务、HMI 任务、网络任务均可并发读取;只有「快速调度」事件标志组约束了逻辑→逆变器的计算先后(4.1 节),并没有互斥保护,存在读到半更新结构(如 G100 状态与原因不成对、AC 设定功率与 ramp 值不一致)的窗口。 logic_read_sequencecontrol_mode()在本文件内被高频调用(如logic_sys_running_info_handle内多处)仅为读全局,无性能问题,但在同一函数内多次读取可能在极端时序下读到不同值。handle_logic_soc_calibration_tick的 20 s 等待只在Generator == TRUE或u8_grid_status == FALSE分支生效,且wait_flag/start_tick是函数静态变量,与同一支路的其他校准状态不存在一致性问题,但等待期间仍会执行后续的校准时间戳推进逻辑(logic.c:2483起的if未包含在return之后的 else 中,20 s 未到即return,因此实际被跳过——逻辑正确但分支结构较绕)。uk_g100_handle中memset(&t_g100_info, 0, ...)在非 G98/G99 时以每周期 280 ms 的频率清零(logic.c:385),同时把g_t_logic_info.u8_uk_G100_SystemState强制为STATE1_NORMAL,会掩盖掉上一周期诊断出的通讯故障态。- 条件编译双轨:本文件大量使用
#ifdef INV_DC_CTRL/INV_AC_CTRL(如logic.c:1744–1752),AC 自发自用改为调用ac_control_total_power_self_use_calculate_new()而旧函数被注释(logic.c:1861–1862),保留了新旧两套实现的痕迹。