可正常使用版本,代价是5V比较慢

chore: 完成充电控制软件多项功能迭代与优化

1. 修改chrg.uvprojx,开启调试前更新Flash
2. 新增协议回码等待状态,注释掉协议优先于CC的测试流程
3. 启用南向寄存器写命令调试日志
4. 重构Sink工作状态机,拆分关机流程为多阶段等待
5. 新增主继电器0V持续掉电保护功能
6. 优化南向单次量测队列管理,修复多通道低电流确认异常
7. 调整电压稳定确认逻辑,为5V目标增加更长确认窗口
8. 移除软恢复相关状态与逻辑,简化状态流转
This commit is contained in:
wrh
2026-08-10 16:28:19 +08:00
parent 03b313d9fe
commit 52c59395a8
16 changed files with 403 additions and 198 deletions
+19 -17
View File
@@ -2348,6 +2348,7 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch,
rt_uint8_t old_cv_mode = pReal->CV_mode;
rt_uint16_t old_loadv = pReal->sink.loadv;
rt_uint16_t old_loadc = pReal->sink.loadc;
rt_uint8_t old_on_work = pReal->sink.On_work;
rt_uint8_t old_work_mode = pReal->sink.work_mode;
rt_uint16_t sink_work = pShadow->sink.Now_State;
chrg_param_diff_t diff_info;
@@ -2383,11 +2384,13 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch,
}
pReal->sink.test.test_mode_old = curr_test;
} else {
/* Protocol-before-CC test flow is disabled in this version. */
pReal->sub = IDX_SET_SINK_CC_BEFORE_PD;
pReal->sink.work_mode = SINK_WORK_INIT;
}
} else if (pReal->sink.On_work == 0) {
pReal->sink.On_work = 1;
/* Protocol-before-CC test flow is disabled in this version. */
pReal->sub = IDX_SET_SINK_CC_BEFORE_PD;
pReal->sink.work_mode = SINK_WORK_INIT;
} else if (full_handshake_change) {
@@ -2398,6 +2401,7 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch,
* 仅协议变化时不重复设置未变化的CC。
*/
if (diff_info.cc_changed && protocol_data_changed) {
/* Protocol-before-CC test flow is disabled in this version. */
pReal->sub = IDX_SET_SINK_CC_BEFORE_PD;
} else if (diff_info.cc_changed) {
pReal->sub = IDX_SET_SINK_CCLINE;
@@ -2414,8 +2418,6 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch,
pReal->sub = IDX_SET_SINK_PD_ONLY;
if (old_work_mode == SINK_WORK_LOAD_STANDBY) {
pReal->sink.work_mode = SINK_WORK_WAIT;
} else if (old_work_mode == SINK_WORK_LOAD_SOFT_STANDBY) {
pReal->sink.work_mode = SINK_WORK_SOFT_RESUME_WAIT;
} else {
/* 运行状态修改协议参数时保持继电器,只停止电子负载。 */
pReal->sink.work_mode = SINK_WORK_PROTOCOL_UNLOAD;
@@ -2432,7 +2434,20 @@ static eMBException chrg_comm_apply_sink_effect(rt_uint8_t ch,
}
} else {
pReal->sink.On_work = 0;
pReal->sink.work_mode = SINK_WORK_STOP;
/* 组合控制或上位机重发可能在关机尚未完成时再次提交OFF。
* 此时必须保留当前停止阶段,不能重新进入STOP并清零低电流确认次数,
* 否则实际电流即使一直为0,也永远累计不到连续5帧。 */
if ((old_work_mode == SINK_WORK_STOP_WAIT) ||
(old_work_mode == SINK_WORK_STOP_RELAY) ||
(old_work_mode == SINK_WORK_STOP_RELAY_WAIT)) {
pReal->sink.work_mode = old_work_mode;
} else if ((old_on_work == 0U) &&
(old_work_mode == SINK_WORK_WAIT)) {
/* 已完成停止时重复OFF保持WAIT,不重复操作继电器。 */
pReal->sink.work_mode = SINK_WORK_WAIT;
} else {
pReal->sink.work_mode = SINK_WORK_STOP;
}
}
return (chrg_sink_work((eIDX_SOU_CH)ch, pReal) == 0) ?
@@ -2463,8 +2478,7 @@ static rt_bool_t chrg_comm_handle_sink_load_current(
}
should_start = chrg_sink_load_should_start(pReal);
if ((old_work_mode == SINK_WORK_RUNING) ||
(old_work_mode == SINK_WORK_SOFT_RUNNING)) {
if (old_work_mode == SINK_WORK_RUNING) {
if (!should_start) {
pReal->sink.work_mode = SINK_WORK_LOAD_STOP;
return RT_TRUE;
@@ -2484,18 +2498,6 @@ static rt_bool_t chrg_comm_handle_sink_load_current(
return RT_TRUE;
}
if (old_work_mode == SINK_WORK_LOAD_SOFT_STANDBY) {
if (should_start) {
/*
* 软待机恢复同样必须先读取北向实际电压。
* 电压稳定后由解析流程进入SOFT_RESUME,再下发目标电流和WORK_START。
*/
pReal->sub = IDX_GET_SINK_VC;
pReal->sink.work_mode = SINK_WORK_SOFT_RESUME_WAIT;
}
return RT_TRUE;
}
/* 协议握手期间禁止把低于门限的小电流提前写入南向功率板。 */
return should_start ? RT_FALSE : RT_TRUE;
}
+32 -17
View File
@@ -29,8 +29,10 @@
#define SOURCE_QC_MIN_VOLT_MV 5000U // QC2.0/QC3.0允许使用的最低目标电压
#define SOURCE_QC_SWITCH_ERROR 0x04U // Source协议或CC切换失败错误位
#define SINK_CURRENT_START_GRACE_MS 200U // Sink启动后暂不判断无电流的保护时间
#define SINK_VOLT_STABLE_ERROR_MV 2000U // Sink实际电压与协议目标电压的最大允许误差
#define SINK_VOLT_STABLE_CONFIRM_COUNT 3U // Sink连续有效稳定电压帧数达到此值后进入RUNING
#define SINK_VOLT_STABLE_ERROR_MV 2000U // Sink实际电压与协议目标电压的最大允许误差
#define SINK_VOLT_5V_TARGET_MV 5000U // VSafe5V目标电压,需延长稳定确认时间
#define SINK_VOLT_CONFIRM_NORMAL_COUNT 5U // 非5V目标连续有效电压确认帧数
#define SINK_VOLT_CONFIRM_5V_COUNT 15U // 5V目标连续有效电压确认帧数,避免把握手阶段VSafe5V误判为协议稳定
/*****************************************************************
函数名称: chrg_source_apply_protocol_voltage_rule
@@ -82,6 +84,22 @@ static rt_bool_t chrg_sink_voltage_is_stable(rt_uint16_t actual_volt_mv,
RT_TRUE : RT_FALSE;
}
/*****************************************************************
函数名称: chrg_sink_voltage_confirm_count
函数描述: 根据Sink协议目标电压选择进入RUNING前所需的连续稳定帧数
输入参数: target_volt_mv:当前协议申请的目标电压,单位mV
输出参数: -
返回说明: 5V目标返回延长确认帧数,其它目标返回普通确认帧数
其它说明: 快充协议切换时总线会先经过VSafe5V;当目标本身也是5V时,
单凭电压值无法区分过渡阶段和协议稳定阶段,因此增加确认时间,
防止电子负载提前启动后导致协议板复位
*****************************************************************/
static rt_uint8_t chrg_sink_voltage_confirm_count(rt_uint16_t target_volt_mv)
{
return (target_volt_mv == SINK_VOLT_5V_TARGET_MV) ?
SINK_VOLT_CONFIRM_5V_COUNT : SINK_VOLT_CONFIRM_NORMAL_COUNT;
}
/*****************************************************************
函数名称: chrg_source_voltage_control
函数描述: 根据目标电压与实际电压统一控制Source电压下发和重试
@@ -225,6 +243,7 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
struct chrg_switch_t *pSW, struct chrg_north_t *pNOR)
{
rt_uint16_t volt_mv = ((frame_data[4] << 8) | frame_data[5]) * 10;
rt_uint8_t stable_confirm_count;
static rt_uint8_t volt_low[TOTAL_SOU_CHS] = {0};
static rt_uint8_t no_curr[TOTAL_SOU_CHS] = {0};
static rt_uint8_t volt_set_ok[TOTAL_SOU_CHS] = {0};
@@ -234,6 +253,8 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return;
}
stable_confirm_count = chrg_sink_voltage_confirm_count(
pSW->sink.pro_loadv);
pSW->VZ = ((frame_data[14] << 8) | frame_data[15]);
pSW->VF = ((frame_data[16] << 8) | frame_data[17]);
@@ -246,10 +267,10 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
if (volt_mv <= WORK_MIN_VOLT) { // 电压过低,禁止进入工作状态机
volt_stable_count[idx] = 0;
if (volt_set_ok[idx] == 1) {
if (++volt_low[idx] >= 20) {
if (++volt_low[idx] >= 50) {
volt_set_ok[idx] = 0;
no_curr[idx] = 0;
pSW->sink.work_mode = SINK_WORK_LOW;
//pSW->sink.work_mode = SINK_WORK_LOW;
}
}
}
@@ -273,25 +294,19 @@ void chrg_sink_parse(rt_uint8_t *frame_data, eIDX_SOU_CH idx,
else if (chrg_sink_voltage_is_stable(volt_mv,
pSW->sink.pro_loadv)) {
if ((pSW->sink.work_mode != SINK_WORK_RUNING) &&
(pSW->sink.work_mode != SINK_WORK_SOFT_RUNNING) &&
(pSW->sink.work_mode != SINK_WORK_LOAD_STANDBY) &&
(pSW->sink.work_mode != SINK_WORK_LOAD_SOFT_STANDBY)) {
if (volt_stable_count[idx] < SINK_VOLT_STABLE_CONFIRM_COUNT) {
(pSW->sink.work_mode != SINK_WORK_LOAD_STANDBY)) {
if (volt_stable_count[idx] < stable_confirm_count) {
volt_stable_count[idx]++;
}
if (volt_stable_count[idx] >= SINK_VOLT_STABLE_CONFIRM_COUNT) {
/* 回码已经过CRC、ID、命令和配置版本校验;首帧达到目标
* 电压附近后立即进入RUNING,不再增加额外稳定等待。 */
if (volt_stable_count[idx] >= stable_confirm_count) {
/* 回码已经过CRC、ID、命令和配置版本校验,并连续达到当前
* 目标对应的确认帧数;5V采用更长窗口过滤VSafe5V过渡阶段。 */
volt_stable_count[idx] = 0;
pSW->sink.work_mode =
((pSW->sink.work_mode == SINK_WORK_SOFT_RESUME_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_LOAD_RESUME)) ?
SINK_WORK_SOFT_RESUME : SINK_WORK_RUNING;
pSW->sink.work_mode = SINK_WORK_RUNING;
running_start_tick[idx] = rt_tick_get();
no_curr[idx] = 0;
}
} else if ((pSW->sink.work_mode == SINK_WORK_LOAD_STANDBY) ||
(pSW->sink.work_mode == SINK_WORK_LOAD_SOFT_STANDBY)) {
} else if (pSW->sink.work_mode == SINK_WORK_LOAD_STANDBY) {
/* 协议保持在线但电子负载主动停止,不执行无电流重试。 */
volt_stable_count[idx] = 0;
no_curr[idx] = 0;
+1 -1
View File
@@ -26,7 +26,7 @@
#define NORTH_SOURCE_DEBUG 0x00 // Source协议解析及组帧
#define NORTH_SINK_DEBUG 0x00 // Sink协议解析及组帧
#define SOUTH_FRAME_DEBUG 0x00 // 南向UART原始收发帧
#define SOUTH_COMMAND_DEBUG 0x00 // 南向寄存器写命令
#define SOUTH_COMMAND_DEBUG 0x01 // 南向寄存器写命令
#define COMM_FRAME_DEBUG 0x00 // COM UART原始收发帧
#define COMM_DEBUG 0x00 // COM寄存器读写过程
#define COMM_TRIM_DEBUG 0x00 // COM校准参数解析
+34 -18
View File
@@ -82,7 +82,6 @@ static rt_bool_t chrg_roll_nor_sink_query_is_slow(
}
return (pSW->sink.work_mode == SINK_WORK_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_INIT_AUX_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_SOFT_RESUME_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_LOW_MONITOR);
}
@@ -283,6 +282,13 @@ static rt_bool_t chrg_roll_nor_sink_wait_process(rt_uint8_t ch,
}
bit = SOURCE_CHANNEL_BIT(ch);
/* 关机必须先完成南向低电流确认和继电器批次,期间禁止北向发送。 */
if ((pSW->sink.work_mode == SINK_WORK_STOP_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_STOP_RELAY) ||
(pSW->sink.work_mode == SINK_WORK_STOP_RELAY_WAIT)) {
return RT_TRUE;
}
if ((pSW->id != ID_SINK) || !pSW->sink.On_work) {
g_sink_cc_wait_mask &= (rt_uint8_t)~bit;
g_sink_cc_wait_start[ch] = 0U;
@@ -297,18 +303,16 @@ static rt_bool_t chrg_roll_nor_sink_wait_process(rt_uint8_t ch,
return RT_TRUE;
}
/*
* 完整握手批次最后发送FU_REL_ON。批次完成并建立量测基线后,
* 允许北向协议/CC与南向低电流确认并行;当sub进入GET_SINK_VC
* 而状态仍为HANDSHAKE_WAIT时,说明低电流确认尚未完成,禁止发送0x20。
*/
/* 协议或CC切换必须先完成低电流确认;该过程保持南向继电器状态不变。 */
if (pSW->sink.work_mode == SINK_WORK_HANDSHAKE_WAIT) {
if (!chrg_sink_handshake_north_ready((eIDX_SOU_CH)ch)) {
return RT_TRUE;
}
if (pSW->sub == IDX_GET_SINK_VC) {
return RT_TRUE;
}
return RT_TRUE;
}
/* D0回码确认后先经过一个非发送状态,禁止把协议回码当成量测回码。 */
if (pSW->sub == IDX_WAIT_SINK_PD_ACK) {
pSW->sub = IDX_GET_SINK_VC;
chrg_roll_nor_sink_query_wait_start(ch);
return RT_TRUE;
}
if ((pSW->sub != IDX_WAIT_SINK_CC) &&
@@ -605,6 +609,9 @@ static rt_uint8_t chrg_roll_nor_expected_cmd(const struct chrg_switch_t *pSW)
return SINK_CMD_GET_PD;
case IDX_SET_SINK_PD:
case IDX_SET_SINK_PD_ONLY:
#if 0
case IDX_SET_SINK_PD_BEFORE_CC:
#endif
return pSW->sink.protocol;
case IDX_SET_SINK_CCLINE:
case IDX_SET_SINK_CC_BEFORE_PD:
@@ -822,12 +829,18 @@ static int chrg_roll_nor_set(rt_uint8_t ch, struct chrg_switch_t *pSW,
case IDX_SET_SINK_CCLVL: //CC电平
return sink_set_cc_lvl(pSW->sink.cc_lvl);
case IDX_SET_SINK_PD:
/* CC已经在协议前完成设置,协议回码后直接查询电压。 */
*next_sub = IDX_GET_SINK_VC;
/* 只有协议回码确认后,下一轮才允许进入电压查询。 */
*next_sub = IDX_WAIT_SINK_PD_ACK;
return chrg_roll_nor_sink_pro_set(pSW);
case IDX_SET_SINK_PD_ONLY:
*next_sub = IDX_GET_SINK_VC;
*next_sub = IDX_WAIT_SINK_PD_ACK;
return chrg_roll_nor_sink_pro_set(pSW);
#if 0
case IDX_SET_SINK_PD_BEFORE_CC:
/* 协议回码确认后再设置CC,不提前查询电压。 */
*next_sub = IDX_SET_SINK_CCLINE;
return chrg_roll_nor_sink_pro_set(pSW);
#endif
default:
return -1;
}
@@ -1014,9 +1027,12 @@ void chrg_roll_nor_thread_entry (void *data)
(pSW->sink.work_mode == SINK_WORK_INIT_AUX_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_UNLOAD_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_LOW) ||
(pSW->sink.work_mode == SINK_WORK_LOW_AUX_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_HANDSHAKE_PREPARE) ||
(pSW->sink.work_mode == SINK_WORK_HANDSHAKE_WAIT))) {
(pSW->sink.work_mode == SINK_WORK_LOW_AUX_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_HANDSHAKE_PREPARE) ||
(pSW->sink.work_mode == SINK_WORK_HANDSHAKE_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_STOP_WAIT) ||
(pSW->sink.work_mode == SINK_WORK_STOP_RELAY) ||
(pSW->sink.work_mode == SINK_WORK_STOP_RELAY_WAIT))) {
state_work_ret = chrg_sink_work((eIDX_SOU_CH)idx, pSW);
}
/*
@@ -52,6 +52,10 @@ enum {
IDX_WAIT_SINK_CC, // CC设置应答后的非阻塞稳定等待
IDX_SET_SINK_CC_BEFORE_PD, // 先设置CC,稳定后再设置协议
IDX_WAIT_SINK_CC_BEFORE_PD, // 等待CC稳定后进入协议设置
IDX_WAIT_SINK_PD_ACK, // 协议回码确认后的非发送过渡状态
#if 0
IDX_SET_SINK_PD_BEFORE_CC, // 先设置协议,协议回码后再设置CC
#endif
};
struct chrg_rollnor_t {
+17 -5
View File
@@ -29,7 +29,11 @@
#define SOU_CHANNEL_BIT(ch) ((rt_uint8_t)(1U << (ch)))
chrg_rollsou_com_t g_sou_com_batch = {0};
static rt_uint8_t g_sou_measure_once_mask = 0U;
/* 一次性P1量测分别记录待发送请求和正在等待回码的请求。
* 当前帧尚未结束时再次申请的下一帧保存在pending中,不能被当前帧
* 的完成处理清除,否则多通道运行时低电流确认会间歇性停止推进。 */
static rt_uint8_t g_sou_measure_once_pending_mask = 0U;
static rt_uint8_t g_sou_measure_once_active_mask = 0U;
struct chrg_rollsou_t chrgrollsou = {
.run = RUN_AUTO,
@@ -223,7 +227,7 @@ int chrg_sou_measure_once_submit(eIDX_SOU_CH ch)
rt_tick_from_millisecond(SOU_MUTEX_TIMEOUT_MS)) != RT_EOK)) {
return -1;
}
g_sou_measure_once_mask |= SOU_CHANNEL_BIT(ch);
g_sou_measure_once_pending_mask |= SOU_CHANNEL_BIT(ch);
rt_mutex_release(pTHR->mutex);
return 0;
}
@@ -247,7 +251,13 @@ static int sou_measure_once_next(rt_uint8_t *ch)
return -1;
}
for (idx = 0; idx < TOTAL_SOU_CHS; idx++) {
if ((g_sou_measure_once_mask & SOU_CHANNEL_BIT(idx)) != 0U) {
rt_uint8_t bit = SOU_CHANNEL_BIT(idx);
if ((g_sou_measure_once_pending_mask & bit) != 0U) {
/* 发送前从pending转移到active。查询等待期间的新申请会重新
* 置pending位,并在当前查询结束后继续执行。 */
g_sou_measure_once_pending_mask &= (rt_uint8_t)~bit;
g_sou_measure_once_active_mask |= bit;
*ch = idx;
rt_mutex_release(pTHR->mutex);
return 1;
@@ -274,7 +284,8 @@ static void sou_measure_once_finish(rt_uint8_t ch)
rt_tick_from_millisecond(SOU_MUTEX_TIMEOUT_MS)) != RT_EOK)) {
return;
}
g_sou_measure_once_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch);
/* 只结束当前正在等待的查询;等待期间登记的下一帧pending请求必须保留。 */
g_sou_measure_once_active_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch);
rt_mutex_release(pTHR->mutex);
}
@@ -607,7 +618,8 @@ int chrg_sou_com_batch_cancel(eIDX_SOU_CH ch)
pBatch->reg_cnt = 0;
pBatch->next_send_tick = 0U;
/* 已取消事务对应的优先P1量测同样失效,后续状态会重新申请新量测。 */
g_sou_measure_once_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch);
g_sou_measure_once_pending_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch);
g_sou_measure_once_active_mask &= (rt_uint8_t)~SOU_CHANNEL_BIT(ch);
rt_mutex_release(pTHR->mutex);
return 0;
}
+188 -128
View File
@@ -22,16 +22,29 @@
#define SINK_UNLOAD_QUERY_INTERVAL_MS 20U // 卸载期间两次优先量测请求的最小间隔
#define SINK_UNLOAD_CURRENT_MAX_MA 200U // 判定负载已安全卸载的最大实际电流
#define SINK_UNLOAD_CONFIRM_COUNT 2U // 连续满足低电流条件的量测帧数
#define SINK_CLOSE_CURRENT_MA 1000U // 安全关闭阶段写入功率板的电流设定值
#define SINK_UNLOAD_CONFIRM_COUNT 5U // 连续满足低电流条件的量测帧数
/* 主继电器闭合跟踪:1=已提交ALL_REL_ON(主继电器应已闭合) 0=未闭合/已断开。
* 用于0V硬保护区分"首次开载/握手恢复"(主继电器未闭合,Now_voltage=0属正常)
* 与"运行或待机中主继电器已闭合但输入电压为0"(协议板断电窗口,禁止开载)。 */
static rt_uint8_t g_sink_rel_main_closed[TOTAL_SOU_CHS] = {0};
/* 主继电器电压到位确认:1=提交闭合后实测电压已到达工作下限,继电器确认闭合。
* 持续0V监控只对已到位通道生效,避免继电器动作期间(电压尚未建立)误触发掉电保护。 */
static rt_uint8_t g_sink_rel_main_ready[TOTAL_SOU_CHS] = {0};
/* 卸载确认只接受停止批次成功后产生的新P1量测。 */
static rt_uint32_t g_sink_unload_sample_seq[TOTAL_SOU_CHS] = {0};
static rt_bool_t g_sink_unload_batch_confirmed[TOTAL_SOU_CHS] = {RT_FALSE};
static rt_bool_t g_sink_unload_current_confirmed[TOTAL_SOU_CHS] = {RT_FALSE};
static rt_tick_t g_sink_unload_query_tick[TOTAL_SOU_CHS] = {0};
static rt_uint8_t g_sink_unload_confirm_count[TOTAL_SOU_CHS] = {0};
enum {
SINK_UNLOAD_NEXT_RUNNING = 0,
SINK_UNLOAD_NEXT_HANDSHAKE,
SINK_UNLOAD_NEXT_STOP_RELAY
};
/*****************************************************************
函数名称: chrg_sink_load_should_start
函数描述: 判断普通负载的设定值是否允许启动南向电子负载
@@ -68,7 +81,6 @@ static void chrg_sink_unload_confirm_reset(eIDX_SOU_CH idx)
}
g_sink_unload_sample_seq[idx] = 0U;
g_sink_unload_batch_confirmed[idx] = RT_FALSE;
g_sink_unload_current_confirmed[idx] = RT_FALSE;
g_sink_unload_query_tick[idx] = 0U;
g_sink_unload_confirm_count[idx] = 0U;
}
@@ -83,14 +95,6 @@ static void chrg_sink_unload_confirm_reset(eIDX_SOU_CH idx)
其它说明: 基线建立后返回成功,实际低电流确认仍由当前状态函数继续执行;
用于允许北向协议/CC与南向低电流确认并行推进
*****************************************************************/
rt_bool_t chrg_sink_handshake_north_ready(eIDX_SOU_CH idx)
{
if (idx >= TOTAL_SOU_CHS) {
return RT_FALSE;
}
return g_sink_unload_current_confirmed[idx];
}
/*****************************************************************
函数名称: chrg_sink_unload_query_submit
函数描述: 按最小间隔提交当前通道的一次性P1量测请求
@@ -253,7 +257,7 @@ static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
first_start = (pSW->sink.work_mode != SINK_WORK_INIT_AUX_WAIT) ?
RT_TRUE : RT_FALSE;
vals[2] = pSW->CV_mode;
vals[3] = pSW->sink.volt_on;
vals[3] = pSW->sink.volt_on <= 500 ? 500 : pSW->sink.volt_on;
if (pSW->sink.test.test_mode_old == SINK_TEST_SHORT) {
regs[count] = ModbusRTU_ShortTest_CMD_MODE_FLAG;
vals[count++] = ModbusRTU_DYNA_CMD_MODE_STOP;
@@ -273,6 +277,7 @@ static int chrg_sink_work_init(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
/* 南向批次已入队,北向按“CC->协议”顺序立即开始完整握手。 */
chrg_nor_sw_rel((eIDX_NOR_CH)idx, ID_SINK);
pNOR->enable[idx] = 1;
/* Protocol-before-CC test flow is disabled in this version. */
pSW->sub = IDX_SET_SINK_CC_BEFORE_PD;
}
pSW->sink.work_mode = SINK_WORK_INIT_AUX_WAIT;
@@ -312,6 +317,40 @@ static int chrg_sink_work_init_aux_wait(eIDX_SOU_CH idx,
return 0;
}
/*****************************************************************
函数名称: chrg_sink_volt_low_protect
函数描述: 主继电器闭合后持续监控南向实测输入电压,掉电立即转掉电保护
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 电压到位时确认ready;掉电时强制进入SINK_WORK_LOW并执行掉电批次
返回说明: 0:正常或保护批次已提交 <0:参数错误或保护批次提交失败
其它说明: 由北向轮询线程每轮调用,不依赖北向0x20回码。协议板断电时北向
回码会中断(volt_low计数不再累积),而南向P1量测由功率板独立
供电持续刷新,是本保护唯一可靠的电量来源。只有"提交闭合且实测
电压已到位"的通道才启用掉电判定,继电器动作期间不误触发
*****************************************************************/
int chrg_sink_volt_low_protect(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
if (g_sink_rel_main_closed[idx] == 0) {
return 0;
}
if (pSW->Now_voltage >= WORK_MIN_VOLT) {
/* 实测电压到达工作下限,确认主继电器已闭合。 */
g_sink_rel_main_ready[idx] = 1;
return 0;
}
if (g_sink_rel_main_ready[idx] != 0) {
/* 曾经到位后再次掉电:协议板处于断电窗口,禁止负载带载,
* 强制进入掉电安全处理等待协议板重新上电。 */
pSW->sink.work_mode = SINK_WORK_LOW;
return chrg_sink_work(idx, pSW);
}
/* 已提交闭合但电压尚未建立(继电器动作中),继续等待不保护。 */
return 0;
}
/*****************************************************************
函数名称: chrg_sink_work_volt_runing
函数描述: 执行负载RUNING状态,闭合全部继电器并启动负载
@@ -342,70 +381,40 @@ static int chrg_sink_work_volt_runing(eIDX_SOU_CH idx, struct chrg_switch_t *pSW
ret = chrg_sou_com_batch_submit(idx, stop_regs, stop_vals, 2U);
if (ret == 0) {
pSW->sink.work_mode = SINK_WORK_LOAD_STANDBY;
g_sink_rel_main_closed[idx] = 1;
}
return ret;
}
if (pSW->CV_mode == MODE_CONSTANT_VOLTAGE) {
regs[2] = REG_VOLTAGE_OUT + 1;
vals[2] = pSW->sink.loadv;
} else {
regs[2] = REG_CURRENT_OUT + 1;
vals[2] = pSW->sink.loadc;
/* 只有南向实测电压曾经到位后再次掉到低压,才判定为掉电。
* 初次RUNING时继电器批次刚入队,Now_voltage可能仍是上一帧的0,
* 此时不能取消尚未发送到WORK_START的启动批次。 */
if ((g_sink_rel_main_ready[idx] != 0) &&
(pSW->Now_voltage < WORK_MIN_VOLT)) {
pSW->sink.work_mode = SINK_WORK_LOW;
return 0;
}
return chrg_sou_com_batch_submit(idx, regs, vals, 3U);
}
/*****************************************************************
函数名称: chrg_sink_work_soft_resume
函数描述: 协议电压或协议电流变化完成后恢复负载
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 命令入队成功后将工作状态切换为SINK_WORK_SOFT_RUNNING
返回说明: 0:命令提交成功 <0:参数或命令提交失败
其它说明: 命令顺序为ALL_REL_ON、目标电流/电压、WORK_START;快速切换时
主继电器可能在完整握手阶段被关闭,恢复必须先确保继电器闭合
再启动电子负载,避免WORK_START先于主继电器带载;南向固件
继电器独立控制,ALL_REL_ON只开不关,不会误关已闭合的副继电器
*****************************************************************/
static int chrg_sink_work_soft_resume(eIDX_SOU_CH idx,
struct chrg_switch_t *pSW)
{
rt_uint16_t regs[3] = {REG_REL_ON, 0, REG_WORK};
rt_uint16_t vals[3] = {ALL_REL_ON, 0, WORK_START};
int ret;
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
if (!chrg_sink_load_should_start(pSW)) {
/* 软卸载未切继电器,低电流下保持原继电器和协议,只关闭电子负载。 */
regs[0] = REG_WORK;
vals[0] = WORK_STOP;
ret = chrg_sou_com_batch_submit(idx, regs, vals, 1U);
if (ret == 0) {
pSW->sink.work_mode = SINK_WORK_LOAD_SOFT_STANDBY;
}
return ret;
}
if (pSW->CV_mode == MODE_CONSTANT_VOLTAGE) {
regs[2] = REG_VOLTAGE_OUT + 1;
vals[2] = pSW->sink.loadv;
regs[1] = REG_VOLTAGE_OUT + 1;
vals[1] = pSW->sink.loadv;
} else {
regs[2] = REG_CURRENT_OUT + 1;
vals[2] = pSW->sink.loadc;
regs[1] = REG_CURRENT_OUT + 1;
vals[1] = pSW->sink.loadc;
}
if (chrg_sou_com_batch_submit(idx, regs, vals, 3U) != 0) {
return -1;
/* RUNING批次必须完整发送:ALL_REL_ON、目标负载值、WORK_START。 */
ret = chrg_sou_com_batch_submit(idx, regs, vals, 3U);
if (ret == 0) {
g_sink_rel_main_closed[idx] = 1;
}
pSW->sink.work_mode = SINK_WORK_SOFT_RUNNING;
return 0;
return ret;
}
/*****************************************************************
函数名称: chrg_sink_work_load_stop
函数描述: 普通负载运行中设定电流降到最低门限以下时安全停止带载
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 命令入队成功后进入SINK_WORK_LOAD_SOFT_STANDBY
输出参数: 命令入队成功后进入SINK_WORK_LOAD_STANDBY
返回说明: 0:命令提交成功 <0:参数或命令提交失败
其它说明: 命令只发送WORK_STOP;不改变北向协议、CC、电流设定和
主副继电器,保证后续恢复有效电流时无需重新协议握手
@@ -422,26 +431,7 @@ static int chrg_sink_work_load_stop(eIDX_SOU_CH idx,
if (chrg_sou_com_batch_submit(idx, &reg, &val, 1U) != 0) {
return -1;
}
pSW->sink.work_mode = SINK_WORK_LOAD_SOFT_STANDBY;
return 0;
}
/*****************************************************************
函数名称: chrg_sink_work_load_resume
函数描述: 从保持继电器的低电流待机状态恢复普通电子负载
输入参数: idx:南向功率通道编号 pSW:当前通道控制结构体
输出参数: 命令入队成功后进入SINK_WORK_SOFT_RUNNING
返回说明: 0:命令提交成功 <0:参数或命令提交失败
其它说明: 本状态只作为待恢复标记,不直接下发WORK_START;必须由北向解析确认
实际电压稳定后转入SINK_WORK_SOFT_RESUME,再恢复目标电流和WORK_START
*****************************************************************/
static int chrg_sink_work_load_resume(eIDX_SOU_CH idx,
struct chrg_switch_t *pSW)
{
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL) ||
!chrg_sink_load_should_start(pSW)) {
return -1;
}
pSW->sink.work_mode = SINK_WORK_LOAD_STANDBY;
return 0;
}
@@ -477,12 +467,8 @@ static int chrg_sink_work_load_start(eIDX_SOU_CH idx,
*****************************************************************/
static int chrg_sink_nor_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
rt_uint16_t regs[4] = {
REG_WORK, REG_CURRENT_OUT + 1, REG_REL_ON, REG_REL_ON
};
rt_uint16_t vals[4] = {
WORK_STOP, SINK_CLOSE_CURRENT_MA, ALL_REL_OFF, FU_REL_ON
};
rt_uint16_t reg = REG_WORK;
rt_uint16_t value = WORK_STOP;
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
@@ -491,9 +477,14 @@ static int chrg_sink_nor_work_low(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
if (chrg_sou_com_batch_cancel(idx) != 0) {
return -1;
}
if (chrg_sou_com_batch_submit(idx, regs, vals, 4U) != 0) {
/* Low voltage stops the electronic load only. Do not alter South relays:
* an intentional protocol transition must not cause a relay-induced drop. */
if (chrg_sou_com_batch_submit(idx, &reg, &value, 1U) != 0) {
return -1;
}
/* 主继电器已随掉电批次断开,闭合跟踪与电压到位确认一并清除。 */
g_sink_rel_main_closed[idx] = 0;
g_sink_rel_main_ready[idx] = 0;
pSW->sink.work_mode = SINK_WORK_LOW_AUX_WAIT;
return 0;
}
@@ -535,22 +526,74 @@ static int chrg_sink_work_low_aux_wait(eIDX_SOU_CH idx,
返回说明: 0:关机成功 <0:停止命令提交失败
其它说明: 先断开功率继电器并发送WORK_STOP,再关闭软件通道
*****************************************************************/
static int chrg_sink_nor_work_off(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
static int chrg_sink_work_stop_prepare(eIDX_SOU_CH idx,
struct chrg_switch_t *pSW)
{
rt_uint16_t reg = REG_WORK;
rt_uint16_t value = WORK_STOP;
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
if (chrg_sou_com_batch_cancel(idx) != 0) {
return -1;
}
if (chrg_sou_com_batch_submit(idx, &reg, &value, 1U) != 0) {
return -1;
}
/* 主动关机先停止电子负载。WORK_STOP收到匹配回码后,必须通过
* 停止命令之后的新P1量测连续确认低电流,才允许断开功率继电器。 */
chrg_sink_unload_confirm_reset(idx);
pSW->sink.work_mode = SINK_WORK_STOP_WAIT;
return 0;
}
static int chrg_sink_work_stop_relay(eIDX_SOU_CH idx,
struct chrg_switch_t *pSW)
{
rt_uint16_t reg = REG_REL_ON;
rt_uint16_t value = ALL_REL_OFF;
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
if (chrg_sou_com_batch_submit(idx, &reg, &value, 1U) != 0) {
return -1;
}
/* 继电器关闭命令已提交,等待南向回码后再清理软件通道。 */
pSW->sink.work_mode = SINK_WORK_STOP_RELAY_WAIT;
return 0;
}
static int chrg_sink_work_stop_relay_wait(eIDX_SOU_CH idx,
struct chrg_switch_t *pSW)
{
struct chrg_south_t *pSOU = &chrgsouth;
struct chrg_north_t *pNOR = &chrgnorth;
rt_uint16_t regs[2] = {REG_REL_ON, REG_WORK};
rt_uint16_t vals[2] = {ALL_REL_OFF, WORK_STOP};
int result;
if (chrg_sou_com_batch_submit(idx, regs, vals, 2) != 0) {
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
}
if (chrg_sou_com_batch_is_pending(idx)) {
return 0;
}
result = chrg_sou_com_batch_get_result(idx);
if (result <= 0) {
return chrg_sink_work_stop_relay(idx, pSW);
}
pSW->sink.On_work = 0;
pSOU->online[idx] = 0;
pNOR->enable[idx] = 0;
g_sink_rel_main_closed[idx] = 0;
g_sink_rel_main_ready[idx] = 0;
chrg_nor_sw_rel((eIDX_NOR_CH)idx, 0); //关闭北向继电器
chrg_nor_sw_rel((eIDX_NOR_CH)idx, 0);
/* 主动停止已经完成,退出异步等待状态,禁止下一轮重复执行。 */
pSW->sink.work_mode = SINK_WORK_WAIT;
return 0;
}
@@ -585,6 +628,7 @@ static int chrg_sink_work_switch(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
/* 停止成功入队后,清除旧Source运行标志。 */
pSW->source.On_Flag = 0;
/* 首次进入Sink时先设置目标CC线,CC稳定后再设置协议。 */
/* Protocol-before-CC test flow is disabled in this version. */
pSW->sub = IDX_SET_SINK_CC_BEFORE_PD;
/* SWITCH只负责旧角色退出,后续启动统一交给Sink INIT状态。 */
pSW->sink.work_mode = SINK_WORK_INIT;
@@ -629,12 +673,8 @@ static int chrg_sink_work_protocol_unload(eIDX_SOU_CH idx, struct chrg_switch_t
static int chrg_sink_work_handshake_prepare(eIDX_SOU_CH idx,
struct chrg_switch_t *pSW)
{
rt_uint16_t regs[4] = {
REG_WORK, REG_CURRENT_OUT + 1, REG_REL_ON, REG_REL_ON
};
rt_uint16_t vals[4] = {
WORK_STOP, SINK_CLOSE_CURRENT_MA, ALL_REL_OFF, FU_REL_ON
};
rt_uint16_t reg = REG_WORK;
rt_uint16_t value = WORK_STOP;
if ((idx >= TOTAL_SOU_CHS) || (pSW == RT_NULL)) {
return -1;
@@ -643,11 +683,11 @@ static int chrg_sink_work_handshake_prepare(eIDX_SOU_CH idx,
if (chrg_sou_com_batch_cancel(idx) != 0) {
return -1;
}
if (chrg_sou_com_batch_submit(idx, regs, vals, 4) != 0) {
if (chrg_sou_com_batch_submit(idx, &reg, &value, 1U) != 0) {
return -1;
}
/* 四条写回码完成后,还必须连续确认两帧实际电流不大于200mA。 */
/* 协议或CC切换先停止电子负载,连续5次确认低电流后再操作继电器。 */
chrg_sink_unload_confirm_reset(idx);
pSW->sink.work_mode = SINK_WORK_HANDSHAKE_WAIT;
return 0;
@@ -664,7 +704,7 @@ static int chrg_sink_work_handshake_prepare(eIDX_SOU_CH idx,
还要求CURRENT=1000mA、ALL_REL_OFF和FU_REL_ON回码成功,但保持北向Sink继电器接通
*****************************************************************/
static int chrg_sink_work_current_wait(eIDX_SOU_CH idx,
struct chrg_switch_t *pSW, rt_bool_t full_handshake)
struct chrg_switch_t *pSW, rt_uint8_t next_action)
{
rt_uint32_t sample_seq;
int batch_result;
@@ -678,14 +718,24 @@ static int chrg_sink_work_current_wait(eIDX_SOU_CH idx,
batch_result = chrg_sou_com_batch_get_result(idx);
if (batch_result < 0) {
/* 写命令失败时重新执行完整卸载批次,禁止使用量测值提前放行。 */
return full_handshake ? chrg_sink_work_handshake_prepare(idx, pSW) :
chrg_sink_work_protocol_unload(idx, pSW);
/* 写命令失败时重新执行停止命令,禁止使用量测值提前放行。 */
if (next_action == SINK_UNLOAD_NEXT_HANDSHAKE) {
return chrg_sink_work_handshake_prepare(idx, pSW);
}
if (next_action == SINK_UNLOAD_NEXT_STOP_RELAY) {
return chrg_sink_work_stop_prepare(idx, pSW);
}
return chrg_sink_work_protocol_unload(idx, pSW);
}
if (batch_result == 0) {
/* 无有效批次结果时保持阻塞,并重新提交完整卸载动作。 */
return full_handshake ? chrg_sink_work_handshake_prepare(idx, pSW) :
chrg_sink_work_protocol_unload(idx, pSW);
/* 无有效批次结果时保持阻塞,并重新提交停止动作。 */
if (next_action == SINK_UNLOAD_NEXT_HANDSHAKE) {
return chrg_sink_work_handshake_prepare(idx, pSW);
}
if (next_action == SINK_UNLOAD_NEXT_STOP_RELAY) {
return chrg_sink_work_stop_prepare(idx, pSW);
}
return chrg_sink_work_protocol_unload(idx, pSW);
}
if (!g_sink_unload_batch_confirmed[idx]) {
@@ -702,10 +752,17 @@ static int chrg_sink_work_current_wait(eIDX_SOU_CH idx,
g_sink_unload_confirm_count[idx]++;
if (g_sink_unload_confirm_count[idx] >= SINK_UNLOAD_CONFIRM_COUNT) {
g_sink_unload_batch_confirmed[idx] = RT_FALSE;
g_sink_unload_current_confirmed[idx] = RT_TRUE;
g_sink_unload_confirm_count[idx] = 0U;
pSW->sink.work_mode = full_handshake ?
SINK_WORK_WAIT : SINK_WORK_SOFT_RESUME_WAIT;
if (next_action == SINK_UNLOAD_NEXT_HANDSHAKE) {
/* 协议或CC切换保持南向继电器状态,低电流确认后直接开始北向配置。 */
pSW->sink.work_mode = SINK_WORK_WAIT;
} else if (next_action == SINK_UNLOAD_NEXT_STOP_RELAY) {
pSW->sink.work_mode = SINK_WORK_STOP_RELAY;
} else {
/* Keep relays closed and resume through the common
* voltage-confirmed RUNING path. */
pSW->sink.work_mode = SINK_WORK_WAIT;
}
return 0;
}
} else {
@@ -808,6 +865,7 @@ static int chrg_sink_TEST_OCP_ON(rt_uint8_t ch, struct chrg_switch_t *pSW)
返回说明: 0:状态处理成功 <0:参数、状态或命令提交失败
其它说明: 每通道记录上次成功状态,相同状态不重复下发寄存器
*****************************************************************/
int workmode = 0;
int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
{
static uint8_t last_state[TOTAL_SOU_CHS] ={100,100,100,100};
@@ -818,9 +876,12 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
return -1;
}
work_mode = pSW->sink.work_mode;
workmode = work_mode;
/* 异步等待状态需要持续检查批次或新量测,其余相同状态保持去重。 */
if ((work_mode == last_state[idx]) &&
(work_mode != SINK_WORK_INIT_AUX_WAIT) &&
(work_mode != SINK_WORK_STOP_WAIT) &&
(work_mode != SINK_WORK_STOP_RELAY_WAIT) &&
(work_mode != SINK_WORK_UNLOAD_WAIT) &&
(work_mode != SINK_WORK_LOW_AUX_WAIT) &&
(work_mode != SINK_WORK_HANDSHAKE_WAIT)) {
@@ -858,7 +919,17 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
ret = 0;
break;
case SINK_WORK_STOP:
ret = chrg_sink_nor_work_off(idx,pSW);
ret = chrg_sink_work_stop_prepare(idx, pSW);
break;
case SINK_WORK_STOP_WAIT:
ret = chrg_sink_work_current_wait(idx, pSW,
SINK_UNLOAD_NEXT_STOP_RELAY);
break;
case SINK_WORK_STOP_RELAY:
ret = chrg_sink_work_stop_relay(idx, pSW);
break;
case SINK_WORK_STOP_RELAY_WAIT:
ret = chrg_sink_work_stop_relay_wait(idx, pSW);
break;
case SINK_WORK_SWITCH:
ret = chrg_sink_work_switch(idx,pSW);
@@ -867,25 +938,17 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
ret = chrg_sink_work_protocol_unload(idx, pSW);
break;
case SINK_WORK_UNLOAD_WAIT:
ret = chrg_sink_work_current_wait(idx, pSW, RT_FALSE);
break;
case SINK_WORK_SOFT_RESUME_WAIT:
ret = 0;
break;
case SINK_WORK_SOFT_RESUME:
ret = chrg_sink_work_soft_resume(idx, pSW);
break;
case SINK_WORK_SOFT_RUNNING:
ret = 0;
ret = chrg_sink_work_current_wait(idx, pSW,
SINK_UNLOAD_NEXT_RUNNING);
break;
case SINK_WORK_HANDSHAKE_PREPARE:
ret = chrg_sink_work_handshake_prepare(idx, pSW);
break;
case SINK_WORK_HANDSHAKE_WAIT:
ret = chrg_sink_work_current_wait(idx, pSW, RT_TRUE);
ret = chrg_sink_work_current_wait(idx, pSW,
SINK_UNLOAD_NEXT_HANDSHAKE);
break;
case SINK_WORK_LOAD_STANDBY:
case SINK_WORK_LOAD_SOFT_STANDBY:
ret = 0;
break;
case SINK_WORK_LOAD_STOP:
@@ -894,9 +957,6 @@ int chrg_sink_work(eIDX_SOU_CH idx, struct chrg_switch_t *pSW)
case SINK_WORK_LOAD_START:
ret = chrg_sink_work_load_start(idx, pSW);
break;
case SINK_WORK_LOAD_RESUME:
ret = chrg_sink_work_load_resume(idx, pSW);
break;
default:
break;
}
+6 -7
View File
@@ -208,7 +208,8 @@ enum {
*/
#define SINK_LOAD_ENABLE_MIN_MA 100U
extern rt_bool_t chrg_sink_handshake_north_ready(eIDX_SOU_CH idx);
/* 主继电器闭合后的0V持续监控:由北向轮询线程每轮调用,掉电立即转掉电保护。 */
extern int chrg_sink_volt_low_protect(eIDX_SOU_CH idx, struct chrg_switch_t *pSW);
enum {
SINK_WORK_INIT = 0, // 启动入口:第一条南向命令只打开副继电器
@@ -219,23 +220,21 @@ enum {
SINK_WORK_LOW, // 运行电压过低,执行掉电安全处理
SINK_WORK_LOW_AUX_WAIT, // 等待掉电处理及副继电器恢复批次完成
SINK_WORK_LOW_MONITOR, // 副继电器已恢复,等待输入电压重新出现
SINK_WORK_STOP, // 用户主动停止负载
SINK_WORK_STOP, // 用户主动停止:先停止负载并确认低电流
SINK_WORK_SWITCH, // 停止旧电源后进入负载INIT
SINK_WORK_PROTOCOL_UNLOAD, // 协议电压或电流变化:掉载但不切换继电器
SINK_WORK_UNLOAD_WAIT, // 等待软卸载完成并连续两次确认电流不大于200mA
SINK_WORK_SOFT_RESUME_WAIT, // 继电器保持闭合,等待协议电压稳定后恢复负载
SINK_WORK_SOFT_RESUME, // 只恢复目标电流/电压和WORK_START,不写继电器
SINK_WORK_SOFT_RUNNING, // 软恢复后的稳定运行状态,禁止重复切换继电器
SINK_WORK_ON_TEST_DYNA, // 动态负载测试启动状态
SINK_WORK_ON_TEST_SHORT, // 短路测试启动状态
SINK_WORK_ON_TEST_OCP, // OCP过流保护测试启动状态
SINK_WORK_HANDSHAKE_PREPARE, // 完整重握手:停止、清流、全关继电器后打开副继电器
SINK_WORK_HANDSHAKE_WAIT, // 南向低电流确认与北向协议/CC并行
SINK_WORK_LOAD_STANDBY, // 协议已就绪但主继电器未打开,低设定电流下保持停止
SINK_WORK_LOAD_SOFT_STANDBY, // 协议和继电器保持不变,运行中降至低电流后的停止状态
SINK_WORK_LOAD_STOP, // 运行中跨到低电流:只发送WORK_STOP关闭电子负载
SINK_WORK_LOAD_START, // 主继电器未打开的低电流待机恢复:等待北向电压稳定后进入RUNING
SINK_WORK_LOAD_RESUME, // 软待机跨回有效电流:等待北向电压稳定后进入SOFT_RESUME
SINK_WORK_STOP_WAIT, // 关机:等待连续5次实际电流达到安全范围
SINK_WORK_STOP_RELAY, // 关机:低电流确认后提交关闭南向继电器
SINK_WORK_STOP_RELAY_WAIT // 关机:等待关闭南向继电器的回码
};
// sink 参数结构
+1 -1
View File
@@ -132,7 +132,7 @@
<UseTargetDll>1</UseTargetDll>
<UseExternalTool>0</UseExternalTool>
<RunIndependent>0</RunIndependent>
<UpdateFlashBeforeDebugging>0</UpdateFlashBeforeDebugging>
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
<Capability>1</Capability>
<DriverSelection>4096</DriverSelection>
</Flash1>
@@ -0,0 +1,9 @@
*** Using Compiler 'V6.16', folder: 'D:\keil mdk 2\ARM\ARMCLANG\Bin'
Build target 'chrg'
compiling chrg_sink.c...
linking...
Program Size: Code=147156 RO-data=15312 RW-data=9328 ZI-data=15984
FromELF: creating hex file...
After Build - User command #1: fromelf --bin .\build\keil\Obj\chrg.axf -o build/chrg.bin
".\build\keil\Obj\chrg.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:02
+18
View File
@@ -0,0 +1,18 @@
*** Using Compiler 'V6.16', folder: 'D:\keil mdk 2\ARM\ARMCLANG\Bin'
Build target 'chrg'
compiling chrg_north_pkg.c...
compiling chrg_lcd.c...
compiling chrg_thread.c...
compiling chrg_south.c...
compiling chrg_sink.c...
compiling chrg_north.c...
compiling chrg_source.c...
compiling chrg_roll_nor.c...
compiling chrg_roll_sou.c...
compiling chrg_comm.c...
linking...
Program Size: Code=146988 RO-data=15312 RW-data=9328 ZI-data=15984
FromELF: creating hex file...
After Build - User command #1: fromelf --bin .\build\keil\Obj\chrg.axf -o build/chrg.bin
".\build\keil\Obj\chrg.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:03
+21
View File
@@ -0,0 +1,21 @@
*** Using Compiler 'V6.16', folder: 'D:\keil mdk 2\ARM\ARMCLANG\Bin'
Build target 'chrg'
compiling chrg_rel.c...
compiling chrg_vcom.c...
compiling chrg_north_pkg.c...
compiling chrg_lcd.c...
compiling chrg_thread.c...
compiling chrg_south.c...
compiling chrg_eload.c...
compiling chrg_sink.c...
compiling chrg_north.c...
compiling chrg_source.c...
compiling chrg_roll_nor.c...
compiling chrg_roll_sou.c...
compiling chrg_comm.c...
linking...
Program Size: Code=146964 RO-data=15312 RW-data=9328 ZI-data=15984
FromELF: creating hex file...
After Build - User command #1: fromelf --bin .\build\keil\Obj\chrg.axf -o build/chrg.bin
".\build\keil\Obj\chrg.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:02
@@ -0,0 +1,21 @@
*** Using Compiler 'V6.16', folder: 'D:\keil mdk 2\ARM\ARMCLANG\Bin'
Build target 'chrg'
compiling chrg_vcom.c...
compiling chrg_thread.c...
compiling chrg_north_pkg.c...
compiling chrg_lcd.c...
compiling chrg_rel.c...
compiling chrg_eload.c...
compiling chrg_sink.c...
compiling chrg_south.c...
compiling chrg_source.c...
compiling chrg_north.c...
compiling chrg_roll_nor.c...
compiling chrg_roll_sou.c...
compiling chrg_comm.c...
linking...
Program Size: Code=147032 RO-data=15312 RW-data=9328 ZI-data=15984
FromELF: creating hex file...
After Build - User command #1: fromelf --bin .\build\keil\Obj\chrg.axf -o build/chrg.bin
".\build\keil\Obj\chrg.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:03
+21
View File
@@ -0,0 +1,21 @@
*** Using Compiler 'V6.16', folder: 'D:\keil mdk 2\ARM\ARMCLANG\Bin'
Build target 'chrg'
compiling chrg_rel.c...
compiling chrg_north_pkg.c...
compiling chrg_thread.c...
compiling chrg_vcom.c...
compiling chrg_lcd.c...
compiling chrg_eload.c...
compiling chrg_sink.c...
compiling chrg_source.c...
compiling chrg_south.c...
compiling chrg_north.c...
compiling chrg_roll_nor.c...
compiling chrg_roll_sou.c...
compiling chrg_comm.c...
linking...
Program Size: Code=146976 RO-data=15312 RW-data=9328 ZI-data=15984
FromELF: creating hex file...
After Build - User command #1: fromelf --bin .\build\keil\Obj\chrg.axf -o build/chrg.bin
".\build\keil\Obj\chrg.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:03
@@ -0,0 +1,9 @@
*** Using Compiler 'V6.16', folder: 'D:\keil mdk 2\ARM\ARMCLANG\Bin'
Build target 'chrg'
compiling chrg_comm.c...
linking...
Program Size: Code=147096 RO-data=15312 RW-data=9328 ZI-data=15984
FromELF: creating hex file...
After Build - User command #1: fromelf --bin .\build\keil\Obj\chrg.axf -o build/chrg.bin
".\build\keil\Obj\chrg.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:02
+2 -4
View File
@@ -1,11 +1,9 @@
*** Using Compiler 'V6.16', folder: 'D:\keil mdk 2\ARM\ARMCLANG\Bin'
Build target 'chrg'
compiling chrg_eload.c...
compiling chrg_sink.c...
compiling chrg_roll_sou.c...
linking...
Program Size: Code=146936 RO-data=15312 RW-data=9328 ZI-data=15992
Program Size: Code=147104 RO-data=15312 RW-data=9328 ZI-data=16000
FromELF: creating hex file...
After Build - User command #1: fromelf --bin .\build\keil\Obj\chrg.axf -o build/chrg.bin
".\build\keil\Obj\chrg.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:04
Build Time Elapsed: 00:00:01