EMS 知识库
首页 / knowledge/故障速查

EMS 故障分册(E0001 ~ E0094)

本页目录先看这 6 条(现场最容易踩的坑)零、先看懂这张位图(现场必须先懂这个)一、23 个"活位"逐条bit 0 | E0001 | EMS_FAULT_NET_FAULT | u8_net_faultbit 1 | E0002 | EMS_FAULT_RTC_FAULT | u8_rtc_faultbit 2 | E0003 | EMS_FAULT_EEPROM_FAULT | u8_eeprom_faultbit 3 | E0004 | EMS_FAULT_INV_LOST | u8_inv_lostbit 4 | E0005 | EMS_FAULT_GRID_METER_LOST | u8_grid_meter_lostbit 5 | E0006 | EMS_FAULT_PV_METER_LOST | u8_pv_meter_lostbit 6 | E0007 | EMS_FAULT_BMS_LOST | u8_bms_lostbit 7 | E0008 | EMS_FAULT_BAT_VOLT_LOW | u8_bat_volt_lowbit 8 | E0009 | EMS_FAULT_BACKUP_OVERLOAD | backup_overloadbit 9 | E0010 | EMS_FAULT_INV_SLAVE_LOST | inv_slave_lostbit 10 | E0011 | EMS_FAULT_INV_MASTER_LOST | inv_master_lostbit 11 | E0012 | EMS_FAULT_PARALLEL_COMM_ERROR | parallel_comm_errorbit 12 | E0013 | EMS_FAULT_PARALLEL_MODE_DIFFER | parallel_mode_differbit 13 | E0014 | EMS_FAULT_FLASH_FAULT | u8_flash_faultbit 14 | E0015 | EMS_FAULT_SDRAM_ERROR | u8_sdram_errorbit 15 | E0016 | EMS_FAULT_EXTENSION_CAN_ERROR | u8_extension_can_errorbit 16 | E0017 | EMS_FAULT_INV_TYPE_NOT_SPECIFIED | inv_type_not_specifiedbit 17 | E0031 | EMS_FAULT_INV_LOST_BAT_SHUTDOWN | u8_inv_lost_bat_shutdownbit 18 | E0032 | EMS_FAULT_SAMPLING_ANOMALY | sampling_anomalybit 19 | E0033 | EMS_FAULT_INV_SATUSE_ABNORMAL_BAT_SHUTDOWN | inv_satuse_abnormal_bat_shutdownbit 20 | E0034 | EMS_FAULT_PARALLEL_HOST_LOST | parallel_host_lostbit 21 | E0035 | EMS_FAULT_PARALLEL_FORM_LOST | parallel_form_lostbit 22 | E0036 | EMS_FAULT_PV_CHARGER_HOST_LOST | pv_charger_host_lostbit 23 | E0040 | EMS_FAULT_INV_INITIALIZATION_FAILED | inv_initialization_failedbit 24 | E0041 | EMS_FAULT_EPO_TRIGGER | epo_triggerbit 25 | E0042 | EMS_FAULT_WIFI_P1_PAIRING_FAULT | u8_wifi_P1_pairing_faultbit 26 | E0079 | EMS_FAULT_BAT_HEAT_FAULT | u8_bat_heat_faultbit 27 | E0085 | EMS_FAULT_AFCI_SELF_CHECK_FAULT | afci_self_check_faultbit 28 | E0092 | EMS_FAULT_BAT_MIXED_INSTALLATION_NUM_ERROR | u8_bat_mixed_installation_num_errorbit 29 | E0094 | EMS_FAULT_MID_METER_LOST | u8_mid_meter_lost二、死位(永不报)——7 个三、现场应该最先记住的几条规律四、不确定的地方(如实标注)五、维护

面向现场售后:报 E00xx 时查这里。共 30 个故障位。 需求号:REQ-001(K7)| 源码基准:V0.11.676(git 04e72700)| 定稿 2026-10-15 源码只读,全部结论来自逐行阅读,未修改任何 .c/.h。


先看这 6 条(现场最容易踩的坑)

  1. 有 7 个码在本版本固件里永远不会报 —— E0001 E0008 E0009 E0012 E0013 E0015 E0016。

看到这 7 个码说明固件版本与本分册不一致,别在当前代码里找它。详见 §二。

  1. 有 3 个码一旦出现就是永久锁存,只有断电/复位才消 —— E0014(Flash)、E0031(失联 12 h)、E0033(异常强制关机)。

