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

logic.c

源文件路径: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_activestatic统计处于 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_powerstatic判断电表功率是否超过英国 G100 规定的馈出/取入限值(含 2% 裕度)
logic_apparent_power_limit全局逆变视在功率限制:仅在 AS4777 安规下允许使能,使能后压低 s32_inv_rated_output_power
uk_g100_handlestatic英国 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_curstatic由电网侧功率限值反算单相最大输入电流(0.1 A 单位,减 cur_margin 裕度)
sys_grid_input_power_limitstatic电网侧取电限值的增量式 PI 型累加器,周期 5 s(CSIP ramp 下 1 s),输出累积到 g_s32_bat_charge_power_limit
sys_inv_grid_input_power_limitstatic由逆变器市电侧过载系数、空开规格、CSIP 负载限值反算电池从 AC 端取电的功率上限,累加到 g_s32_bat_charge_power_inv_limit
logic_sys_running_info_handlestatic系统数据总采集:把逆变器/电池/电表/并机的数百项数据搬进 t_logic_control_parameter,再计算馈网限值、充放电限值、电流限值、电池使能标志
calculation_next_calibration_timestatic按配置周期天数推算下一次 SOC 校准年月日(含闰年与跨月),并 post Flash 保存
sys_get_soc_calibration_flag全局SOC 校准状态机(0 空闲 / 1 校准充电 / 2 校准放电),返回当前校准阶段
logic_comparing_time_periodsstatic时间段判定:返回 0 段内、1 段外、2 无效,支持跨天与周日~周六位掩码
logic_control_by_timestatic处理全部时间段类配置(强制馈网、削峰填谷、强充、允放/禁放),把结果刷进 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_handlestatic序列控制模式状态机:优先级链判定 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_handlestaticBackup 控制总入口:先 SOC 控制再基础保护,最后 set_inverter_backup_enable(与并机 backup 状态取或)
handle_logic_soc_calibration_tick全局非并网/油机工况下 SOC 校准的补偿处理:等待 20 s 后按循环/单次模式推进校准时间
dnsp_ramp_ac_control_handlestaticAC 侧 DNSP ramp 渐进限幅:逆变总功率按 step,电池充/放限值增按 step*1.1、减按 step*0.9,并做 BMS/并机上限钳位
dnsp_ramp_ac_rebase_to_real_powerstaticAC ramp 基准对齐:逆变以 s32_pinvt 为起点、电池以当前限值为起点,重置 ramp tick
dnsp_ramp_dc_control_handlestaticDC 侧 DNSP ramp 渐进限幅:逆变/馈网/电池三路均按 step 渐进(1.1/0.9 倍率被注释掉)
dnsp_ramp_dc_rebase_to_real_powerstaticDC ramp 基准对齐:以电表功率、s32_pinvt、电池总功率为起点
dnsp_ramp_control_handlestaticDNSP 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)

任务体是一个无限循环,每个周期依次做四件事:

  1. 等待快速调度标志: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 计算不受软定时限速而立即执行。
  2. 周期采集与决策:仅当 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 调度/油机都会改写模式标志。

  1. 次任务:handle_logic_soc_calibration_tick()、handle_logic_smart_tick()、backup_control_flag_handle()(logic.c:2943–2945),这三个不受系统控制态限制。
  2. 交棒:若本周期拿到了快速调度标志(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)

这是全文件的信息枢纽,顺序为:

4.3 序列控制模式状态机:ongrid_logic_handle(logic.c:2189–2339)

判定部分是一条严格优先级 if-else 链,先命中先得(logic.c:2193–2285):

