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 定时器触发:什么时候用它?

定时器触发不是不能用,但场景有限。我个人习惯在两种情况下用:

  1. 过采样场景:比如你想在一个PWM周期内采多次电流做平均,PWM触发只能给一个触发点,定时器可以连续触发。
  2. 低速电机或位置传感器采样:电机转速很低时,PWM频率可能只有几百Hz,这时候用定时器触发更灵活。

但要注意一个坑:定时器触发和PWM不同步。你想想看,定时器是独立运行的,它不知道PWM什么时候开关。如果你在MOS管开关瞬间触发了ADC,采回来的值就是噪声。我曾经踩过这个坑,后来加了一个硬件同步信号才解决。

避坑指南:

我曾经在无感启动阶段用定时器触发采样,结果观测器一直收敛不了。查了两天才发现——定时器触发时刻正好落在PWM开关边沿上,电流采样值全是毛刺。后来我把定时器同步到PWM的TRGO信号上,问题才解决。

所以,如果你非要用定时器触发,记得把它的时钟源同步到PWM的时基上。

2.4 软件触发:调试利器,量产慎用

软件触发,说白了就是你在代码里写一句 ADC_StartConversion()。这个方式在调试阶段非常方便——你可以随时触发一次采样,看看当前电流是多少。但量产的时候,我强烈不建议用。

为什么?三个原因:

  • CPU占用高:每次触发都要CPU介入,FOC控制周期本来就紧,你还要分心去管ADC。
  • 时序不可控:软件触发受中断优先级、代码执行时间影响,你没法精确控制采样时刻。
  • 噪声敏感:软件触发没法避开PWM开关噪声,除非你手动加延时——但延时又会影响控制周期。

我记得有一次帮客户调试,他们用软件触发做电流采样,结果电机低速时电流波形抖得厉害。我一看代码,ADC触发放在主循环里,采样时刻完全随机。后来改成PWM触发,问题立刻消失。

我的建议:

调试阶段可以用软件触发,方便灵活。但进入量产代码前,一定要切到PWM硬件触发。如果你实在想保留软件触发做诊断,可以加一个条件编译开关,量产时关掉。

2.5 三种触发方式的选型决策流程

为了让你更直观地理解怎么选,我画了一张决策流程图:

ADC触发源选型决策流程 选择ADC触发源 是否用于实时电机控制? 是 否 PWM硬件触发 是否需要过采样? 是 否 定时器触发 软件触发(调试) 选型建议 • 无感FOC、高频注入 → PWM触发(首选) • 过采样、低速采样 → 定时器触发(需同步PWM) • 调试、诊断、非实时 → 软件触发(量产前切走)

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零开销,你还有什么理由不用?