代码里没有清除路径。看到「重启一次就没了」不要以为修好了。详见 §三 第 3 条。

  1. 机械不卖电很可能不是独立问题 —— 在英国 G100(G98/G99)安规下,

E0004 E0005 E0006 E0007 E0010 E0011 里任一个挂着,系统会被强制切成「禁止馈网」 (logic.c:390-395 聚合 → logic.c:506-511 切成 STATE3_FOBID_FEEDIN,原因码 OVER_STATE3_COM_FAULT)。 现场反馈"不卖电"时先查这 6 个码。

  1. "丢通讯"类故障门槛都在 15 s ~ 30 s,瞬断不会报;反过来报出来就说明已经断很久了。

而且离网/UPS、电网频率 < 45 Hz、断点续传/升级中这三种工况下,一部分码被故意设计成不报。 不报 ≠ 没坏。

  1. E0004(逆变器失联)报出来时,电量类数据会同时变 0 —— 这是 inverter.c:132-189 主动清零一大片

运行数据的连带现象,不是第二个故障。

  1. 屏幕上的码是 5 位数字:故障码 7 显示成 E00007,不是本分册写的 E0007(去掉补零即得)。

而且行首有没有 NO 是关键: E00007 NO. 1 表示故障正在发生, NO E00007 NO. 1 表示该故障已恢复。排查时只看没有 NO 的行。 注:行尾 NO. 后的数字对 EMS 码不是设备号 —— EMS 写日志时硬编码为 1 (data/fault_warn_log/fault_warn_log.c:556/560),只有 BMS 上报的码才按电池序号变化(:603)。 格式实现在 hmi/ui/ui_history_error_log.c:139-165。

本分册的每条结论都标注了 文件:行。提取完成后我又独立复核了其中最强结论(3 个锁存位的无清除路径、 G100 禁止馈网的聚合关系、以及 alphaess/锦浪/科陆 三家逆变器的失联阈值与置位点),全部与原文一致。 后来还从源码原文补出了第 6 条(屏幕显示格式),该格式不影响任何故障位判定,只影响现场读屏。


零、先看懂这张位图(现场必须先懂这个)

EMS 主控把自己判定的故障压在一个 32 位位图 EMS_FAULT_U 里(data/data.h:67-114), 只有 30 个位定义了含义(bit0 ~ bit29),高两位 bit30/bit31 是占位。

(index 就是 bit 位置,不是故障码值;value 非 0 置 1,为 0 清 0)

并写入故障日志(对照表在 fault_warn_log.c:518-549)

一个关键结论:位图没有任何"整体清零"的地方。 全工程搜不到 u_ems_fault.u32_all = 0 或对 g_t_ems_info 的 memset。所以只要某位置了 1 而代码里没有对应的清 0 分支,这个故障就会一直挂着, 直到主控断电或复位。本文件下面标注为「单向锁存」的三个位(bit13/bit17/bit19)就属于这种情况。

故障位恢复的响应速度取决于扫描它的任务周期,本文件逐个标出:

任务文件:行周期负责的位
task_invertermidware/inverter/inverter.c:118880 msbit3, bit16, bit22
task_inverter_canmidware/inverter/inverter.c:128530 msbit10, bit20, bit21
task_bmsmidware/bms/bms.c:2933100 msbit6, bit17, bit19, bit26, bit28
task_metermidware/meter/meter.c:5881300 msbit4, bit5, bit25, bit29
task_system_datadata/data.c:263(信号量超时 500)≈500 msbit2
task_system_auxmidware/auxiliary/system_aux.c:2092400 msbit1
task_interface_parsemidware/interface/interface.c:230500 msbit24
task_samplingmidware/meter/ct.c:844(ADC-DMA 信号量触发)随采样中断bit18
alphaess_inverter_comm_usart由 task_inverter 调,inverter.c:111680 msbit23

位图的一个下游影响(现场会看到"另一个症状"):logic/logic.c:390-395 把 E0004/E0005/E0006/E0007/E0010/E0011 这 6 个位或在一起,只要有一个为 1, 在 英国 G100 安规(u8_safety = G98/G99) 配置下就会把系统状态强制切成 STATE3_FOBID_FEEDIN(禁止馈网),状态原因 OVER_STATE3_COM_FAULT(logic.c:506-511)。 所以现场可能遇到「报一个通讯类故障 + 系统不给卖了」的组合,那不是两个独立问题。


一、23 个"活位"逐条

bit 0 | E0001 | EMS_FAULT_NET_FAULT | u8_net_fault

死位,永不报。 见文末「死位」一节。


