做无感FOC的应该都有过这种经历:中高速段用反电动势观测器跑得好好的,转速一掉到几百转以下,估算角度就开始抖,电流波形跟着开叉,严重一点直接触发过流保护。这不是环路参数没调好,而是反电动势观测器在零低速段先天失效——反电动势幅值和转速成正比,转速一低信号就被采样噪声和死区谐波淹没。想把无感方案做到零速甚至带载启动,高频注入是目前工程上最成熟的路径。
这篇文章要聊的是一套基于STM32F4的完整高频注入工程,从源代码模块怎么组织,到原理图里那些关键电路为什么那么画,全部串起来讲。适合正在做无感FOC、低压伺服、压缩机或水泵驱动,尤其是卡在零低速启动这一关的人参考。工程上高频注入不算新东西,真正坑人的是软件和硬件之间的配合,比如采样窗口对齐、滤波相位延迟、保护电路误触发,这些细节才是决定方案能不能落地的关键。
1. 高频注入到底在解决什么问题
1.1 无感FOC的死区:为什么零低速会失控
FOC矢量控制的本质是把定子电流分解到转子d-q坐标系里,分解的前提是你得知道转子在哪里。带了编码器或霍尔,角度直接读就行;无感方案里这个角度靠观测器估。中高速段,反电动势观测器工作得非常好,因为它要用的反电动势信号足够大,随便一个二阶滑模或者龙伯格观测器都能锁得住。
可转速接近零时,反电动势趋近于零,信号完全埋进噪声里,观测器反馈的误差信息没有了,角度自然漂。更麻烦的是,FOC坐标变换本身对角度误差非常敏感——角度偏个十几度,q轴指令电流实际有一半分量被映射到d轴上,电机会出现力矩波动、启动堵转甚至反转。这就是所谓零低速死区。
高频注入的思路绕开了反电动势,改从“高频阻抗随转子位置变化”这个物理特性下手。电机转不转,转铁芯位置总在那里,铁芯磁路的凸极效应就带出了位置信息。换句话说,高频注入用的是一种跟转速无关的物理信号,这就是它能搞定零速的根本原因。工程上要解决的核心问题也很明确:如何把一个微弱的、被基波电流和开关纹波包裹的高频位置信号提取出来。
1.2 注入信号是怎么“看”到转子位置的
往定子绕组里叠加一个高频电压,高频电压会在绕组里激发出高频电流分量。这个分量的幅度和相位,由定子高频阻抗决定。关键来了:在高频激励下,d轴和q轴电感是不相等的,尤其是内置式永磁电机,d轴磁路比q轴多了一段气隙,电感小不少,这个不对称就叫凸极效应。
当高频电压方向扫过转子不同位置时,高频电流响应的大小会发生周期性变化,变化规律里就藏着转子角度信息。原理上很像医学上的造影剂——往血管里注入造影剂,然后再拍片子,血管的走向就看得清清楚楚。高频注入也是这个意思,注入的是电压“造影剂”,读取的是高频电流“影像”。
对表贴式永磁电机来说,d轴和q轴磁路结构基本对称,凸极效应不明显,但主磁路一旦饱和,d轴电感会随转子位置发生非线性变化,也会产生可以利用的等效凸极效应。所以高频注入在SPMSM和IPMSM上都能用,只是信号强度和调试难度不同。实际工程里,表贴电机的信号会比内置式弱不少,对采样电路和滤波器的要求更高。
1.3 旋转注入和脉振注入怎么选
高频注入有两大流派。旋转高频电压注入是在静止坐标系注入一个旋转的高频电压矢量,高频电流响应会形成一个椭圆,椭圆的扁率和指向跟转子位置相关,解调上要做同步旋转坐标变换和陷波处理,算法量偏大,但对凸极率要求相对低,早期很多学术实现都用它。
脉振高频电压注入是在估计的d轴方向注入一个余弦高频电压,然后从q轴高频电流响应里解调出位置误差信号,再送给锁相环收敛。它的优势是信号链路短、参数少、实现直接,工程上调试起来清晰很多。我在实际项目里基本固定用脉振注入,原因就是可控性强:注入电压、频率、解调滤波器、PLL带宽,每一级都能独立调,出问题也容易定位。
脉振注入有个前提,电压矢量要注入到估计的d轴上,估计角度和真实角度有偏差时,q轴电流里才会出现误差分量。也就是说,这个方法天然就是为“位置误差观测器”设计的,和PLL结构是绝配。工程落地时,我建议优先考虑脉振注入,先把一条链路跑通,再去研究旋转注入的改进方案。
2. 完整工程的软硬件架构拆解
2.1 系统框架怎么搭
整套工程以STM32F4系列MCU为核心,外围分成功率驱动、电流采样、电压采样、保护逻辑四块。软件侧按实时性要求拆成三层:主循环负责通信和参数整定,中等优先级任务负责启停逻辑和速度环,最高优先级的电流环中断负责执行FOC、高频注入和位置观测器。
顶层数据流是一条客户现场很好理解的主干:电流环中断周期一到,ADC同步采样三相电流和母线电压,完成坐标变换得到d-q电流;随后在估计d轴电压指令上叠加上注入频率的余弦信号;反向得到的电流分量经过带通滤波器提取高频分量,再与解调参考信号混频,经低通滤波器得到位置误差;误差进PLL,得到转子角度和速度,角度用于下一拍坐标变换。这一整条链路在每一个中断周期内都要执行完。
这样的架构好在哪儿?高频注入不是独立的模块,它和电流环、坐标变换混在同一块逻辑里。好处是延迟小、相位对齐容易。坏处是一旦某环节出问题,很难从外部判断是FOC的问题还是注入链路的问题。所以软件里要预留一个“旁路开关”,可以随时关闭注入、强制给定角度,用来做模块隔离测试。
2.2 原理图里的五个关键电路模块
功率级的核心是三相桥式电路,分立MOS管方案或者集成IPM方案都行。F4的TIM1高级定时器带互补输出和死区生成,六路PWM直接驱动能力强,通常外接栅极驱动器再驱动功率管。母线电容一定要紧贴功率管放置,这是吸收开关尖峰的第一道防线,很多布局上的啸叫和过压问题都是这脚电容位置摆远了造成的。
电流采样我建议采用低边采样电阻加分差运放的方案。成本低,精度足够,采样电阻放低边,运放把毫伏级压差放大到ADC的满量程范围。要特别注意的是运放的带宽,高频注入信号的频率通常在1kHz左右,但PWM开关毛刺的频谱非常高,运放带宽太低会把有用的注入信号压衰减,太高又把毛刺全采进来。实测选带宽在几MHz到十几MHz之间,并且加上RC低通滤波,是比较稳的组合。
母线电压采样用电阻分压加电压跟随器,精度要求不高,但响应速度要够,因为过压保护要依赖这个值。过流保护必须做成硬件级的——采样电阻信号直接连滞回比较器,比较器输出接MCU的刹车输入引脚,过流时硬件直接关断PWM输出,完全不依赖软件响应时间。这块设计不好,软件写得再漂亮,管不住炸管的瞬间。
2.3 软件分层和实时性规划
F4系列主频不算高,跑高频注入+FOC需要精打细算。电流环中断频率我一般定在10kHz到16kHz,再高意义不大,反而把注入频率和滤波器的设计空间压窄。中断里的任务按固定顺序执行:先读ADC,再做Clark/Park变换,然后注入叠加,执行电流PI,做SVPWM调制,最后跑观测器。每一步都要求用硬件浮点,F4自带FPU,算这些三角函数和滤波公式损耗很低。
非实时任务全部挪到主循环,用状态机管理。有人喜欢把速度环也放中断里,但在高频注入工程里我不建议,因为观测器收敛过程需要跟速度环做交互,速度环频率和电流环一样高会导致注入信号和速度环耦合,调试的时候很难判断是哪个环节出问题。主循环里跑1kHz速度环就足够了,还能腾出资源做数据上报和监控。
观测器代码单独放在一个.c文件里,输入是解调后的位置误差,输出是角度和转速。这样做的好处是不管注入的物理实现怎么变,观测器接口一直稳定。后面如果从脉振注入改成旋转注入,只需要换解调部分,PLL观测器完全复用。
3. 源代码关键模块实现细节
3.1 高频注入电压的生成与叠加
脉振注入的电压指令是加在估计d轴上的,代码上最直接的位置是在Park逆变换之前把注入量加到ud_ref上。这样注入的电压会经过坐标变换,跟随估计角度旋转,实现“始终沿着估计d轴方向脉振”的效果。
// 电流环中断内,Park逆变换之前叠加注入量 // ud_ref 来自电流环PI输出,hf_alpha是查表得到的高频正弦值 #define HF_INJECT_FREQ_HZ 1000.0f #define HF_INJECT_AMPLITUDE 0.05f // 相对母线电压的百分比 float hf_sin_val = arm_sin_f32(hf_angle); // 查表生成注入信号 ud_ref += HF_INJECT_AMPLITUDE * vbus * hf_sin_val; hf_angle += 2.0f * PI * HF_INJECT_FREQ_HZ * dt; if (hf_angle >= 2.0f * PI) hf_angle -= 2.0f * PI;叠加位置放这里很关键。如果放在SVPWM的Duty计算之后,注入量会跟坐标变换解耦不彻底,产生不必要的q轴分量,影响解调精度。在ud_ref上叠加,是脉振注入最标准、也是工程上验证过的做法。
注入信号实时生成我习惯用查表法,预先算一个周期的高频正弦表,中断里每拍取一个值。保证同一时刻采样、解调和注入共用一个相位基准,这个“相位一致性”是高频注入工程实现的灵魂。
3.2 采样窗口与信号分离
高频注入工程里,ADC采样时机比FOC普通模式苛刻得多。普通FOC只要采样在PWM周期内错开开关沿就行,因为用的是基波电流。但这里采的电流还要拿去做1kHz高频信号解调,而PWM本身在10kHz附近产生了大量开关纹波,如果ADC触发点离开关沿太近,纹波会直接淹没问题信号。
正确做法是把ADC触发点设在PWM载波中心。载波中心是上下桥臂都处于导通或关断的稳态期,开关动作全部完成,电流纹波最小。配合F4的ADC注入组通道,在定时器更新事件后延迟一小段延时采样,实测毛刺能明显下降。
信号分离靠滤波器实现。我们在电流环中断里拿到的iq是混合信号,里面有基波电流、注入高频分量、开关纹波。开关纹波靠采样窗口躲掉,基波分量靠带通滤波器滤掉。带通滤波器的中心频率就是注入频率,用二阶IIR滤波器就能满足要求,系数在启动前算好:
// 二阶IIR带通滤波器系数计算,fs=16000,f0=1000,带宽约250Hz // 采用标准双线性变换法得到b0...b2和a1...a2 #define F_COEF_B0 0.0786f #define F_COEF_B1 0.0f #define F_COEF_B2 -0.0786f #define F_COEF_A1 -1.5528f #define F_COEF_A2 0.8428f确定系数后,q轴高频电流分量经过这个滤波器直接送入解调环节。滤波器Q值不要设太高,太高了通带窄但相位延迟大,后面会解释这个相位延迟是怎么影响角度估计的。
3.3 从高频电流到转子位置误差解调
脉振注入的解调查起来就一句话:把带通滤波后的q轴高频电流,乘一个同频率的解调参考正弦,再经过低通滤波器提取直流分量。这个直流分量正比于位置误差角的正弦值。
// 高频电流解调 float iqhf = iq_bandpassed; // q轴带通滤波后的高频电流 float demod = iqhf * arm_sin_f32(hf_angle); // 与注入信号同相相乘 float err_signal = lpf_1st(demod); // 一阶低通提取直流分量数学上,高频电流包含的q分量在混频后会产生一个含有2倍注入频率分量的项和一个直流项,低通滤波器把高频项滤掉,剩下的直流分量就是我们要的位置误差信号。这个误差信号进PLL,PLL输出估计转速和角度,角度再反馈回坐标变换和下一次注入方向。
这个错误信号有个特性,误差接近零时线性度最好,误差太大时信号会饱和。所以启动流程里要注意,不要一开始就给很大负载扭矩指令,让PLL先收敛到零附近再加载。否则误差信号本来就饱和,PLL可能收敛到错误的稳态点。
PLL的实现可以用标准二阶环路:
// PLL观测器核心 float omega_pll += Kp_pll * err_signal * dt; float theta_pll += omega_pll * dt + Ki_pll * err_signal * dt;PLL带宽不要超过100到200Hz比较合适。注入频率一般1000Hz左右,滤波器群延迟带来的滞后在低速段并不致命,但如果PLL带宽跟滤波延迟产生了推动力,很容易出现边收敛边抖的临界稳定现象。
3.4 注入幅值和频率怎么定
注入频率和幅值的选取有工程经验可循。注入频率要远低于PWM开关频率,保证注入电压在电流环带宽里有足够响应,同时又不能太低,太低会和基波电流耦合,滤波器很难分离。我的经验值:开关频率10到16kHz时,注入频率取载波的1/10到1/5,也就是1kHz到2kHz之间比较稳。
注入电压幅值一般在母线电压的3%到8%。太小,高频电流信号被系统噪声埋没;太大,会带来明显转矩脉动和损耗问题,也会浪费母线电压利用率。具体选多少,要看电机的凸极率。IPMSM凸极率高,3%可能就够了;SPMSM要按矫顽力和饱和状态加大到6%甚至8%。
我习惯这样做:先固定频率1kHz,把注入幅值从2%逐步往上加,观察解调后位置误差信号的信噪比,做到可靠起动的前提下选择尽量小的幅值。因为幅值越大,电机噪音和振动越明显,这不是单纯电气指标的问题,很多应用场合对NVH有硬性要求。
有一个常见的认识误区。有人觉得注入频率越高,信号分离越容易,就拼命提高注入频率。但高频电压激励下的定子铁芯涡流损耗会显著上升,电流采样运放的衰减也会随着频率升高而加剧。我实测过,频率到2kHz以上时,采样电阻上的压降衰减反而让注入信号的有效幅度下降,得不偿失。所以频率不是越高越好,采样电路的带宽得和注入频率匹配。
4. 原理图集成实践:布局与信号完整性
4.1 功率板布局和接地处理
原理图看起来只是画几个器件连线,真正决定高频注入工程能不能稳定跑的,是PCB布局。高频注入对采样信号的信噪比要求比一般FOC工程高,因为要提取的高频电流分量本来就很微弱,任何乱窜的开关噪声都是致命的。
功率地和模拟地必须单点连接,通常选在母线电容的负端,这个点也是功率回路di/dt最大的地方。采样电阻的地要单独走线回到这个单点,千万不要让采样回路和功率回路的电流共用一段铜皮。否则,功率电流的压降会直接叠加在采样信号上,注入信号会被完全淹没。我见过不少“原理图上仿真完美、上电就废”的方案,问题都出在地线没分开。
模拟地和数字地之间用0欧电阻或者磁珠在ADC附近单点相连,模拟电源和数字电源分开滤波。这里的原则是:所有敏感信号走线尽量短,运放的反馈电阻直接贴器件放,不要为了美观来回绕线。
4.2 采样调理电路的相位延迟
采样电路里面,电流采样运放、RC抗混叠滤波器、ADC内部的采样保持电路都会引入信号延迟。带宽越高的运放延迟越小,RC滤波的截止频率也必须足够高于注入频率。比如注入频率1kHz,RC滤波截止频率至少要放到20kHz以上,否则高频信号经过RC就被衰减了。
延迟的问题不只是幅度衰减。相位延迟直接影响解调结果的准确性。高频信号经过运放和滤波器,相位会滞后一个固定量。滞后等价于解调参考信号的相位跟实际高频电流相位错开了,混频后的直流分量会被压缩一个cos(延迟角)的系数。延迟越大,位置误差信号的增益越低,系统看起来就是“角度能收敛,但速度慢”。
这里可以做一个软件补偿。测量当前电路的群延迟,估算延迟时间t_delay,在解调参考信号里把高频角度向后做相位补偿即可。
// 相位补偿:hf_angle_compensated = hf_angle_record - 2*pi*f0*t_delay float phase_comp = 2.0f * PI * HF_INJECT_FREQ_HZ * 0.0005f; // 假设延迟500ns float demod_ref = arm_sin_f32(hf_angle - phase_comp);工程上更省事的做法是先把电路做宽带宽,然后实测波形后再做微调补偿。千万不要跳过测量直接盲补,相位方向搞反了会越补越差。
4.3 保护电路与PWM封锁
高频注入叠加在正常FOC输出上,会让电流波形里多出一层高频纹波。保护电路的阈值如果按基波电流峰值上限来设定,高频纹波很容易导致误触发过流保护。所以我建议过流比较器的阈值先留15%到20%的余量,等调试完成后根据实际高频纹波幅度再收紧。
保护链路必须有独立的硬件路径:采样电阻信号一路进ADC供软件用,一路进比较器供硬件保护用。比较器输出直接进MCU的高级定时器刹车输入引脚,配置成硬件事件,控制器停机后PWM输出直接变为安全状态。
另一个容易忽略的点是保护比较器滤波时间常数。滤波太强,过流信号会被延迟,失去保护意义;滤波太弱,开关尖峰又会毛刺触发。经验值是让比较器的传播延迟在200纳秒左右,但加一个小时间常数的RC滤波,抗住单个窄毛刺,同时又不会延迟整体保护反应。
4.4 原理图和源代码的接口约定
工程里最容易出问题的环节其实是接口对接。原理图里的引脚分配要跟代码里的宏定义完全一致,一旦这里错位,调试时搞半天还找不到问题。我会在项目初期就输出一张接口约定表,所有参与的人都照这个核对。
| 功能信号 | MCU引脚 | 外设通道 | 备注 |
|---|---|---|---|
| 电流A采样 | PA0 | ADC1_IN0 | 采样电阻放大后输入 |
| 电流B采样 | PA1 | ADC1_IN1 | 同上 |
| 母线电压采样 | PA2 | ADC1_IN2 | 分压后输入 |
| PWM_U_H | PA8 | TIM1_CH1 | 互补输出CH1N_PB13 |
| PWM_V_H | PA9 | TIM1_CH2 | 互补输出CH2N_PB14 |
| PWM_W_H | PA10 | TIM1_CH3 | 互补输出CH3N_PB15 |
| 过流保护刹车 | PB12 | TIM1_BKIN | 硬件保护输入 |
这张表的意义不只是给硬件工程师看,软件开发者也按它来配置GPIO和DMA。代码里每个外设初始化都对应这个表来做,后续变更引脚只需要改一处表,不用到处翻代码。实测这种管理方式在跨团队协作时特别好用,能避免大量低级的连线错误。
5. 调试实录与常见问题排查
5.1 高频注入信号被系统噪声淹没
现象是解调输出怎么调都不见一个像样的误差信号,位置观测器转速乱飘。先不要怀疑算法,应该先用示波器测采样点电流波形,放大到高频分量尺度,看看能不能肉眼看到1kHz左右的纹波。
如果看不到纹波,问题大概率在注入电压没有真正加到电机上。检查注入叠加位置是不是在SVPWM之前,确认ud_ref叠加量有没有被电流环PI输出清零——电流环稳态输出较小,PI输出完全可能吞掉这个小的叠加量。这时候可以临时把注入量加到500mV级别,看驱动波形是否有明显变化。
如果能看到纹波但解调出来还是噪声,检查带通滤波器的中心频率是不是跟注入频率一致。很多人直接拿网上代码里的系数套,采样频率一变,滤波器就偏了。正确做法是在代码里打印滤波器中心频率对应的几个标定点,把实际波形数据送给滤波器,看输出是否在1kHz处明显放大。
5.2 电流波形上的高频毛刺和采样窗口
现象是电流波形上叠加了一串极窄的毛刺,看起来像是高频污染。实际多半是ADC触发时间和PWM开关动作重合了,采样时刻正好落在开关沿附近。普通FOC不一定看得出问题,因为毛刺会通过PI调节平均掉,但高频注入解调对这种采样点抖动极其敏感。
解决方法是把ADC触发延时调开,尽量靠近载波中心的稳态区。用F4的高级定时器可以配置ADC触发点在周期内的任意位置。实测在10kHz开关频率下,触发点设定在载波中心前后1到2微秒范围内,毛刺最小。注意不要直接设在中心点,要留出一小段裕量给死区补偿。
如果毛刺依旧,看采样信号调理电路里有没有足够的抗混叠滤波。RC截止频率太高会漏进开关毛刺,太低会衰减高频注入信号。建议用两级滤波,一级在运放输入端滤射频,一级在ADC输入前滤开关纹波,分摊截止频率的压力。
5.3 位置收敛慢或者角度偏差
表现为能启动,但扭矩明显偏小,或者带载后速度压不住。这类问题首要怀疑对象是相位延迟。高频信号从采样到解调,经过的运放、RC滤波器、ADC采样保持都会引入相位延迟。延迟导致解调出来的误差信号幅度衰减,PLL等效增益下降,收敛自然慢。
排查时用信号发生器模拟一个1kHz信号注入采样链路,在MCU端用DAC或者串口把混频前的波形数据发出来,计算解调参考和实际信号的相位差。补偿后如果收敛速度明显改善,说明诊断对了。
另一个容易被忽略的问题是PLL带宽参数。PLL带宽取得太低,仿佛滤波器都稳定了,但角度对转速变化的跟踪却跟不上。补给带宽和滤波器延迟交互,在调试时要注意:拉低PLL带宽能压住抖,但收敛慢;拉高PLL带宽能提速,但又容易在带载时震荡。不要一对参数走到黑,带宽和滤波器Q值要联动调节。
5.4 带载启动瞬间的过流误触发
高频注入信号在启动瞬间叠加在电流指令上,如果启动时负载角还没收敛,d轴电流突加,瞬时电流峰值可能越过保护阈值。常见做法是在启动序列里对注入幅值和电流指令同时做斜坡,让信号渐变而不是阶跃跳变。
保护比较器除了加小时间常数滤波外,还可以在刹车控制里加一个软件消隐时间:过流事件发生瞬间,硬件保护立即生效,但在启动序列中短暂屏蔽刹车信号。这个要权衡风险,屏蔽时间建议不超过几个电流环周期,并且只在检测到PLL收敛后的有限窗口内允许。
比较器阈值不要一开始就设太紧。我的习惯是先按1.5倍额定峰值电流设阈值,跑通全流程后再逐步往下调。因为高频注入下电流纹波本身会比普通FOC大,阈值太紧会掩盖真正的调试问题,比如启动瞬间角度还没收敛却加载,这种只能从逻辑上解决,靠抬高阈值是掩盖不了本质的。
5.5 参数速查与调试顺序建议
高频注入系统的参数耦合度比普通FOC高,一个参数动了,往往要连带调好几个。我在实际项目里总结了一套推荐调试顺序,按这个顺序来找问题能省大量时间。
| 调试阶段 | 关键检查项 | 常用策略 |
|---|---|---|
| 开环注入测试 | 注入信号是否到绕组、采样是否可见 | 开环给角,示波器查纹波 |
| 解调链路验证 | 带通滤波器中心频率、相位补偿 | 信号发生器注入测试 |
| PLL收敛验证 | 位置误差信号是否平滑、PLL带宽 | 低速空载,看角度稳定性 |
| 带载启动验证 | 启动斜坡、保护阈值、电流环带宽 | 逐步加载并记录最优参数 |
| 全速域切换验证 | 高频注入段与反电动势段的切换 | 设置转速滞回区间平滑切换 |
每一阶段都要看到明确的波形或数据证据再进入下一阶段。跳步调试是我见过最多翻车的根源——直接跳到带载调试,如果位置收敛有问题,你根本分不清是注入没做好还是力矩环没调好。
说到这里,再分享一个我反复踩过的坑:初次调试时别一心追求所有环节都最优。先把注入频率固定在载波的十分之一,幅值设到5%,确保位置观测器转起来能看到一个稳定的转速信号,再慢慢优化。工程项目的成败往往不是算法多高深,而是每一步都走得扎实,高频注入尤其如此——每一步都有波形可看,有数据可查,耐心排查,改进方向清晰可见。