优先级条件得到模式
1get_generator_control_flag() == TRUEGC_CECONTROL
2bms_get_ready_enable() == TRUENO_BAT_CECONTROL
3u8_self_test_charge != FALSESELF_TEST_CHARGE_MODE
4sys_get_soc_calibration_flag() != FALSESOC_CALIBRATIONG_MODE(充电期直接 bat_force_charge(),放电期带 2000 tick 限速 bat_force_discharge())
5u8_cmd_force_charge != FALSECMD_FORCE_CHARGE_MODE
6u8_sys_force_charge != FALSESYS_FORCE_CHARGE_MODE
7u8_user_force_charge != FALSEUSER_FORCE_CHARGE_MODE
8u8_bat_force_charge != FALSEBAT_FORCE_CHARGE_MODE
9u8_bat_power_control_flag == TRUEDISPATCH_BAT_MODE
10frequency_regulation_flag() == TRUEDISPATCH_FREQ_MODE
11get_dispatch_enable() == TRUEDISPATCH_MODE
12get_smart_control_mode() == TRUESMART_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)是唯一的通用时间段判定器:

logic_control_by_time(logic.c:1450)依次处理五组配置,全部结果直接刷进 g_t_logic_info:

  1. 强制电池馈网(logic.c:1472–1504):u8_bat_time_feedin_en 使能时遍历 t_config_extend3_data 的 6 个时间段,取第一段命中的截止 SOC 与功率;未使能时只把 time_force_bat_feedin_flag 置 FALSE。
  2. 削峰填谷(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 拷到运行态。
  3. 强充时间段(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)。
  4. 允放/禁放时间段(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_LIMITOVER_STATE2_0S_15S,记录 s_u32_tick_over_export
STATE2_OVER_LIMIT恢复且持续超限 < 15 s回 STATE1_NORMALOVER_STATE1_NOTH,s_u32_tick_over_export 前移
STATE2_OVER_LIMIT恢复且持续超限 15 s–60 s回 STATE1_NORMALOVER_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 sSTATE3_FOBID_FEEDINOVER_STATE3_MORE60S,置 s_u8_save_flag
STATE3_FOBID_FEEDIN30 天内 ≥3 次(s_u8_save_flag == 1 且与 u32_tick_state3[0] 间隔 ≤ 30 天)STATE4_LOCKOVER_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):

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 = 校准放电。

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 内容:

节拍:每周期把 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 值覆盖,形成闭环渐进)。三项的步长规则:

最后若未并机,用 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 超充)控制与光伏优先

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 时禁止(取「或」,即任一禁止即禁止)。

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_modeongrid_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_flaglogic_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_handleG98/G99 + 专用机型;状态变化即 save_job_post(LOGIC_CONFIG_PAGE)logic_sys_running_info_handle、云端报文
g_t_logic_info.u8_uk_G100_SystemState / _StateReason / _tmpvauk_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_activedeu_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_limitsys_grid_input_power_limit、dnsp_ramp_ac_control_handle5 s / 1 s 周期累加;DNSP ramp 直写sys_grid_input_power_limit 返回值链
g_s32_bat_charge_power_inv_limitsys_inv_grid_input_power_limit、dnsp_ramp_dc_control_handle同上同上
g_t_logic_info.u8_time_peak_clip_flag / u8_time_valley_fill_flaglogic_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 本文件调用的外部函数/变量(按模块)

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 被依赖(哪些文件会用到它)