bit 1 | E0002 | EMS_FAULT_RTC_FAULT | u8_rtc_fault

两者都在 rtc_refresh()(system_aux.c:341-380)内,由 task_system_aux 每轮调用一次(system_aux.c:2073,周期 400 ms)

的返回值不等于 0:

相当于读失败要有相当强的证据

回写给 RTC(pcf8563.c:1474-1476:PCF8563_SetDateTime() + return -2), 也就是芯片时间跑飞时主控会尝试纠回

现场注意:E0002 通常意味着 RTC 芯片通讯不良/晶振停振/电池没电,不是主控算错时间。


bit 2 | E0003 | EMS_FAULT_EEPROM_FAULT | u8_eeprom_fault

都在 eeprom_fault_handle()(data/data.c:211-242)内,由 task_system_data 每轮调用(data/data.c:308,≈500 ms)

(hardware/flash/feeprom.c:46/77/84/95/100)

  1. s_u32_eeprom_hardware_write_fault_flag——底层 Flash 擦/写失败

(hardware/flash/feeprom.c:163/194/250/269)

  1. s_u32_eeprom_software_read_fault_flag——某个配置页读出后 CRC/内容不对

(data/system_config/system_config.c 各 *_restore() 里大量调用,如 :1236/1286/1432/1596...)

  1. s_u32_eeprom_software_write_fault_flag——某个配置页写回失败

(system_config.c:120/166/246/281/.../3141) 每个标志位用 bit(页号 - SYSTEM_STARTE_PAGE) 记是哪一页出的问题(fault_warn_log.c:2077-2089)

如果某页只有"读失败"而没有"写失败",就认为它是临时坏值,主动把"读失败"标志清掉。 现场含义:偶尔闪一次的 E0003 会自动消失;一直挂着的 E0003 意味着某页真的写不进去了。


bit 3 | E0004 | EMS_FAULT_INV_LOST | u8_inv_lost

由 task_inverter 调用(inverter.c:1138),周期 80 ms

—— 该标志为 TRUE 就置 1,为 FALSE 就清 0(无条件跟随,无时长消抖)

→ 现场含义:E0004 只对贝瓦 / 锦浪 / 古瑞瓦特 / 汇川这 4 类逆变器有意义, 盛能杰、科陆机型下这个码不会因为"逆变器失联"而报(盛能杰另有 E0010 走内部错误位)

备电三相、电池电压/电流/功率等一大片运行数据全部清零,并把运行模式写成 cFaultMode。 所以报 E0004 时,App/屏幕上电量类数据同时变 0 是正常的连带现象,不是两个故障


bit 4 | E0005 | EMS_FAULT_GRID_METER_LOST | u8_grid_meter_lost

都在 meter_fault_handle()(meter.c:4539-4598)内,由 task_meter 调用(meter.c:5775),周期 300 ms

距上次读到 P1 数据 > 3000 ms 就置位,且明确排除下面三种情况不报: 正在做固件升级、断点续传中、逆变器处于 cUPS 模式(midware/ethernt/wireless/wireless_driver.c:621-627); 恢复正常则 wireless_driver.c:632 清 0

  1. 首次搜索不到电表:grid_meter_detect()(meter.c:605-647),连续 30 次找不到才进入判断

(每次搜索间隔 ≥ 1000 ms,宏 METER_DETECT_INTERVAL_TIME,meter.h:98 → 约 30 s), 且还要同时满足:非"离网未接市电"、且不是 cUPS 模式、且电网频率 ≥ 4500(45.00 Hz); 否则即使搜不到也不报(meter.c:626-640)

  1. 本来在通讯、后来断了:grid_meter_read_data()(meter.c:3075)里的连续失败计数 u8_lost_cnt

超阈值(meter.c:3622-3636):

然后走和路径 2 一样的并网/离网判断(meter.c:3652-3666)

  1. 无线 CT/电表:wireless_meter_handle_lost()(meter.c:5456-5476),判断条件同路径 2

meter.c:5806-5811,每 15 s 刷新一次数据,把丢失标志强制清 0

现场注意:离网(UPS/无市电)时不报电表丢失,这是设计如此,不是漏报。


bit 5 | E0006 | EMS_FAULT_PV_METER_LOST | u8_pv_meter_lost

未配 PV 电表时 meter.c:5866 强制清 0

现场注意:PV 侧是否报错,首先看有没有配"构网使能"。同一块表、同样断线,两种配置下 一个报 E0006、一个不报。


bit 6 | E0007 | EMS_FAULT_BMS_LOST | u8_bms_lost

