3、电流采样与ADC配置:双电阻/单电阻采样策略,GD32 ADC同步触发

电流采样是FOC控制环的「眼睛」。采样不准,后面PARK变换、PI调节全是白算。我见过不少工程师在仿真里跑得挺好,一上硬件电流波形就全是毛刺,查到最后都是ADC采样时序没对齐。

这一章咱们就聚焦GD32的ADC怎么配,才能让电流环跑得稳。双电阻和单电阻两种方案我都会讲,但说实话,工业产品里双电阻是主流,单电阻更多是为了省成本。

3.1 双电阻采样 vs 单电阻采样

先看个对比表格,心里有个底:

对比项 双电阻采样 单电阻采样
采样电阻数量 2个(下桥臂串联) 1个(直流母线串联)
相电流重构 直接测量两相,第三相计算 需根据开关状态重构
最低占空比限制 无 有(需保证采样窗口)
ADC通道数 2个(同步采样) 1个
成本 略高 低
适用场景 高性能伺服、工业驱动 低成本风机、水泵

双电阻采样的原理很简单:在电机三相中任意两相下桥臂串联采样电阻,测出这两相电流,第三相用基尔霍夫定律算出来。我习惯测U相和V相,W相直接 Iw = -(Iu + Iv)。这样ADC只需要两个通道,同步触发一次就搞定。

单电阻采样呢?它只在直流母线上放一个电阻。你得根据当前PWM开关状态,在特定时刻采样母线电流,再反推出各相电流。说白了,就是「猜」出三相电流。我在一个风机项目里用过,为了省5毛钱成本,结果调试花了两周——每次换向区附近电流重构都会出问题。

核心结论:如果你的产品对低速性能、零速带载有要求,老老实实用双电阻。单电阻在占空比低于10%或高于90%时,采样窗口会被压缩,重构误差会急剧增大。

3.2 GD32 ADC同步触发机制

FOC电流环要求两相电流在同一时刻被采样。如果ADC分时采样,哪怕只差几个微秒,在高速旋转时都会引入相位误差。GD32的ADC支持多种触发源,我推荐用定时器的TRGO事件来同步触发。

具体怎么做?

  1. 配置定时器:以TIMER0为例,设置中心对齐PWM模式。在计数器上溢或下溢时产生TRGO信号。
  2. 配置ADC触发源:将ADC的触发源选择为TIMER0的TRGO。GD32的ADC有规则组和注入组,电流采样用规则组就够了。
  3. 配置采样时间:确保ADC采样窗口落在PWM下桥臂导通区间内。

我贴一段核心配置代码,这是我在GD32F303上验证过的:

// 配置TIMER0产生TRGO
timer_parameter_struct timer_initpara;
timer_initpara.period = 3999;          // 10kHz PWM
timer_initpara.prescaler = 107;        // 108MHz / 108 = 1MHz
timer_initpara.alignedmode = TIMER_COUNTER_CENTER_ALIGNED;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(TIMER0, &timer_initpara);

// 使能TRGO输出(上溢/下溢事件)
timer_master_slave_sync_config(TIMER0, TIMER_MASTER_SLAVE_MODE_ENABLE);
timer_trigger_output_config(TIMER0, TIMER_MASTER_TRGO_UPDATE);

// 配置ADC0触发源为TIMER0 TRGO
adc_external_trigger_source_config(ADC0, ADC_INSERTED_CHANNEL, ADC0_1_EXTTRIG_INSERTED_T0_TRGO);
adc_external_trigger_config(ADC0, ADC_INSERTED_CHANNEL, ENABLE);

我的习惯:采样点选在PWM计数器下溢时刻。这时候下桥臂全部导通,相电流刚好流过采样电阻,信号最稳定。上溢时刻也可以,但要注意死区时间的影响。

3.3 采样时序与PWM对齐

为什么采样时序这么重要?你想想看,PWM开关动作会在母线上产生巨大的电流尖峰。如果ADC刚好在开关时刻采样,读到的值全是噪声。

正确的做法是:把采样窗口放在PWM周期的中间区域,避开开关沿。对于中心对齐PWM,下溢时刻(计数器=0)和上溢时刻(计数器=period)都是理想的采样点。

我画了一张时序图,帮你理清关系:

双电阻采样时序与PWM对齐 PWM_U PWM_V PWM_W CNT 上溢 上溢 下溢 下溢 下溢 ADC_TRIG 采样点 采样点 采样点 采样点对齐PWM下溢时刻,此时下桥臂全部导通,相电流流过采样电阻 避开开关沿噪声,确保ADC采样值真实反映相电流

从图上你能看到:ADC触发信号与PWM下溢时刻严格对齐。每次下溢,ADC同时采样两相电流。这个时序一旦确定,整个电流环的采样频率就固定了——就是PWM频率。

3.4 ADC配置实战要点

GD32的ADC有几个关键参数需要你注意:

  • 分辨率:12位是标配,但如果你母线电压只有12V,建议用12位。如果母线是48V或更高,12位也够用,但要注意采样电阻的功耗。
  • 采样时间:GD32的ADC采样时间可配置为1.5~239.5个ADC时钟周期。我一般设成13.5个周期,配合1MHz的ADC时钟,采样窗口约13.5μs。这个时间足够让采样电容稳定。
  • 转换模式:用规则组连续转换,但触发源要选外部触发。别用软件触发,软件触发没法保证和PWM同步。

我曾经踩过的坑:ADC时钟频率不能超过14MHz(GD32F303数据手册写的)。有次我为了加快采样速度,把ADC时钟配到了18MHz,结果转换结果非线性,电流波形像锯齿。后来查了三天才发现是时钟超限了。

下面是一个完整的ADC初始化代码片段,双电阻采样用:

// ADC0和ADC1同步初始化
void adc_current_sampling_init(void)
{
    // 使能ADC时钟
    rcu_periph_clock_enable(RCU_ADC0);
    rcu_periph_clock_enable(RCU_ADC1);
    
    // ADC时钟配置:ADCCLK = 108MHz / 8 = 13.5MHz
    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV8);
    
    // ADC0配置
    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 2);
    
    // 采样时间:13.5个周期
    adc_sampling_time_configure(ADC0, ADC_CHANNEL_0, ADC_SAMPLETIME_13POINT5);
    adc_sampling_time_configure(ADC0, ADC_CHANNEL_1, ADC_SAMPLETIME_13POINT5);
    
    // 外部触发配置(TIMER0 TRGO)
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_T0_TRGO);
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
    
    // 使能ADC
    adc_enable(ADC0);
    delay_1ms(1);
    adc_calibration_enable(ADC0);
    
    // ADC1配置(与ADC0相同)
    // ... 省略重复代码
}

3.5 采样值到实际电流的转换

ADC读到的值是数字量,你得把它转成实际电流值。公式很简单:

I_actual = (ADC_value / 4096) * Vref / R_shunt / Gain

其中:

  • ADC_value:ADC转换结果(0~4095)
  • Vref:ADC参考电压(通常3.3V)
  • R_shunt:采样电阻阻值(常用0.01Ω或0.005Ω)
  • Gain:运放放大倍数(通常20~50倍)

举个例子:ADC读到2048,Vref=3.3V,R_shunt=0.01Ω,Gain=20。那么实际电流 = (2048/4096) * 3.3 / 0.01 / 20 = 0.825A。

我的建议:在代码里用定点数做这个转换,别用浮点。GD32没有硬件浮点单元,浮点运算会拖慢电流环。我习惯把系数提前算好,存成Q15格式,每次采样后直接乘加就行。

3.6 单电阻采样的特殊处理

如果你非要用单电阻,有几个坑必须提前知道:

  • 采样窗口限制:当占空比接近0%或100%时,下桥臂导通时间太短,采样电容来不及稳定。我建议在代码里做占空比钳位,最小占空比不低于10%。
  • 换向区重构:在扇区切换时,两相同时换向,母线电流无法反映单相电流。这时候需要用上一周期的电流值做预测,或者插入额外的采样点。
  • ADC触发策略:单电阻需要在PWM周期内触发两次ADC——一次在中心,一次在边沿。GD32的注入组可以做到,但配置起来比双电阻麻烦不少。

说实话,除非成本压力极大,否则我不推荐单电阻。省下的几毛钱,最后都花在调试时间上了。

3.7 本章小结

电流采样是FOC控制环的地基。双电阻方案稳定可靠,采样时序与PWM对齐是核心。GD32的ADC支持外部触发,用TIMER0的TRGO信号就能实现同步采样。配置时注意ADC时钟频率、采样时间、触发源选择这三个关键点。