3、电流采样故障:采样电阻短路/开路、运放饱和、ADC异常检测与处理
电流采样,是FOC控制的眼睛。眼睛出了问题,整个系统就是盲人摸象。我见过太多项目,电机转不起来,最后查来查去,都是采样链路出了毛病。这一讲,咱们就把采样电阻、运放、ADC这三个环节的故障,掰开揉碎了讲清楚。
3.1 采样电阻的短路与开路
采样电阻,说白了就是一颗毫欧级的小电阻。它串联在电机相线上,把电流信号转成电压信号。但它也是最容易受伤的器件。
3.1.1 短路故障
采样电阻短路,意味着电阻两端直接导通。这时候,电流信号直接消失,你读到的电压永远是0V。电机控制器会认为“没有电流”,然后拼命加大占空比,结果就是——电流失控,炸管。
检测方法其实很简单:
- 静态检测: 电机静止时,采样电阻两端电压应为0V(或接近0V)。如果读到非零值,说明可能有短路或焊接问题。
- 动态检测: 给一个很小的占空比(比如1%),观察电流反馈是否跟随。如果反馈始终为0,大概率是短路了。
我个人习惯,在初始化阶段做一次“自检”。给一个已知的小电流,看看ADC读回来的值对不对得上。对不上,直接报错,不让电机启动。
3.1.2 开路故障
开路比短路更隐蔽。采样电阻开路,电流回路还在,但电压信号会变得非常大——因为运放输入端变成了高阻抗状态,容易耦合噪声。
我曾经在一个项目中遇到过,电机低速运行时一切正常,一加速就剧烈抖动。查了三天,最后发现是采样电阻一端虚焊,接触不良。温度一高,热胀冷缩,接触电阻变大,信号就乱了。
开路检测,我建议用“过压检测法”:
- 正常工作时,采样电阻两端电压不会超过某个最大值(比如±3.3V)。
- 如果ADC读到接近电源轨的电压(比如3.2V或0V),而且持续超过几个采样周期,基本可以判定是开路。
3.2 运放饱和
运放是采样链路的放大器。它把采样电阻上的微弱电压(毫伏级)放大到ADC能识别的范围(比如0~3.3V)。但运放有个毛病——它会饱和。
3.2.1 为什么会饱和?
说白了,就是输入信号超出了运放的线性工作范围。原因有几种:
- 过流: 电机电流太大,采样电阻上的电压超过了运放的输入范围。
- 共模电压过高: 在高端电流采样中,共模电压可能接近母线电压。如果运放的共模抑制比不够,输出就会饱和。
- 电源问题: 运放供电电压不足,或者参考电压漂移。
3.2.2 饱和的后果
运放饱和后,输出会“卡死”在某个固定电压上。比如,正饱和时输出接近3.3V,负饱和时接近0V。这时候,ADC读到的电流值就是错的。FOC算法会基于错误的值计算电压矢量,结果就是——电流环失控,电机剧烈抖动甚至反转。
我记得有一次调试,电机一启动就“嗡嗡”响,电流波形像锯齿一样。用示波器一看,运放输出已经顶到3.3V了。原来是电流太大,采样电阻选小了。换了个大一点的电阻,问题解决。
3.2.3 饱和检测与处理
检测饱和,其实很简单:
- 阈值判断: 如果ADC读数接近满量程(比如大于3.2V)或接近0V(比如小于0.1V),而且持续超过N个周期,就认为运放饱和了。
- 变化率判断: 正常电流信号是有变化的。如果ADC读数长时间不变(比如连续100个采样点都一样),大概率是饱和了。
处理方式,我建议分两步:
- 立即降功率: 把电流环的给定值强制降到安全范围(比如额定电流的50%)。
- 报警并记录: 记录故障时刻的电流、电压、温度等参数,方便事后分析。
3.3 ADC异常检测与处理
ADC是模拟信号进入数字世界的最后一关。ADC出问题,前面的采样电阻和运放再好也没用。
3.3.1 常见的ADC异常
| 异常类型 | 表现 | 可能原因 |
|---|---|---|
| ADC卡死 | 读数长时间不变 | 时钟丢失、DMA配置错误 |
| ADC跳变 | 读数随机跳动,无规律 | 电源噪声、参考电压不稳 |
| ADC偏移 | 读数整体偏大或偏小 | 参考电压漂移、采样时间不足 |
| ADC饱和 | 读数固定在0或满量程 | 输入电压超出范围、运放饱和 |
3.3.2 检测方法
我常用的检测手段有三个:
- 自检模式: 在系统初始化时,给ADC输入一个已知电压(比如内部参考电压的1/2),看看读回来的值对不对。不对的话,直接报错。
- 一致性检查: 连续读取N次ADC值,计算方差。如果方差超过阈值,说明ADC有异常跳变。
- 超时检测: 如果ADC转换完成中断没有在规定时间内触发,说明ADC可能卡死了。
你想想看,如果ADC卡死了,你读到的电流值永远是同一个数。FOC算法会认为电流没变,然后继续输出同样的电压矢量。结果就是——电机要么不动,要么失控。
3.3.3 处理策略
ADC异常的处理,我建议分等级:
- 轻度异常(偶尔跳变): 做软件滤波。比如中值滤波或滑动平均滤波,把异常值滤掉。
- 中度异常(频繁跳变或偏移): 降低控制频率,切换到开环模式(比如VF控制),同时报警。
- 重度异常(卡死或饱和): 立即停机,切断PWM输出,防止炸管。
3.4 综合故障处理流程
在实际项目中,这三种故障往往同时出现。比如,采样电阻开路会导致运放饱和,运放饱和又会导致ADC读数异常。所以,我建议做一个统一的故障处理流程:
// 伪代码示例:电流采样故障检测
void Current_Sampling_Fault_Check(void)
{
// 1. 读取三相电流ADC值
adc_val[0] = ADC_Read(CHANNEL_U);
adc_val[1] = ADC_Read(CHANNEL_V);
adc_val[2] = ADC_Read(CHANNEL_W);
// 2. 检查ADC是否卡死
for (int i = 0; i < 3; i++)
{
if (adc_val[i] == last_adc_val[i])
{
adc_stuck_counter[i]++;
if (adc_stuck_counter[i] > 100)
{
Fault_Handler(FAULT_ADC_STUCK, i);
return;
}
}
else
{
adc_stuck_counter[i] = 0;
}
last_adc_val[i] = adc_val[i];
}
// 3. 检查运放是否饱和
for (int i = 0; i < 3; i++)
{
if (adc_val[i] > SATURATION_HIGH_THRESHOLD ||
adc_val[i] < SATURATION_LOW_THRESHOLD)
{
saturation_counter[i]++;
if (saturation_counter[i] > 10)
{
// 降功率处理
Current_Limit_Set(SAFE_CURRENT);
Fault_Handler(FAULT_OPAMP_SATURATION, i);
return;
}
}
else
{
saturation_counter[i] = 0;
}
}
// 4. 检查采样电阻开路(过压检测)
for (int i = 0; i < 3; i++)
{
if (adc_val[i] > OPEN_CIRCUIT_THRESHOLD)
{
open_circuit_counter[i]++;
if (open_circuit_counter[i] > 5)
{
Fault_Handler(FAULT_SHUNT_OPEN, i);
return;
}
}
else
{
open_circuit_counter[i] = 0;
}
}
}
嗯,这一讲的内容就到这里。电流采样故障,说白了就是“信号链路”的问题。从采样电阻到运放再到ADC,每一个环节都可能出问题。我的建议是:在设计阶段就做好冗余检测,在软件里做好故障分级处理。这样,即使出了问题,也能从容应对,而不是手忙脚乱地炸管。
下一讲,咱们聊聊“位置传感器故障”。霍尔传感器、编码器、磁编码器,各有各的脾气。到时候见。