都在 bms_comm_detect()(bms.c:56-69)内,由 task_bms 调用(bms.c:2756),周期 100 ms

注意:开机 60 s 内这个函数既不置位也不清零,位图保持原状

  1. g_t_bat_info.t_run_info.u8_connect == FALSE(电池通讯连接标志)
    1. pvcharger_read_machine_mode() != PVCHARGR_FROM_E(不是"被外部 PV 充电器主机接管"的模式)

清掉整块电池运行数据(bms.c:1133-1141)

现场注意:上电 60 s 内不会报 E0007。刚上电就找售后说"电池没了"要先等一分钟。


bit 7 | E0008 | EMS_FAULT_BAT_VOLT_LOW | u8_bat_volt_low

死位,永不报。 见文末「死位」一节。


bit 8 | E0009 | EMS_FAULT_BACKUP_OVERLOAD | backup_overload

死位,永不报。 见文末「死位」一节。


bit 9 | E0010 | EMS_FAULT_INV_SLAVE_LOST | inv_slave_lost

在 senergys5_get_error_waring_apping_table1()(set_comm_usart_s5.c:1059-1083)内, 该函数由 senergys5_query_inv_real_time_data1()(set_comm_usart_s5.c:3141)在解析逆变器实时数据后调用 (调用点 set_comm_usart_s5.c:3217)

—— s_u_senergys5_error_mapping_table.bit.u8_internal_comm_error。 该位的原始来源是逆变器寄存器 0x101E(Error message 1)的 bit2 (set_comm_usart_s5.c:3189 读入 word0;位定义 set_comm_usart_s5.h:527, 注释原文:Internal communication error(master to slave))

(set_comm_usart_s5.c:4390,在 senergys5_restart_dsp_handle() 内,set_comm_usart_s5.c:4320)

EMS 侧没有独立判据 —— 这一位是纯镜像

现场注意:报 E0010 时,故障根源在逆变器内部(主控 DSP 与从 DSP 之间),不在 EMS。 换 EMS 主板解决不了,要查逆变器。


bit 10 | E0011 | EMS_FAULT_INV_MASTER_LOST | inv_master_lost

都在 inverter_lost_handle_can()(inverter.c:199-221)内,由 task_inverter_can 调用(inverter.c:1270),周期 30 ms

现场注意:E0011 是 CAN 通道丢失,E0004 是 串口通道丢失,两者可能同时报(两条链路都断)。


bit 11 | E0012 | EMS_FAULT_PARALLEL_COMM_ERROR | parallel_comm_error

死位,永不报。 见文末「死位」一节。


bit 12 | E0013 | EMS_FAULT_PARALLEL_MODE_DIFFER | parallel_mode_differ

死位,永不报。 见文末「死位」一节。


bit 13 | E0014 | EMS_FAULT_FLASH_FAULT | u8_flash_fault

即系统备份参数区读不出来。该函数(system_config.c:2326-2361)的逻辑是: 从 SYSTEM_DATA_BACKUP_PAGE 连读 3 次,每次都要能读出、且 CRC 校验通过; 3 次都失败就调 system_backup_info_init() 重建备份并返回 FALSE

现场注意:E0014 出现即代表主控 Flash 里的系统备份区已损坏并被重建, 重建后 SN、逆变器型号等参数可能回到默认值,必须人工核对 SN 与机型配置。 而且这个故障会一直挂着直到重启,看到"重启后 E0014 消失"是预期行为。


bit 14 | E0015 | EMS_FAULT_SDRAM_ERROR | u8_sdram_error

死位,永不报。 见文末「死位」一节。


bit 15 | E0016 | EMS_FAULT_EXTENSION_CAN_ERROR | u8_extension_can_error

死位,永不报。 见文末「死位」一节。


bit 16 | E0017 | EMS_FAULT_INV_TYPE_NOT_SPECIFIED | inv_type_not_specified

—— 配的机型与固件编译的机型不一致,且固件不是"通吃"版本

g_t_inv_info.t_config_data.u8_inv_model,即储存在 Flash 里的机型配置; ≥ INVERTER_MAX(7) 的非法值会被当场改写成 INVERTER_NULL

现场注意:这是配置类故障,不是硬件故障。出现 E0017 先查机型配置有没有丢, 不要去拆线。⚠️ 另一个必须知道的坑见本文件末「不确定的地方」第 1 条。


bit 17 | E0031 | EMS_FAULT_INV_LOST_BAT_SHUTDOWN | u8_inv_lost_bat_shutdown

