2. VCU基础概念

VCU 的核心功能,说白了就是五件事:上下电、挡位、扭矩、能量、故障。这五个模块就像人的五脏六腑,缺一不可。我做了这么多年 VCU 开发,每次接手新项目,第一件事就是把这五个模块的架构理清楚。今天咱们一个一个过。

核心观点:VCU 的五个核心功能模块不是孤立的。上下电是基础,挡位是意图,扭矩是执行,能量是效率,故障是安全。它们之间互相耦合,开发时必须统一考虑。

VCU 核心功能模块架构图 VCU 核心控制器 上下电管理 挡位管理 扭矩管理 能量管理 故障诊断 说明: 五个模块通过 CAN/LIN 总线交互,上下电状态决定挡位和扭矩的使能条件, 能量管理影响扭矩输出上限,故障诊断监控所有模块的运行状态。

2.1 整车上下电管理

上下电管理是 VCU 最基础的功能,也是整车安全的第一道防线。你想想看,一辆车如果连上电都控制不好,后面的功能全是白搭。

我个人习惯把上下电分为三个阶段:唤醒阶段、主上电阶段、下电阶段。每个阶段都有严格的状态机控制。

阶段 触发条件 VCU 动作 典型时间
唤醒阶段 钥匙 ON / 远程唤醒 唤醒 BMS、MCU、DC-DC,自检 ≤ 200ms
主上电阶段 自检通过 + 制动信号 闭合主继电器,预充完成,READY 灯亮 ≤ 500ms
下电阶段 钥匙 OFF / 故障触发 降扭矩→断开继电器→休眠 ≤ 300ms

避坑指南:我曾经遇到过一个问题——预充继电器粘连导致上电瞬间电流冲击。后来我们在状态机里加了预充完成检测的超时判断,如果 1 秒内预充电压没达到 90%,直接报故障并禁止主继电器闭合。这个坑,踩过一次就记住了。

上下电管理的核心代码逻辑,其实就是个有限状态机。我贴一段简化版的伪代码,大家感受一下:

// 上下电状态机 - 简化示例
typedef enum {
    POWER_OFF,
    WAKE_UP,
    PRE_CHARGE,
    MAIN_POWER_ON,
    POWER_DOWN,
    SLEEP
} PowerState_t;

PowerState_t currentState = POWER_OFF;

void PowerStateMachine(void) {
    switch(currentState) {
        case POWER_OFF:
            if(KeyOnSignal == TRUE) {
                WakeUpBMS();
                WakeUpMCU();
                currentState = WAKE_UP;
            }
            break;
        case WAKE_UP:
            if(SelfCheckPassed() && BrakeSignal == TRUE) {
                StartPreCharge();
                currentState = PRE_CHARGE;
            }
            break;
        case PRE_CHARGE:
            if(PreChargeVoltage >= 0.9 * BatteryVoltage) {
                CloseMainRelay();
                SetReadyLight(ON);
                currentState = MAIN_POWER_ON;
            } else if(PreChargeTimeout == TRUE) {
                SetFaultCode(FAULT_PRECHARGE_FAIL);
                currentState = POWER_DOWN;
            }
            break;
        // ... 其他状态处理
    }
}

2.2 挡位管理

挡位管理,说白了就是解析驾驶员的意图。你挂 D 挡还是 R 挡,VCU 得知道,而且得安全地执行。

挡位管理有几个关键点:

  • 挡位信号采集:旋钮式、电子挡杆、怀挡,不同硬件有不同的信号协议
  • 挡位状态机:P→R→N→D 的切换逻辑,必须防抖、防误操作
  • 安全互锁:车速 > 5km/h 时禁止挂 R 挡,这是硬性要求

经验之谈:我建议大家在挡位管理里加一个"挡位请求仲裁"模块。什么意思呢?就是驾驶员按了挡位按钮,VCU 先判断当前条件是否允许切换,允许了才执行。这样能避免很多误操作导致的安全事故。

挡位切换的时序要求很严格。我记得有一次标定,客户反映挂 D 挡后车辆响应有延迟。查了半天,发现是挡位信号滤波时间太长。后来把滤波窗口从 50ms 调到 20ms,问题就解决了。

