1. 项目概述
在电机控制领域,FOC(Field Oriented Control,磁场定向控制)技术已经成为高性能电机驱动的黄金标准。而电流采集作为FOC控制中最关键的反馈环节,其精度和实时性直接决定了整个控制系统的性能表现。最近我在一个基于STM32的BLDC电机控制项目中,深入研究了FOC电流采集的实现方案,这里将完整分享从硬件设计到软件实现的全部技术细节。
对于使用STM32进行FOC开发的工程师来说,电流采集常常是第一个需要攻克的难关。不同于普通的ADC采样,FOC对电流采集有着严苛的要求:需要同步采样两相电流(第三相可通过计算得出),采样时刻必须精确对齐PWM中心点,还要处理运放偏移、ADC非线性、噪声抑制等一系列问题。本文将基于STM32G4系列MCU,详细解析三相电流采集的完整实现路径。
2. 硬件设计要点
2.1 电流采样拓扑选择
在FOC系统中,常见的电流采样方案主要有三种:
- 低侧采样:在MOSFET的下桥臂与地之间串联采样电阻
- 高侧采样:在电源正极与MOSFET上桥臂之间串联采样电阻
- 相线采样:直接在电机相线上串联采样电阻或使用电流传感器
我们最终选择了低侧采样方案,主要基于以下几点考虑:
- 电路简单,无需高压差分运放
- 采样时刻容易控制(在下桥臂导通时采样)
- STM32内置PGA(可编程增益放大器)可直接连接
注意:低侧采样需要特别注意"采样窗口"问题。当PWM占空比接近100%时,下桥臂导通时间过短可能导致无法完成有效采样。我们的解决方案是限制最大占空比为95%,确保至少有5%的时间用于电流采样。
2.2 运放电路设计
虽然STM32G4内置PGA,但在大电流场合(>5A)仍建议使用外部运放进行信号调理。我们设计的运放电路关键参数如下:
c复制// 采样电阻:0.01Ω/1%精度/5W
// 运放增益:G = 1 + Rf/Rg = 20倍
// 带宽:≥100kHz(对应PWM频率20kHz时的5次谐波)
// 共模抑制比:≥80dB
实际PCB布局时特别注意:
- 采样电阻采用开尔文接法,避免引线电阻影响
- 运放输入走线严格对称,等长处理
- 模拟地与数字地单点连接,避免地环路干扰
3. 软件实现解析
3.1 ADC配置要点
STM32的ADC配置对电流采样精度至关重要,以下是我们的核心配置参数:
c复制hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // 确保采样时钟≤60MHz
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE; // 多通道扫描模式
hadc1.Init.ContinuousConvMode = DISABLE; // 非连续模式
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_HRTIM_TRG1; // 由HRTIM触发
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 2; // 两相电流同步采样
hadc1.Init.DMAContinuousRequests = ENABLE;
关键点说明:
- 使用HRTIM定时器精确触发ADC采样,确保与PWM中心对齐
- 采样时间设置为47.5个ADC时钟周期(对应1.5μs@32MHz)
- 启用DMA双缓冲模式,避免采样数据丢失
3.2 电流重构算法
在低侧采样方案中,我们只能在对应下桥臂导通时采样电流。因此需要通过特定算法重构三相电流:
c复制void FOC_CurrentReconstruct(float *Iabc, uint8_t sector) {
switch(sector) {
case 1: // 采样Iu和Iv
Iabc[0] = AdcValueToAmpere(ADC1->JDR1);
Iabc[1] = AdcValueToAmpere(ADC1->JDR2);
Iabc[2] = -Iabc[0] - Iabc[1];
break;
case 2: // 采样Iu和Iw
Iabc[0] = AdcValueToAmpere(ADC1->JDR1);
Iabc[2] = AdcValueToAmpere(ADC1->JDR2);
Iabc[1] = -Iabc[0] - Iabc[2];
break;
// ...其他扇区类似处理
}
}
4. 校准与补偿技术
4.1 零点偏移校准
即使没有电流通过,ADC采样值也可能不为零。我们在系统启动时执行自动校准:
c复制void CurrentOffsetCalibrate(void) {
float sum_u = 0, sum_v = 0;
for(int i=0; i<1024; i++) {
sum_u += AdcValueToAmpere(ADC1->JDR1);
sum_v += AdcValueToAmpere(ADC1->JDR2);
HAL_Delay(1);
}
g_offset_u = sum_u / 1024;
g_offset_v = sum_v / 1024;
}
4.2 增益补偿
由于运放增益误差和电阻容差,两相电流的增益可能不一致。我们通过注入直流电流进行增益校准:
- 给U相注入1A直流电流(V相开路)
- 记录ADC采样值ADCu
- 给V相注入相同电流,记录ADCv
- 计算增益补偿系数:Kv = ADCu / ADCv
5. 实测性能优化
5.1 噪声抑制技巧
在实际测试中,我们发现电流采样存在高频噪声,通过以下措施显著改善:
- 在运放输入端增加RC滤波(100Ω+100nF)
- ADC采样时刻避开PWM边沿(设置死区时间后延迟1μs采样)
- 软件端采用移动平均滤波(窗口长度=4)
5.2 动态响应测试
使用阶跃负载测试电流环响应,原始波形显示有约10%的超调。通过调整以下参数优化:
- 降低电流环PI控制器的积分增益Ki
- 增加ADC采样触发提前量(从PWM中心点提前500ns)
- 启用STM32的ADC过采样功能(4倍过采样+右移2位)
优化后测试结果显示:
- 电流控制带宽:从1.2kHz提升到1.8kHz
- 阶跃响应超调:从10%降低到3%
- 稳态误差:<0.5%
6. 常见问题排查
6.1 采样值异常跳动
现象:ADC采样值偶尔出现大幅跳变
排查步骤:
- 检查PCB布局,发现电流采样走线与PWM信号线平行
- 重新布线,使模拟信号与数字信号正交走线
- 在采样电阻两端增加0.1μF陶瓷电容
解决效果:采样跳动从±5LSB降低到±1LSB
6.2 电流重构误差大
现象:三相电流之和不为零
可能原因:
- 两相增益不一致(可通过增益补偿解决)
- 采样时刻不同步(检查HRTIM触发配置)
- ADC采样时间不足(增加采样时钟周期数)
6.3 高频振荡问题
现象:电机运行在高转速时出现啸叫
解决方案:
- 检查发现是电流环相位裕度不足
- 在PI控制器输出增加低通滤波(截止频率=5kHz)
- 重新整定PI参数,确保幅值裕度>6dB
经过完整的优化实施,我们的STM32 FOC系统最终实现了:
- 电流采样精度:±0.5% FS
- 动态响应时间:<100μs
- 最大采样更新率:100kHz(对应PWM频率20kHz)