由 task_bms 调用(bms.c:2890),周期 100 ms

(该标志只在 system_config.c:108 的 system_sn_init() 里被置 TRUE, 并作为 FactoryFlag 参数注册给服务器,可由服务器下发改写 —— net/server.c:3944。实际含义是"还没走完出厂配置") 且从第一次检测到通讯丢失起连续 12 小时(bms.c:1256,12 * 60 * 60 * 1000)才置 1

(bms.c:1237-1245),也就是说:只有本来就是 0 的时候才写 0,一旦置 1 就再也清不掉 → 单向锁存。 只能靠断电/复位

现场注意:通讯短暂恢复过不要以为没事 —— 只有持续 12 小时不间断才置位, 而一旦置位就永久锁存。看到 E0031 说明这台机器至少失联过半天。


bit 18 | E0032 | EMS_FAULT_SAMPLING_ANOMALY | sampling_anomaly

都在 task_sampling(ct.c:844)的采样处理里,由 ADC-DMA 完成中断喂信号量触发

或 g_t_ct.t_grid_ct_info.t_ct_data.u16_ct_volt_a < 300

(判断整体在 ct.c:1095-1110)

实现细节:s_u32_sampling_anomaly_tick(ct.c:37)只在条件不成立时才刷新(ct.c:1109), 所以 abs(当前 - tick) > 2000 实际测的就是"这个异常已经连续持续多久"

采样率由 ct_sampling_init() 里 timer1_init(100, 167) 决定(ct.c:66,注释写"默认 100 Hz 100 个点")

现场注意:E0032 是"接了市电但 CT 侧采不到像样的电压/点数"。 代码里 300 这个数是 CT 内部量纲的原始判据,源码没有标注单位, 不要直接理解成 300 V。先查 CT 接线、CT 插头、CT 方向。


bit 19 | E0033 | EMS_FAULT_INV_SATUSE_ABNORMAL_BAT_SHUTDOWN | inv_satuse_abnormal_bat_shutdown

置位的同时会执行 bms_set_shutdown(TRUE) 强制电池关机

s_u32_battery_shut_down_tick 就被刷新(bms.c:1222),计时重新开始

(u8_relay_status 来自电池通讯,赋值见 midware/bms/alpha/battery_comm.c:1318)

现场注意:E0033 描述的是"电网掉了 + 母线没电 + 电池没有自己站起来 + 电池继电器还是合着的" 这种异常工况,属于保护性判定。一旦报出就是永久锁存,必须断电才能清。


bit 20 | E0034 | EMS_FAULT_PARALLEL_HOST_LOST | parallel_host_lost

方向:本机是并机系统中的"从机",报"找不到主机"

由 task_inverter_can 调用(inverter.c:1276),周期 30 ms

置位时还会把 u8_parallel_addr 清 0、u8_parallel_addr_en 置 FALSE、清空运行数据 (意味着要重新组网才能恢复)

现场注意:15 s 是一个比较宽松的门槛,短暂插拔通讯线不会立刻报。


bit 21 | E0035 | EMS_FAULT_PARALLEL_FORM_LOST | parallel_form_lost

方向:本机是"主机",报"有从机掉了"

g_t_host_machine_networking_info[i].u8_parallel_lost_flag != FALSE,本机即报 E0035 (循环在 parallel.c:1006-1012,用局部变量 l_u8_from_machine_lost 汇总)

置位同时把 u8_parallel_addr 清 0

现场注意:E0035 只告诉你"有从机丢了",不告诉你是哪一台。 哪一台要去看各自的从机地址/运行数据是否为零。


bit 22 | E0036 | EMS_FAULT_PV_CHARGER_HOST_LOST | pv_charger_host_lost

(pvcharger.c:159-250)内,由 task_inverter 调用(inverter.c:1168),周期 80 ms

每轮都直接写 TRUE 并刷新时间戳 —— 也就是说这个故障只在 PV 充电器被当成从机、 由外部主机(Host)通过逆变器来管的时候才可能报

并 memset 清空整块 PV 充电器数据

现场注意:普通单机不会报 E0036。报了先确认 PV 充电器模式配置。


bit 23 | E0040 | EMS_FAULT_INV_INITIALIZATION_FAILED | inv_initialization_failed

都在 alphaess_inverter_comm_usart()(alphaess_comm_usart.c:5090)内, 由 task_inverter 调用(inverter.c:1116),周期 80 ms

该标志在 alphaess_comm_usart.c:119 等处置 TRUE)

  1. 距初始化开始 > 3000 ms(alphaess_comm_usart.c:5106)
    1. 此时调用 system_start_first_setting()(alphaess_comm_usart.c:3685-3716)仍然返回 FALSE

