4. 软件保护方案:ADC采样策略、数字滤波算法、软件阈值判断、故障标志位管理
硬件保护像是个急性子的保安,一看到电流超标就立刻拉闸。但很多时候,电流尖峰只是电机换相时的正常现象,或者只是外部干扰。如果每次都触发硬件保护,电机根本没法正常转。
软件保护就是那个沉稳的工程师。它不急着下结论,而是先看看数据,分析一下,再决定要不要保护。说白了,硬件负责「快」,软件负责「准」。
核心思路:硬件保护做最后一道防线,软件保护做智能判断。两者配合,才能既保护硬件,又不误动作。
4.1 ADC采样策略:什么时候采?采几次?
ADC采样是软件保护的「眼睛」。眼睛不好使,后面算法再牛也没用。我见过不少项目,保护误触发,最后查出来是采样时机不对。
4.1.1 采样窗口的选择
BLDC 的相电流不是平滑的直流,而是 PWM 调制出来的脉冲波形。你想想看,如果在 PWM 开关管导通和关断的瞬间去采样,那数据肯定乱跳。
我个人习惯的做法是:
- 单电阻采样:在 PWM 中心对齐的时刻采样。这时候电流最稳定,噪声最小。
- 双/三电阻采样:在下桥臂导通期间采样。避开开关动作的尖峰。
小技巧:采样窗口要避开 PWM 边沿至少 1-2μs。我一般会在定时器里设置一个采样触发延迟,确保电流已经稳定了再启动 ADC。
4.1.2 采样频率与过采样
采样频率不是越高越好。太高了,CPU 忙不过来;太低了,又抓不住故障电流。
我一般这样配置:
| 应用场景 | 采样频率 | 说明 |
|---|---|---|
| 低速/轻载 | 10-20 kHz | 电流变化慢,不需要高频采样 |
| 高速/重载 | 20-50 kHz | 电流变化快,需要更密集的采样 |
| 过流保护专用 | 50-100 kHz | 专门用于快速检测异常,可独立于控制环路 |
另外,我建议用过采样技术。比如,对同一个电流值连续采 4 次,然后取平均。这样能有效降低量化噪声。代价就是多占一点 CPU 时间,但换来的是更稳定的数据。
4.2 数字滤波算法:把噪声「洗」干净
ADC 采回来的数据,直接拿去判断阈值?别急,先过一遍滤波器。我在项目中遇到过,电机启动瞬间的电流尖峰,如果不滤波,软件保护会频繁误触发。
4.2.1 滑动平均滤波
这是最简单也最常用的方法。维护一个长度为 N 的缓冲区,每次采样都更新,然后取平均值。
// 滑动平均滤波示例
#define FILTER_LEN 8
uint16_t filter_buf[FILTER_LEN];
uint8_t filter_index = 0;
uint16_t moving_average(uint16_t new_sample) {
uint32_t sum = 0;
filter_buf[filter_index] = new_sample;
filter_index = (filter_index + 1) % FILTER_LEN;
for (int i = 0; i < FILTER_LEN; i++) {
sum += filter_buf[i];
}
return (uint16_t)(sum / FILTER_LEN);
}
N 值越大,滤波效果越好,但响应也越慢。我一般取 4 到 8 之间。对于过流保护,响应速度很重要,所以 N 不能太大。
4.2.2 中值滤波
对付脉冲噪声(比如偶尔的尖峰干扰),中值滤波效果很好。把最近几次采样排序,取中间值。
嗯,这里要注意:中值滤波计算量大一些,不适合高频采样。我一般只在关键通道(比如相电流)上用,或者只在故障判断前用一次。
4.2.3 一阶低通滤波
如果你不想用缓冲区,可以用一阶低通滤波。它本质上是一个加权平均:
// 一阶低通滤波
#define ALPHA 0.8 // 滤波系数,0-1之间
uint16_t filtered_value = 0;
uint16_t low_pass_filter(uint16_t new_sample) {
filtered_value = (uint16_t)(ALPHA * filtered_value + (1 - ALPHA) * new_sample);
return filtered_value;
}
ALPHA 越大,滤波越平滑,但响应越慢。我习惯在调试时先设成 0.7,然后根据实际波形调整。
注意:数字滤波会引入延迟。对于过流保护,延迟不能超过 100μs,否则硬件可能已经烧了。所以,滤波算法要轻量,不能太复杂。
4.3 软件阈值判断:多级保护,层层递进
阈值判断不是简单的「超过就保护」。那样太粗暴了。我习惯设计多级阈值,不同级别对应不同的处理方式。
4.3.1 三级阈值设计
| 级别 | 阈值范围 | 动作 | 恢复方式 |
|---|---|---|---|
| 警告级 | 额定电流 × 1.2 | 记录日志,降低 PWM 占空比 | 电流回落后自动恢复 |
| 保护级 | 额定电流 × 1.5 | 立即关断 PWM,置位故障标志 | 需手动复位或延时重试 |
| 硬件级 | 硬件比较器设定值 | 硬件直接关断,不经过软件 | 需断电重启 |
为什么要分三级?因为有些过流是暂时的(比如负载突变),降功率就能扛过去。有些是严重的(比如相间短路),必须立刻停机。
4.3.2 滞回比较
直接比较阈值有个问题:电流在阈值附近抖动时,保护会频繁开启和关闭。这就像空调在设定温度附近频繁启停一样,很烦人。
解决办法是加滞回:
- 保护触发阈值:1.5 倍额定电流
- 恢复阈值:1.2 倍额定电流
也就是说,电流超过 1.5 倍才保护,但必须降到 1.2 倍以下才恢复。中间有个 0.3 倍的死区,避免频繁切换。
我的经验:滞回区间不要太小,否则等于没加。我一般设 20%-30% 的滞回量。具体数值可以在调试时用示波器观察电流波形来调整。
4.4 故障标志位管理:状态机思维
故障标志位不是简单的 0 或 1。我建议用状态机来管理。这样逻辑清晰,也方便扩展。
4.4.1 故障状态定义
typedef enum {
FAULT_NONE = 0x00, // 无故障
FAULT_WARNING = 0x01, // 警告级
FAULT_OVER_CURRENT = 0x02, // 过流保护
FAULT_HARDWARE = 0x04, // 硬件保护触发
FAULT_LOCKED = 0x80 // 锁定状态,需复位
} fault_status_t;
用位域的方式定义,可以同时记录多个故障。比如,同时有警告和过流,状态就是 0x03。
4.4.2 状态转移逻辑
我习惯用一个简单的状态机来处理:
- 正常状态:电流正常,无标志位。
- 警告状态:电流超过警告阈值,置位 FAULT_WARNING,降低功率。
- 保护状态:电流超过保护阈值,置位 FAULT_OVER_CURRENT,关断 PWM。
- 锁定状态:如果保护后电流仍然异常,或者硬件保护触发,进入锁定状态。必须断电或手动复位才能退出。
避坑指南:我曾经在项目里忘了清除故障标志位,导致电机保护后再也启动不了。后来我加了一个「自动恢复计数器」:保护后延时 1 秒,如果电流恢复正常,自动清除标志位。这样既安全又智能。
4.5 整体流程图
下面这张图展示了软件保护的完整流程。从 ADC 采样开始,到最终决定是否保护,每一步都很关键。
4.6 调试建议
软件保护写好了,怎么验证?我分享几个实战经验:
- 先用仿真器看数据:把 ADC 原始值和滤波后的值通过串口或 DAC 输出,用示波器观察。看看滤波效果是否满意。
- 故意制造过流:堵转电机,或者短路一相(注意安全!),看软件保护是否及时响应。
- 调整阈值:不要一次设死。先设一个宽松的值,然后逐步收紧,找到最佳平衡点。
安全提醒:调试过流保护时,一定要在电源回路中串联一个限流电阻或保险丝。我曾经因为疏忽,短路测试时直接把 MOS 管炸了。嗯,那味道,终身难忘。
软件保护方案的核心就这些。采样要准,滤波要稳,阈值要分级,标志位要管理好。把这几点做到位,你的 BLDC 驱动就能在「安全」和「性能」之间找到最佳平衡。