2. ADC触发源选择:PWM触发 vs 定时器触发 vs 软件触发
电流采样精度,说白了就是看你采样的那一刻对不对。你想想看,电机转起来的时候,电流波形是高频变化的,你什么时候去采,采到的值完全不一样。我刚开始做无感FOC的时候,就吃过这个亏——ADC触发源选错了,采回来的电流数据根本没法用,观测器直接发散。
所以这一节,咱们就把三种触发方式掰开揉碎了讲清楚。我个人习惯把触发源的选择看作是「采样同步」的第一步,这一步走歪了,后面滤波、校准全白搭。
2.1 三种触发方式的核心差异
先看一张对比表,心里有个底:
| 触发方式 | 触发时机 | 精度等级 | CPU占用 | 典型场景 |
|---|---|---|---|---|
| PWM触发 | PWM周期中点/边沿 | ⭐⭐⭐⭐⭐ | 极低(硬件自动) | 无感FOC、高频注入 |
| 定时器触发 | 固定时间间隔 | ⭐⭐⭐⭐ | 低(硬件自动) | 低速采样、过采样 |
| 软件触发 | 代码手动启动 | ⭐⭐⭐ | 高(轮询/中断) | 调试、非实时场景 |
嗯,这里要注意——精度等级不是绝对的,得看你怎么用。但PWM触发在电机控制里,确实是「天选之子」。
2.2 PWM触发:为什么它是首选?
做过无感驱动的朋友都知道,电流采样最怕什么?怕开关噪声。MOS管开关瞬间,电流波形上会叠加一个尖峰,你正好在那个时刻采样,采回来的值能偏出20%以上。
PWM触发的好处在于:你可以把采样点精确地放在PWM周期的中点。中点位置电流最平稳,开关噪声最小,而且正好对应相电流的平均值。我习惯用中心对齐PWM模式,这样ADC触发信号可以配置在计数器上溢或下溢时刻,硬件自动完成,CPU完全不用管。
核心配置要点(以STM32为例):
- PWM模式:中心对齐模式(Center-Aligned)
- 触发事件:计数器上溢(Update Event)或下溢
- ADC触发源:TIMx_TRGO(定时器触发输出)
- 采样时间:建议配置在PWM周期的50%处
我曾经在一个项目里,用边沿对齐PWM配合软件触发,结果电流波形毛刺多得没法看。后来改成中心对齐+PWM硬件触发,信噪比直接提升了12dB。说白了,硬件帮你干的事,别用软件去凑。
2.3 定时器触发:什么时候用它?
定时器触发不是不能用,但场景有限。我个人习惯在两种情况下用:
- 过采样场景:比如你想在一个PWM周期内采多次电流做平均,PWM触发只能给一个触发点,定时器可以连续触发。
- 低速电机或位置传感器采样:电机转速很低时,PWM频率可能只有几百Hz,这时候用定时器触发更灵活。
但要注意一个坑:定时器触发和PWM不同步。你想想看,定时器是独立运行的,它不知道PWM什么时候开关。如果你在MOS管开关瞬间触发了ADC,采回来的值就是噪声。我曾经踩过这个坑,后来加了一个硬件同步信号才解决。
避坑指南:
我曾经在无感启动阶段用定时器触发采样,结果观测器一直收敛不了。查了两天才发现——定时器触发时刻正好落在PWM开关边沿上,电流采样值全是毛刺。后来我把定时器同步到PWM的TRGO信号上,问题才解决。
所以,如果你非要用定时器触发,记得把它的时钟源同步到PWM的时基上。
2.4 软件触发:调试利器,量产慎用
软件触发,说白了就是你在代码里写一句 ADC_StartConversion()。这个方式在调试阶段非常方便——你可以随时触发一次采样,看看当前电流是多少。但量产的时候,我强烈不建议用。
为什么?三个原因:
- CPU占用高:每次触发都要CPU介入,FOC控制周期本来就紧,你还要分心去管ADC。
- 时序不可控:软件触发受中断优先级、代码执行时间影响,你没法精确控制采样时刻。
- 噪声敏感:软件触发没法避开PWM开关噪声,除非你手动加延时——但延时又会影响控制周期。
我记得有一次帮客户调试,他们用软件触发做电流采样,结果电机低速时电流波形抖得厉害。我一看代码,ADC触发放在主循环里,采样时刻完全随机。后来改成PWM触发,问题立刻消失。
我的建议:
调试阶段可以用软件触发,方便灵活。但进入量产代码前,一定要切到PWM硬件触发。如果你实在想保留软件触发做诊断,可以加一个条件编译开关,量产时关掉。
2.5 三种触发方式的选型决策流程
为了让你更直观地理解怎么选,我画了一张决策流程图:
2.6 实际项目中的配置示例
拿我最近一个项目来说,主控是STM32G4,PWM频率20kHz,中心对齐模式。ADC触发配置如下:
// 配置PWM1的TRGO为更新事件
TIM1->CR2 |= TIM_CR2_MMS_1; // 010: 更新事件作为TRGO
// 配置ADC1的触发源为TIM1_TRGO
ADC1->CFGR2 |= ADC_CFGR2_JEXTEN_0; // 使能外部触发
ADC1->CFGR2 |= (6 << ADC_CFGR2_JEXTSEL_Pos); // 选择TIM1_TRGO
// 配置采样时间(确保避开开关噪声)
ADC1->SMPR1 |= (0b111 << ADC_SMPR1_SMP0_Pos); // 采样周期640.5个ADC时钟
嗯,这里要注意——采样时间不能太短。我习惯把采样时间配置在600个ADC时钟以上,这样采样电容有足够时间充电,精度才有保障。
2.7 总结一下
三种触发方式,各有各的用武之地。但如果你问我,做无感FOC电流采样,PWM触发就是最优解,没有之一。定时器触发可以作为补充,软件触发只配待在调试代码里。
你想想看,硬件帮你把采样时刻精确到纳秒级,CPU零开销,你还有什么理由不用?