该函数依次做三件事,任一失败即 FALSE: query_inv_function_enable_data_alphaess() → query_inv_safety_actpower_setting() → query_inv_quiescent_volt_reactpower_support()

并把 u8_inv_parameter_init_flag 置 FALSE(alphaess_comm_usart.c:5108-5113)

初始化没成功之前,后面的通讯流程整段被跳过 —— 这是个"卡住"的故障

现场注意:E0040 通常伴随逆变器整机不受控/数据不刷新(因为 return 把后续流程跳过了)。 根因一般是逆变器侧参数写不进去(通讯质量、逆变器本身未就绪、安规参数不匹配)。


bit 24 | E0041 | EMS_FAULT_EPO_TRIGGER | epo_trigger

都在 epo_control_handle()(interface.c:139-202)内,由 task_interface_parse 调用(interface.c:225),周期 500 ms

且 EPO 端子信号有效(epo_read_signal_status() == TRUE) → 置 1 + epo_set_protect_enable(TRUE) + 进入 EPO_SEND_SHUTDOWN 状态

→ 依然置 1(此时是为了配合"重新开机"流程)

(interface.c:191-197)。也就是说只有"EPO 恢复 → 重新开机成功"这一条路能清掉

—— 这段只在 ALPHAESS_TYPE 编译分支下存在

现场注意:E0041 = 有人按了急停 / 急停回路断开了。这是人为或接线问题,不是设备故障。 复位方式:把急停恢复,等系统自动走"重新开机"流程;开机成功才清码。


bit 25 | E0042 | EMS_FAULT_WIFI_P1_PAIRING_FAULT | u8_wifi_P1_pairing_fault

midware/meter/meter.c:7047(写 1)、meter.c:7043(写 0),函数是 meter_set_grid_wifi_P1_fault()(meter.c:7039-7049)

但通信棒不支持 P1 —— 需同时满足 u8_wifi_support_P1_falg == TRUE 且 无线类型是 E_LINKER_WIFI 或 E_LINKER_4G。 任一不满足 → 置 1 并 return(注释写明"WIFI 不适配 P1 此时再发 P1 的 AT 指令会影响设备上线")

  1. wireless_driver.c:596-605:读 P1 的 AT 指令连续失败。

计数 s_u8_timeout_count 在 <= 15 时递增,超过 15(即第 17 次仍失败)→ 置 1

同时把 s_u8_timeout_count 归 0

  1. 未匹配的其他情况不写(保持原值)

或 UART 被占用时直接 return,wireless_driver.c:484)

主控与通信棒之间的配对/适配问题,不是电表本身坏

现场注意:报 E0042 时电表数据也不会上来(因为通信棒压根读不到 P1)。 先确认通信棒型号/固件是否支持 P1,再怀疑电表。


bit 26 | E0079 | EMS_FAULT_BAT_HEAT_FAULT | u8_bat_heat_fault

fault_warn_log.c:2151(写 0),函数是 set_bat_heat_fault_flag()(fault_warn_log.c:2147-2157)

(进入该态的判据在 bms.c:2591-2596:BMS 报过热码、或报加热故障码、或电池连接检查异常; 另一条在 bms.c:2576-2580:加热超过 9000 ms 未见效)

  1. bms.c:1828:bat_heat_fault_drop_out()(bms.c:1814-1838)"加热异常退出"流程的第 2 步,

即第 1 步下发停加热指令后、超过 3100 ms 时写入

且电池连接正常

bms_read_heat_fault_code())、电池连接检查 bat_bat_connet_check()、加热继电器状态 u8_heat_relay_sta

现场注意:E0079 报出来之后不会马上消失,最少要挂 10 分钟;而且恢复机会用满 3 次后 系统就不再自动恢复了。冬天现场遇到,多半是 加热膜/加热继电器/电池温度传感器 方向。


bit 27 | E0085 | EMS_FAULT_AFCI_SELF_CHECK_FAULT | afci_self_check_fault

另有一个外部清除入口 midware/inverter/inverter.c:7980(inverter_set_afci_self_check_clear(0), 在 inverter.c:7975-7983)

且错误计数 s_u8_err_cnt > 3(即已经失败 4 次)时置 1(afci_comm.c:720-728), 同时置 u8_afci_self_result_shut_down = TRUE(停机)

