3、非功能需求:安全性、可靠性与实时性

好,咱们接着聊。上一节我们把车门控制的功能需求理清楚了,比如怎么解锁、怎么升窗。但说实话,功能需求只是“能不能用”的问题。真正决定一个产品好不好的,是那些看不见的东西——非功能需求。

我个人习惯,在写第一行代码之前,先把非功能需求想透。为什么呢?因为一旦代码写完了,再回头改这些东西,成本高得吓人。我在项目中遇到过好几次,功能跑得挺好,结果一测防夹手,车窗直接把矿泉水瓶夹爆了……嗯,那场面,客户脸都绿了。

3.1 安全性要求:防夹手与故障自检

车门控制里,安全性是头等大事。你想想看,车窗夹到小孩的手指,或者门锁在行驶中突然弹开,这都是人命关天的事。所以,安全相关的需求,必须从设计一开始就刻在骨子里。

3.4.1 防夹手机制

防夹手,说白了就是车窗在上升过程中,如果遇到阻力,必须立刻停止并反转。这个功能看起来简单,但坑特别多。

核心原理:

  • 通过霍尔传感器或电流检测,实时监测电机负载
  • 当检测到阻力超过阈值,立即触发反转
  • 反转距离通常为 100-200ms 的行程

我曾经踩过一个坑: 防夹手的阈值设得太灵敏了。结果冬天车窗结冰,一升窗就触发防夹,车窗根本关不上。后来我学乖了,加了一个“自适应阈值”逻辑——根据电机运行初期的电流基线,动态调整防夹阈值。

防夹手设计要点:

  • 必须区分“正常阻力”(如密封条摩擦)和“异常阻力”(如手指卡住)
  • 反转动作必须在 50ms 内响应,否则夹力会超过安全标准
  • 需要做“防夹手自学习”:每次安装后,让车窗完整运行一次,记录阻力曲线

这里给出一段伪代码,展示防夹手的核心逻辑:

// 防夹手检测任务,每 10ms 执行一次
void AntiPinch_Task(void)
{
    static uint16_t baseline_current = 0;
    uint16_t current = Read_MotorCurrent();
    
    // 自学习阶段:记录正常运行的电流基线
    if (system_state == LEARNING_MODE)
    {
        baseline_current = current;
        return;
    }
    
    // 计算偏差
    int16_t delta = (int16_t)current - (int16_t)baseline_current;
    
    // 如果电流超过阈值,且车窗正在上升
    if (delta > PINCH_THRESHOLD && window_direction == UP)
    {
        // 立即停止并反转
        Motor_Stop();
        Delay_ms(20);  // 等待电机惯性消除
        Motor_Reverse(REVERSE_TIME_150MS);
        
        // 记录故障事件
        Log_Event(EVENT_ANTIPINCH_TRIGGERED);
    }
}

我的小技巧: 防夹手的阈值不要写死。我习惯在 EEPROM 里存一个“学习值”,每次车窗安装或更换电机后,让系统自动跑一遍自学习。这样能适应不同车辆的机械公差。

3.4.2 故障自检

故障自检,也叫“上电自检”或“周期性自检”。它的目的是:在系统启动时或运行中,主动检查关键部件是否正常。

为什么会需要这个?你想想看,如果霍尔传感器坏了,防夹手功能就失效了。但驾驶员不知道啊,他以为车窗有防夹功能,结果……嗯,后果很严重。

我建议的自检项目:

自检项目 检测方法 故障处理
电机驱动电路 输出一个短脉冲,检测反馈电流 若异常,禁用该车窗,点亮故障灯
霍尔传感器 手动转动电机,检查脉冲是否正常 若异常,降级为“无防夹模式”
CAN 通信 发送心跳报文,等待应答 若超时,进入安全模式(锁门但不升窗)
电源电压 ADC 采样,检查是否在 9-16V 范围内 若欠压,禁止大电流操作

注意: 自检不能影响用户体验。上电自检必须在 100ms 内完成,否则驾驶员会感觉“这车反应好慢”。我见过一个项目,自检做了 500ms,结果被客户投诉“启动延迟”。后来改成“后台自检+前台快速响应”,才解决问题。

3.2 可靠性要求:MTBF

MTBF,全称 Mean Time Between Failures,平均无故障时间。说白了就是:这个系统平均能用多久才出一次故障。

对于车门控制器,行业标准通常要求 MTBF 不低于 10 万小时。换算一下,大概 11 年。也就是说,你设计的控制器,要保证在 11 年内不出硬件故障。

怎么提高 MTBF? 我个人经验,主要看三点:

  • 降额设计: 电机驱动 MOS 管,额定电流 10A,我只用到 6A。留足余量,温度就低,寿命就长。
  • 冗余设计: 关键信号(如门锁状态)用双路采样。一路坏了,另一路还能工作。
  • 环境防护: 车门控制器在门板里,夏天能到 85°C,冬天能到 -40°C。所有元器件必须选车规级(AEC-Q100)。

MTBF 计算示例:

假设系统由 3 个模块组成:

  • MCU 模块:失效率 λ₁ = 0.5 FIT(1 FIT = 10⁻⁹ 小时⁻¹)
  • 电机驱动模块:失效率 λ₂ = 1.2 FIT
  • 通信模块:失效率 λ₃ = 0.8 FIT

系统总失效率 λ = λ₁ + λ₂ + λ₃ = 2.5 FIT

MTBF = 1 / λ = 1 / (2.5 × 10⁻⁹) = 400,000,000 小时 ≈ 45,662 年

嗯,这个数字看起来很大,但别忘了,这只是理论值。实际中还要考虑焊接质量、振动、湿度等因素。我一般会在理论值上打个 0.7 的折扣。

3.3 实时性要求:响应时间

实时性,就是“从事件发生到系统响应”的时间。对于车门控制,这个时间必须短到让用户感觉“无延迟”。

我建议的响应时间指标:

操作 最大响应时间 说明
按键解锁 50ms 用户按下按钮到门锁动作
车窗升降 100ms 从收到指令到电机开始转动
防夹手触发 20ms 从检测到障碍物到电机停止
CAN 报文接收 10ms 从总线收到报文到应用层处理

你可能会问:这些时间怎么保证?其实,核心在于任务调度。我习惯用“优先级抢占+时间片轮转”的方式:

  • 防夹手检测:最高优先级,每 5ms 执行一次
  • 按键扫描:中等优先级,每 10ms 执行一次
  • CAN 通信:中等优先级,每 10ms 处理一次
  • 自检任务:低优先级,每 100ms 执行一次

避坑指南: 我曾经在一个项目里,把自检任务和防夹手任务放在同一个优先级。结果自检时读 EEPROM,耗时 30ms,导致防夹手检测被延迟。嗯,后果就是——防夹手响应时间超标了。后来我把自检任务降级,并拆分成多个小步骤,才解决这个问题。

好了,非功能需求就聊到这里。总结一句话:功能需求决定产品能不能用,非功能需求决定产品好不好用。 下一节,我们开始聊系统架构设计,把今天这些需求落地成具体的模块划分。