2.3 扭矩管理

扭矩管理是 VCU 最核心的功能,也是最能体现标定水平的地方。你想想看,驾驶员踩油门,VCU 要算出来给电机发多少扭矩,这个计算过程涉及十几个输入信号。

扭矩管理的流程大致是这样的:

  1. 驾驶员需求解析:油门踏板开度 → 基础扭矩请求
  2. 限制条件叠加:电池 SOC 限制、电机温度限制、车速限制
  3. 扭矩仲裁:驾驶员需求 vs 安全限制,取最小值
  4. 扭矩输出:通过 CAN 发送扭矩指令给 MCU
限制条件 影响范围 典型标定值
SOC 限制 SOC < 20% 时限制峰值扭矩 峰值扭矩降为 60%
电机温度限制 温度 > 120°C 时降扭 每升高 5°C 降 10% 扭矩
车速限制 车速 > 150km/h 时限制扭矩 扭矩上限 80Nm
故障限制 检测到严重故障时扭矩归零 扭矩 = 0

关键点:扭矩管理的核心是"安全优先"。任何时候,限制条件叠加后的扭矩值必须小于等于驾驶员请求值。说白了,VCU 只能给比驾驶员要的少的扭矩,不能多给。

2.4 能量管理

能量管理,说白了就是怎么让车跑得更远、更省电。这部分工作,标定工程师的发挥空间很大。

能量管理主要包括:

  • 能量回收策略:滑行回收、制动回收,回收扭矩的标定
  • DC-DC 控制:12V 低压电池的充电管理
  • 热管理协调:电池加热/冷却的能耗优化

我个人觉得能量回收是最有意思的部分。你想想看,同样的路况,回收扭矩标得大,续航能多 5%-8%,但驾驶感受会变差,乘客容易晕车。这里面的平衡,全靠标定经验。

标定技巧:我建议能量回收扭矩不要用固定值,而是根据车速和制动深度做 MAP 查表。低速时回收扭矩小一点,避免"踩刹车就点头"的感觉;高速时回收扭矩可以大一些,回收效率更高。

2.5 故障诊断与处理

故障诊断是 VCU 的"守门员"。没有故障诊断,前面四个功能再完善,出了故障也是白搭。

故障诊断分三个等级:

故障等级 定义 VCU 响应
一级故障 严重安全故障(如绝缘故障) 立即下高压,扭矩归零
二级故障 性能受限故障(如电机过温) 降扭矩,点亮故障灯
三级故障 提示性故障(如传感器漂移) 记录故障码,不影响驾驶

避坑指南:我曾经遇到过一个问题——故障误报导致车辆频繁下电。查了三天,发现是 CAN 总线干扰导致信号跳变。后来我们在故障诊断里加了"确认次数"机制,连续 3 次采样都报故障才确认,误报率直接降到零。

故障诊断的代码实现,核心是"采样→滤波→判断→响应"四个步骤。嗯,这里要注意,故障判断的周期不能太长,否则故障发生了 VCU 还不知道,那就危险了。我一般把故障诊断任务的周期设在 10ms-20ms。

// 故障诊断 - 简化示例
void FaultDiagnosisTask(void) {
    // 1. 采样
    uint16_t insulationResistance = GetInsulationResistance();
    
    // 2. 滤波(滑动平均)
    static uint16_t filterBuffer[5];
    static uint8_t index = 0;
    filterBuffer[index++] = insulationResistance;
    if(index >= 5) index = 0;
    uint16_t avgResistance = Average(filterBuffer, 5);
    
    // 3. 判断
    if(avgResistance < INSULATION_THRESHOLD) {
        faultCounter++;
        if(faultCounter >= 3) {  // 连续 3 次确认
            SetFaultCode(FAULT_INSULATION_FAIL);
            SetFaultLevel(FAULT_LEVEL_1);
            PowerDownImmediately();
        }
    } else {
        faultCounter = 0;
    }
}

好了,五个核心功能模块就讲到这里。每个模块展开都能讲一整天,今天咱们先把框架搭起来。后面几章会逐个深入,尤其是扭矩管理和能量管理,那是标定的重头戏。