7. 备注与风险点

  1. 未使用的宏:ENWG_MIN_POWER(logic.c:36,值 4200)定义后从未引用,enwg_device_limit_power 与 deu_14a_enwg_handle 直接写死字面量 4200(logic.c:151、logic.c:250)。修改保底功率时容易漏改。
  2. 死变量:s32_set_inverter_setgradw / s32_old_set_inverter_setgradw(logic.c:51)为全局定义,但全工程无任何位置引用(相关赋值在 logic.c:1081 的 inverter_set_dnsp_rate() 已被注释掉)。
  3. 声明但未定义的函数:logic.h:698 声明了 uk_g100_state_change,全工程无定义,属遗留声明。
  4. 注释与实现不符(14a 闭环):logic.c:187 声明 s32_pgrid_int(闭环积分)已被注释掉,但 logic.c:209、logic.c:252、logic.c:273 的注释仍在描述「前馈 + 积分修正」「积分消除植物超调」。当前实现只有 IIR 低通 + 前馈,没有积分项,注释会误导后续维护。
  5. 魔法数字代替标志位:logic.c:2951 用 os_flag == 0x01 判断,实际语义是 POST_PEND_FAST_ENABLE(值 1),可用具名枚举提高可读性。
  6. 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。
  7. G100 历史队列移位异常(logic.c:521–524):先写 temp[0] = 新值,再 memmove(&temp[1], &temp[0], 5),导致新值同时占据索引 0 与 1,真实历史被压缩一级(temp[4] 被丢弃)。若期望「新值入队、旧值后移」,应先把移位放在赋值之前。
  8. deu_14a_enwg_handle 中 ev1_chasts / ev1_runmode (logic.c:128–132)计算后未被使用,属残留代码。
  9. u8 i 反向循环(logic.c:529):for (u8 i = 5; i >= 1; i--) 依赖无符号数在 i == 0 时退出;写法可运行但极易被误改为 i >= 0 造成死循环。
  10. SOC 校准触发条件的分组歧义(logic.c:1252–1258):整个表达式是 A || B || (C && 充电标志 != 0),u8_soc_calibration_charge_flag != 0 只约束第三个分支(跨年月日之前的过期判断)。从上下文看「校准未开启才跳过本次」的语义应作用于全部过期分支,当前写法可能给出非预期行为。
  11. logic_apparent_power_limit 只单向限制(logic.c:343):当使能位从真变假时不会恢复被压低的 s32_inv_rated_output_power(该字段每周期由 parallel_read_system_rated_output_power() 重填,因此实际可恢复,但依赖了外部重填,函数自身不自洽)。
  12. dnsp_ramp_* 把 ramp 值直接写回目标字段(logic.c:2551、2567、2584、2701、2715、2731):目标变量被覆盖为渐进值,_old 与目标同源,因此「目标」不再是外部期望值。若同时有其他模块写同一字段,会互相覆盖。
  13. 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 声明,属跨文件不可见的隐式状态。
  14. dnsp_ramp_dc_control_handle 与 AC 版规则不一致:AC 版电池限值按 1.1 倍 / 0.9 倍渐进,DC 版的倍率计算被注释掉(logic.c:2721),而函数头注释仍写着「增加按 step*1.1,减少按 step*0.9」,注释与实现不一致。
  15. Flash 写入频率:uk_g100_handle 在 STATE2_OVER_LIMIT 持续超限分支里每周期都会走到 save_job_post(LOGIC_CONFIG_PAGE)(logic.c:444),且状态迁移、时间戳压栈也各自 post。长时间超限场景下对同一 Flash 页的写入频度值得关注。
  16. sizeof(char) 级隐式类型转换:logic_read_max_feedin_power() 返回 u32 但源字段是 s32(logic.c:3017);uk_g100_over_set_power 返回 u8 但内部按 s32 计算再比较(logic.c:330)。负值/溢出语义依赖具体调用点。
  17. sys_grid_input_max_single_phase_cur 中硬编码 230 V(logic.c:679):同文件的其他换算使用实测相电压(logic.c:750–755)。两者对 230 V/400 V 系统的换算基准不一致,低压或异常电压下估值会有偏差。
  18. 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)」,实际参数列表为空。
  19. 跨任务数据共享无锁:本文件在逻辑任务中写入 g_t_logic_info,逆变器任务、并机任务、HMI 任务、网络任务均可并发读取;只有「快速调度」事件标志组约束了逻辑→逆变器的计算先后(4.1 节),并没有互斥保护,存在读到半更新结构(如 G100 状态与原因不成对、AC 设定功率与 ramp 值不一致)的窗口。
  20. logic_read_sequencecontrol_mode() 在本文件内被高频调用(如 logic_sys_running_info_handle 内多处)仅为读全局,无性能问题,但在同一函数内多次读取可能在极端时序下读到不同值。
  21. 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,因此实际被跳过——逻辑正确但分支结构较绕)。
  22. 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,会掩盖掉上一周期诊断出的通讯故障态。
  23. 条件编译双轨:本文件大量使用 #ifdef INV_DC_CTRL / INV_AC_CTRL(如 logic.c:1744–1752),AC 自发自用改为调用 ac_control_total_power_self_use_calculate_new() 而旧函数被注释(logic.c:1861–1862),保留了新旧两套实现的痕迹。