且 query_afci_warning_message() 为真,则清 0 并把 u8_afci_self_check_result 置 TRUE

  1. inverter.c:7980:外部调用 inverter_set_afci_self_check_clear(0) 时清 0

(afci_comm.c:685,(OSTimeGet() - u32_ems_afci_self_check_tick) > 8*1000)

调用入口在 alphaess_comm_usart.c:5060(afci_self_check_handle())

现场注意:报 E0085 时机器是停机状态(u8_afci_self_result_shut_down = TRUE)。 自检失败 4 次才报,所以柜台看到这个码,基本可以认定 AFCI 模块或它的通讯有问题。


bit 28 | E0092 | EMS_FAULT_BAT_MIXED_INSTALLATION_NUM_ERROR | u8_bat_mixed_installation_num_error

都在 get_bat_mixed_installation_num_error_flag()(bms.c:3375-3395)内, 由 task_bms 调用(bms.c:2927),周期 100 ms

TYPE_SMILE_M_BAT_13_9P_1 或 TYPE_SMILE_M_BAT_13_9P_2 完全一致(bms.c:3377-3378)

  1. get_risk_of_system_installation_plan() == TRUE

—— 该函数(inverter.c:8066-8079)只在"机型 = 盛能杰 SET_TYPE 且 子型号 = SUB_M10"时返回 TRUE

  1. 电池数量超限:
    • 混装标志为 0(新老电池混装)时:bms_read_num() > 2(超过 2 块)
      • 混装标志为 1(全新电池)时:bms_read_num() > 3(超过 3 块)

(bms.c:3381-3382)

u8_bat_mixed_installation_flag(读取接口 bms_read_mixed_installation_flag(),bms.c:3364)

现场注意:这是安装方案合规性告警,不是硬件坏。 含义是"这套 M10 + 13.9P 电池的方案,电池数量配超了"。⚠️ 前提 2 的实现见 本文件末「不确定的地方」第 2 条。


bit 29 | E0094 | EMS_FAULT_MID_METER_LOST | u8_mid_meter_lost

都在 meter_fault_handle() 内

g_t_meter.t_mid_info.u8_comm_lost_err == TRUE → 置 1

(调用节流 METER_DETECT_INTERVAL_TIME = 1000 ms → 约 30 s), 置位同时清运行数据;搜到一次就清 0(meter.c:1164)

  1. mid_meter_read_data()(meter.c:4273):连续 u8_lost_cnt > METER_LOST_MAX_CNT(15 次)

无有效响应 → 清数据 + 置丢失(meter.c:4330-4340)

现场注意:没装 MID 电表、或功能没开,永远不会有 E0094。


二、死位(永不报)——7 个

