3. ADC触发同步设置

任务目标

在单电阻FOC系统中,电流采样依赖PWM载波周期内特定时刻的ADC触发。本案例目标是将ADC触发源配置为与PWM定时器同步,并确保触发时刻落在有效采样窗口内,从而保证相电流重构的准确性。

核心原理与配置要点

单电阻采样通常在PWM周期中心处(即载波谷值或峰值)触发ADC,此时三相下桥臂全部导通或上桥臂全部导通,母线电流与某一相电流对应关系最清晰。有效采样窗口由PWM死区时间、功率管开关瞬态和ADC采样保持时间共同决定。若触发时刻过早或过晚,采样值将包含开关噪声或超出导通区间,导致重构电流失真。

本案例基于STM32G4系列(HRTIM或高级定时器TIM1)实现,核心配置包括:

  • PWM定时器工作在中心对齐模式,计数周期为PERIOD;
  • ADC触发源选择定时器事件(如TIM1_TRGO或HRTIM事件),而非软件触发;
  • 触发时刻通过定时器的重复计数或比较寄存器偏移设定,使其对齐到载波中心;
  • ADC采样时间需小于有效窗口宽度,确保转换在窗口内完成。

关键完整代码

// 假设使用TIM1作为PWM定时器,ADC1为采样ADC
// 系统时钟 170MHz,PWM频率 20kHz,中心对齐模式
// PERIOD = 170e6 / (2 * 20e3) = 4250

#define PWM_FREQ        20000
#define SYS_CLOCK       170000000
#define PERIOD          (SYS_CLOCK / (2 * PWM_FREQ))  // 4250
#define DEADTIME_NS     200
#define ADC_SAMPLE_NS   100
#define TRIG_OFFSET     (PERIOD / 2)  // 中心对齐模式下的载波中心

// 死区时间和采样时间换算为计数值(近似)
#define DEADTIME_CLKS   (DEADTIME_NS * SYS_CLOCK / 1e9)   // 34
#define ADC_SAMPLE_CLKS (ADC_SAMPLE_NS * SYS_CLOCK / 1e9) // 17

// 有效窗口半宽 = (PERIOD/2 - DEADTIME_CLKS) - ADC_SAMPLE_CLKS
// 触发点应位于窗口中心附近,此处直接使用载波中心
void ADC_Trigger_Sync_Init(void)
{
    // 1. 配置TIM1为PWM中心对齐模式
    TIM1->CR1 |= TIM_CR1_CMS_1;          // 中心对齐模式1
    TIM1->ARR = PERIOD - 1;
    TIM1->PSC = 0;
    
    // 2. 配置PWM输出通道(以通道1为例)
    TIM1->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;  // PWM模式1
    TIM1->CCER |= TIM_CCER_CC1E;
    TIM1->CCR1 = PERIOD / 2;             // 50%占空比
    
    // 3. 配置死区时间
    TIM1->BDTR = (DEADTIME_CLKS & 0xFF) | TIM_BDTR_MOE;
    
    // 4. 配置TIM1_TRGO为更新事件(载波周期开始)
    TIM1->CR2 = (TIM1->CR2 & ~TIM_CR2_MMS) | TIM_CR2_MMS_1;  // MMS=010: 更新事件
    
    // 5. 配置ADC1触发源为TIM1_TRGO
    ADC1->CR2 |= ADC_CR2_EXTEN_0;        // 上升沿触发
    ADC1->CR2 |= ADC_CR2_EXTSEL_0 | ADC_CR2_EXTSEL_2;  // 选择TIM1_TRGO
    
    // 6. 配置采样时间(确保小于有效窗口)
    ADC1->SMPR2 |= ADC_SMPR2_SMP0_0 | ADC_SMPR2_SMP0_1;  // 约19.5周期,约115ns@170MHz
    
    // 7. 使能ADC和DMA(用于连续采样)
    ADC1->CR2 |= ADC_CR2_ADON;
    ADC1->CR2 |= ADC_CR2_DMA;
    
    // 8. 使能TIM1更新中断(用于控制环路同步)
    TIM1->DIER |= TIM_DIER_UIE;
    NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);
}

// 定时器更新中断:表示PWM周期开始,可在此启动FOC计算
void TIM1_UP_TIM16_IRQHandler(void)
{
    if (TIM1->SR & TIM_SR_UIF) {
        TIM1->SR &= ~TIM_SR_UIF;
        // FOC控制循环入口(电流采样已完成,因ADC触发早于中断)
    }
}

运行与验证方法

硬件连接:将TIM1通道1输出连接至示波器,同时将ADC1的触发输出(可通过GPIO复用或调试引脚引出)连接至示波器另一通道。

验证步骤:

  1. 编译并烧录代码,确保系统时钟配置为170MHz;
  2. 用示波器观察PWM输出波形,确认频率为20kHz、占空比50%、死区时间约200ns;
  3. 观察ADC触发信号(或通过调试寄存器读取ADC触发标志),确认触发频率与PWM一致(20kHz);
  4. 调整TRIG_OFFSET值(例如改为PERIOD/2 - 100),观察ADC触发时刻相对PWM中心点的偏移,确认触发点可调;
  5. 通过ADC采样结果验证:在电机运行时,若采样电流波形平滑无毛刺,说明触发时刻位于有效窗口内;若出现明显噪声尖峰,则需增大死区时间或调整触发偏移。

通过条件:示波器显示ADC触发频率严格等于PWM频率(20kHz±1%),且触发点位于PWM载波中心附近(偏差小于死区时间);电机运行时电流采样波形无明显开关噪声干扰。

常见问题

  • 触发时刻偏移:若采样电流在开关沿附近出现尖峰,将TRIG_OFFSET向载波中心方向调整,或增大死区时间。
  • 采样时间过长:若ADC采样时间接近或超过有效窗口宽度,需降低ADC分辨率或增加PWM周期。
  • 触发丢失:检查TIM1_TRGO映射是否正确,以及ADC外部触发极性设置是否匹配。