全工程对这 7 个位的位域名做了全文检索(.c + .h),除了 data/data.h 里的定义行, 零命中。 也没有任何 ems_set_fault_bit(0/7/8/11/12/14/15, ...) 调用 (已逐个列出全工程 42 处 ems_set_fault_bit( 的实参,出现的索引集合恰为 {1,2,3,4,5,6,10,13,16,17,18,19,20,21,22,23,24,27,28,29} 共 20 个, 加上直接写位域的 bit9/bit25/bit26,合计 23 个活位)。

bit故障码枚举名位域名
0E0001EMS_FAULT_NET_FAULTu8_net_fault
7E0008EMS_FAULT_BAT_VOLT_LOWu8_bat_volt_low
8E0009EMS_FAULT_BACKUP_OVERLOADbackup_overload
11E0012EMS_FAULT_PARALLEL_COMM_ERRORparallel_comm_error
12E0013EMS_FAULT_PARALLEL_MODE_DIFFERparallel_mode_differ
14E0015EMS_FAULT_SDRAM_ERRORu8_sdram_error
15E0016EMS_FAULT_EXTENSION_CAN_ERRORu8_extension_can_error

说明: 这 7 个位的码表登记是完整的(fault_warn_log.c:519-534 里都有映射, 所以日志系统认得它们、理论上能记录),但当前 V0.11.676 版本没有任何代码路径会把它们置 1, 因此现场永远不会在屏幕上/App 上看到这 7 个码。 要么是历史遗留(比如 bit8 backup_overload 的同类逻辑已经迁到别的结构体上, midware/inverter/ginlong/ginlong_comm_usart.c:999 用的是 ginlong 自己结构体里的同名位域, 跟 EMS 位图无关),要么是给后续版本预留的位置。 排查时不要在这 7 个码上浪费时间。


三、现场应该最先记住的几条规律

  1. **"丢通讯"类故障(E0004/E0005/E0006/E0007/E0010/E0011/E0034/E0035/E0036/E0094)

的门槛都在 15 s ~ 30 s 级别**,瞬断不会报;反过来报出来就说明已经断了相当久,不要用"刚插拔了一下线"解释。

  1. 离网(UPS)状态、电网频率 < 45 Hz、断点续传/升级中 这三种情况会让

E0004/E0005/E0006/E0094 中的一部分故意不报(例如 meter.c:3652-3666、 meter.c:4076-4089、wireless_driver.c:621-627)。不报 ≠ 没坏,要结合现场工况看。

  1. E0014(Flash)、E0031(失联 12 h 后的强制关机)、E0033(异常工况强制关机)三个码一旦出现就是永久锁存,

代码里没有清除路径,只有断电/复位才能消。看到"重启一次就没了"不要以为是好了。

  1. E0010(从机丢失)的根因在逆变器内部(主从 DSP 之间),EMS 只是把逆变器上报的位抄过来,

属于纯镜像;E0042(WIFI 不适配 P1)的根因在通信棒与 P1 电表的配对,不是电表坏。

  1. E0003 附带自愈:只有"读失败、后续写成功"的页会被主动清标志,所以闪一下就消失的 E0003 可以观察,

一直挂着的才要处理。

  1. 英国 G100(G98/G99)配置下,任意一个通讯类故障都会导致禁止馈网

(logic.c:390-395 聚合 6 个位 → logic.c:506-511 切成 STATE3_FOBID_FEEDIN,原因码 OVER_STATE3_COM_FAULT)。 现场如果反馈"机器不卖电了",先查这 6 个码有没有一个挂着。


四、不确定的地方(如实标注)

  1. 编译期机型宏 INVERTER_TYPE 在本明文基线里等于 INVERTER_NULL(0)

(midware/inverter/inverter.h:172,git 04e72700 提交内容一致;user/EMS_3_0.uvprojx 里 也没有任何 INVERTER_TYPE 的编译期宏定义)。 这会影响两处结论:

按字面读,只要 u16_oem_flag != OEM_HHE,E0017 就永远挂着 —— 这显然不是实际出货行为

整个实现包在 #if ((INVERTER_TYPE == INVERTER_MAX) || (INVERTER_TYPE == SET_TYPE)) 里, 按字面读会恒返回 FALSE,E0092 永远不报 → 我的判断是:这份明文快照的 inverter.h 机型宏很可能不是实际发货固件所用的值 (实际应是 INVERTER_MAX,即"通吃"版本,因为 inverter.c 里到处是 #if ... || (INVERTER_TYPE == INVERTER_MAX) 加运行时 get_inverter_type() 判断的写法)。 但我没有证据(platform-ems-3-6/ 是加密二进制、不可读),所以本文件里这两条 我都按"字面条件 + 现场实际含义"两条都写了,没有替哪个结论下判断。 建议后续用一个能确认机型宏的渠道核实一次,再定稿。

  1. bit19/E0033 的第二个条件 inverter_get_bat_breaker_statuse() == 2

我只是照代码写了"逆变器报告电池断路器状态 = 2",没有去追这个 2 在逆变器协议里代表什么 (是"断开"还是"异常")。如果要写进定稿给现场用,建议再查一次逆变器协议文档。

  1. bit18/E0032 里的 u16_ct_volt_a < 300

源码没有标注这个量的单位(同文件 cal_grid_vol() 里也没有注释)。 我按原文写了数值 300,没有换算成伏特。定稿前不要替它加单位。

  1. u8_factory_flag(bit17/E0031 的条件之一)

它只在 system_config.c:108 的 system_sn_init() 里被置 TRUE,另作为 FactoryFlag 参数注册给服务器(net/server.c:3944),可被下发改写。 我在代码里没有找到把它置 FALSE 的自动逻辑,所以"什么时候算出厂完成"这一点我没有查清, 只写了"实际含义是还没走完出厂配置"这个推断,请以推断看待。

  1. 所有"任务周期"数字

来自各任务循环末尾的 OSTimeDlyHMSM() 实参(如 inverter.c:1188 的 80、meter.c:5881 的 300)。 task_system_data 那一行是 OSSemPend(g_t_power_down_sem, 500, &err)(data/data.c:263), 我按 500 个 OS tick 记为"≈500 ms",没有去核对系统 tick 频率。 其余任务有 OSTimeDlyHMSM 直接给毫秒,是确定的。


五、维护

grep -rn "ems_set_fault_bit" --include="*.c" platform-ems-3-6-plain/ 快速重定位。