拓冰建站拓冰建站
首页 / 资讯中心 / 正文

中心对齐PWM与FOC电流采样:采样窗口、硬件搭法与STM32配置

做FOC最怕什么不是算法推不出来而是电流采样没弄明白一上电就冒烟。中心对齐PWM和电流采样是FOC里最基础也最容易踩坑的一对组合程序逻辑看着没问题但实际跑起来电流波形全是毛刺、过流保护乱跳严重的直接炸MOS管。这篇文章就把中心对齐PWM下单电阻、双电阻、三电阻采样的时间窗口、硬件搭法和ADC触发配置一条条捋清楚都是实际调板子出来的经验希望帮你少炸几块功率板。1. 项目概述为什么“采样窗口”是决定会不会炸机的关键1.1 中心对齐PWM到底和边沿对齐差在哪先把概念对齐。边沿对齐PWM的计数器是从0数到ARR数完立刻归零所以PWM的高电平要么贴着重载点要么贴在归零点波形不对称。中心对齐PWM则不同计数器从0加到ARR再往下减到0像一个三角波比较寄存器CCR决定翻转点输出脉冲自然落在三角波的中心区域。因为高电平围绕PWM周期中心对称所以叫“中心对齐”。FOC里用中心对齐PWM不是偶然。SVPWM的七段式输出要求三相开关状态在一个PWM周期内对称分布只有中心对齐模式能天然满足这个对称性谐波更小母线电压利用率也更好。但代价就是采样的时间关系复杂了不少。边沿对齐下你只要在重载中断里触发ADC采一次就行中心对齐下上下桥开关切换点在时间轴上是对称分布的采样点选在哪个位置直接决定你采到的是相电流还是开关噪声。1.2 采样错位会怎么把你带进炸机名单我见过太多“程序看起来没问题”的炸机案例最后定位下来都是采样时序的锅。中心对齐PWM下最常见的三种死法第一种采样点落在开关边沿附近。开关管在导通关断瞬间di/dt非常大采样电阻上会叠加一个尖峰电压如果这个尖峰幅度超过运放输入范围或触发过流比较器轻则过流保护误跳重则电流环拿到一个错误的反馈值PI控制器直接输出错误占空比。第二种采样滤波截止频率设得太低。很多人为了让ADC读数干净把RC滤波时间常数设得很大结果电流环的相位裕度全被滤波器吃掉了。电流环一旦出现相位滞后闭环就不稳定占空比越给越大直到母线电流超过MOS管极限。第三种死区时间配得太小。MOS管关断需要时间如果死区小于开关管的关断延时上下桥直通。直通瞬间的电流不是几十安培能形容的直接就是短路电流。这三种情况都指向同一个核心问题采样点的时间窗口必须算准、配稳。接下来我把时间轴一张张拆开。2. 核心原理中心对齐PWM下的采样时间轴2.1 计数器、ARR、CCR一个PWM周期的时间坐标以STM32高级定时器为例向上向下计数模式下计数器从0递增到ARR再从ARR递减到0。一个完整PWM周期包含2倍的ARR计数进来所以PWM频率f_PWM 定时器时钟 / (2 × (ARR 1))。举个例子定时器时钟72MHz要得到20kHz PWMARR 72MHz / (2 × 20kHz) - 1 1800 - 1 1799。计数器从0到1799需要1800个时钟周期约25微秒再减下来又是25微秒加起来50微秒一个PWM周期。比较寄存器CCR决定PWM占空比。注意中心对齐模式下CCR的距离是相对计数峰值/谷值对称的。假设某相CCR900计数器在上升阶段从0到900时输出高电平下降阶段从1800到900过程中也输出高电平两个高电平段都贴着三角波的峰值在时间轴上呈对称形态。这个对称形态直接决定了采样点的选择。三相FOC中SVPWM的占空比随电角度变化但三个PWM的高电平中心都在同一个计数时刻附近——通常是计数器等于0或者等于ARR的位置。这两个位置对应的就是零电压矢量此时三相下桥同时导通或者三相上桥同时导通。2.2 为什么零矢量是采样黄金窗口零矢量状态下要么三个上桥全开要么三个下桥全开所有相电流都通过同一侧的开关管流回。如果你用的是下桥臂采样电阻方案当三个下桥MOS都导通时三个采样电阻上各自流过本相电流这就是最理想的采样时刻。零矢量为什么好采因为开关状态固定没有高边低边切换的瞬间采样电阻上的电压基本上是平稳的直流电平只有电流纹波在叠加。ADC在这个时刻触发采到的数据信噪比最高。对比非零矢量状态某一相电流可能走上桥臂而不走采样电阻你无法从该电阻上直接得到这一相的电流。三相电流之间的关系是iaibic0所以理论上知道两相就能算第三相但这要求你采到的两相电流必须是同一时刻的值。如果两个采样点相隔太远电流在PWM周期内的波动会产生重构误差。中心对齐PWM的好处在于零矢量窗口在时间轴上是连续且对称的三相电流在零矢量期间都持续流过各自的采样电阻这给单电阻、双电阻、三电阻采样都提供了稳定的基础窗口。2.3 死区插入如何挤压采样窗口死区时间是中心对齐PWM绕不开的话题。互补PWM输出为了防止上下桥直通必须在一次开关切换的边沿插入一段“全关断”时间。这段死区会让PWM的实际有效电平和理论占空比略有偏差更重要的是它会挤压采样窗口。算一下最小可采样脉宽。假设PWM周期50微秒死区1微秒ADC采样保持时间1微秒采样电阻到运放再经过RC滤波的建立时间0.5微秒那么一个相脉冲至少要有约2.5~3微秒的持续时间采样点才不会落在死区或开关振荡区。转换成占空比3微秒 / 50微秒 6%。也就是说如果某一相的占空比小于6%在中心对齐PWM下该相脉冲宽度就不够采样直接采会采到不稳定的电平甚至死区噪声。这就是单/双/三电阻采样在低调制比或高调制比时都会遇到的“窗口不足”问题。3. 三种采样方案单电阻、双电阻、三电阻到底怎么搭3.1 三电阻采样搭法最直观但依然有坑三电阻采样的硬件结构最简单三个下桥臂各接一个采样电阻各自经过差分运放放大后送ADC。控制策略上在一个PWM周期的零矢量时刻三个ADC通道同时触发采样一组数据直接得到ia、ib、ic。这里的关键点是“同时”。三个相电流必须用同一个触发源同步采样否则采到的三个值不是同一时刻的电流重构或转换计算就会带误差。STM32上常用ADC的注入组多通道同时转换或者用两个以上ADC同步采样。三电阻的坑主要在低调制比区域。当电角度运行到某个扇区边界附近某一相占空比会接近0%或100%对应的高电平宽度可能小于最小可采样脉宽。这时候只靠零矢量时刻采三个电阻已经不够了工程上通常的做法是用另外两相的有效采样值去重构采不到的那一相或者做“最小脉宽补偿”把SVPWM输出的窄脉冲人为拉宽一点保证任何时刻至少三相电流都有可采窗口。三电阻方案因为每个电阻都承担满负荷电流发热和功耗也要认真算。选型时除了阻值精度还要考虑温漂和功率余量这部分后面专门讲。3.2 双电阻采样省一路采样通道但要处理扇区边界双电阻采样省掉一个采样电阻和一路运放只用两相下桥采样电阻。原理还是靠iaibic0采到任意两相后重构第三相。看起来简单实操里最大的问题在扇区边界。SVPWM有六个扇区每个扇区里有一相的占空比要么接近0要么接近100。在中心对齐PWM下这一相在零矢量期间根本没有有效电流流过对应的下桥采样电阻或者脉宽太窄采不了。这时候就必须切换到另外两个能采到的相。具体切换逻辑是这样的当电机电角度处于扇区边界比如C相下桥占空比接近0C相无法直接采样就采A相和B相C相电流 -(iaib)当换到另一个扇区可能A相无法采样就采B相和C相。这个扇区判断表和重构公式必须和SVPWM向量扇区完全对应一旦错位重构出来的第三相电流符号都是反的闭环一跑就飞车。我实际调双电阻时踩过这个坑扇区表是从网上抄的没注意自己的SVPWM用的是哪种零矢量分配方式结果在60度电角度附近电流反馈突然跳变电机一顿一顿的。后来花了一下午对着示波器逐扇区核对才发现零矢量顺序和重构表不匹配。还有一种兜底方案叫“PWM相移法”。在窄脉宽的扇区边界时刻把采样窗口不足的那一相脉冲稍微往PWM周期中心移一下人为创造出一个足够宽的采样窗口。代价是实际电压矢量的位置和理想值有一点偏差但电流环本身有调节能力这个偏差在现代MCU上足够小不会影响控制精度。3.3 单电阻采样成本最低但对时序最敏感单电阻方案在母线负端或直流侧放一个采样电阻。每个PWM周期内不同开关状态下流过这个电阻的电流对应不同的相。原理是在一个PWM周期中选两个不同时刻采样第一次采到某一相的电流第二次采到另一相的电流第三相用和为零重构。采样点通常选在两个非零矢量区间。在中心对齐PWM的三角波上升段和下降段分别会经过不同的开关组合。合理选择两个采样时刻正好让两次采样落在两个不同相的电流有效区间内。但单电阻的问题也最突出。第一最小采样窗口比双电阻更苛刻因为单电阻在每个开关状态下对应的可采样时间更短高调制比或低调制比下很容易找不到两个“窗口都足够宽”的时刻。第二开关切换瞬间的母线电流尖峰非常大单电阻信号上叠加的噪声比相电阻方案更严重滤波和采样延时必须严格控制。第三低速工况下相电流小信噪比差单电阻的零漂往往最明显。如果做无感FOC的启动阶段单电阻尤其容易出问题。电机还没转起来时电流很小采样电阻上的压降可能只有几毫伏运放偏置、ADC量化噪声都会把有效信号淹没。这种情况下要么加大采样电阻但效率会下降要么换双/三电阻方案要么在启动阶段用开环强拉一段再切闭环。从我个人的建议来说能上三电阻就上三电阻成本敏感再用双电阻单电阻留给对成本极端敏感且控制算法足够成熟的场景。4. 关键参数计算与STM32采样配置4.1 采样电阻、运放增益和RC滤波参数怎么算采样电阻选型是整个采样电路的起点。阻值太小信噪比差阻值太大损耗高、发热重。核心约束有两个ADC满量程和功率损耗。假设最大相电流I_peak10A采样电阻R_shunt0.01Ω那么采样压降V_sense 10A × 0.01Ω 0.1V。如果ADC参考电压是3.3V运放增益Gain可以取20倍满载时输出2V还有1.3V余量给动态过冲。功率损耗P I² × R 100 × 0.01 1W实际选型至少要2W额定功率的电阻还要考虑通风和PCB散热。RC低通滤波的截止频率fc 1 / (2πRC)。这个参数很关键fc要远高于电流环带宽通常电流环带宽在1kHz左右所以fc至少要在10kHz以上同时fc要低于PWM频率才能在ADC采样之前把开关纹波抑制掉。以20kHz PWM为例我一般取fc在50kHz~100kHz之间R取100ΩC取33nF左右算出来fc约48kHz再微调。这里有个很多人不知道的坑RC滤波的R不能太大。ADC采样瞬间内部采样保持电容会从外部RC网络抽取电荷如果R太大RC恢复时间太长采到的值会被拉低。所以R一般不要超过几百欧姆或者干脆在RC后面加一级运放跟随器做缓冲ADC再从运放输出端采样。4.2 STM32中心对齐PWM加ADC触发配置以STM32F405的TIM1为例给一份实际可用的配置思路。定时器部分时钟72MHz中心对齐模式1ARR1799得到20kHz PWM。TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_TimeBaseStructure.TIM_Prescaler 0; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_CenterAligned1; TIM_TimeBaseStructure.TIM_Period 1799; TIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseInit(TIM1, TIM_TimeBaseStructure); TIM_BDTRInitStructure.TIM_OSSRState TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState TIM_OSSIState_Disable; TIM_BDTRInitStructure.TIM_LOCKLevel TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime 72; // 72MHz下对应1us死区 TIM_BDTRInitStructure.TIM_Break TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput TIM_AutomaticOutput_Enable; TIM_BDTRInit(TIM1, TIM_BDTRInitStructure); TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update); TIM_CtrlPWMOutputs(TIM1, ENABLE); TIM_ARRPreloadConfig(TIM1, ENABLE); TIM_Cmd(TIM1, ENABLE);ADC部分使用TIM1的TRGO事件作为外部触发源配置ADC注入组采样。ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Resolution ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode DISABLE; ADC_InitStructure.ADC_ContinuousConvMode DISABLE; ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right; ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_T1_TRGO; ADC_InitStructure.ADC_ExternalTrigConvEdge ADC_ExternalTrigConvEdge_Rising; ADC_Init(ADC1, ADC_InitStructure); ADC_ExternalTrigConvCmd(ADC1, ENABLE); ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_84Cycles);注意一个细节中心对齐模式下Update事件发生在计数器达到0和达到ARR两个位置。也就是说每个PWM周期会触发两次TRGO对应两个零矢量采样点。实际使用时可以两个点都采同一个PWM周期内做一次均值或者比较能提高一点信噪比也能判断采样点是否落在稳定窗口内。如果你用双电阻或单电阻方案采样点不要死板地只用在零矢量时刻而是要根据当前扇区动态切换ADC触发时刻。STM32的ADC支持注入组和自定义触发偏移工程上常用定时器的CC4事件作为辅助触发在需要的位置额外启动一次转换。4.3 采样电路的PCB布局经验再好的参数配置PCB布局乱了照样炸。采样电阻到大电流走线一定要分开采样电阻的两个引脚直接用Kelvin接法引出采样线差分走线尽量等长、贴近不要和大电流路径共用一段铜皮。运放供电和ADC参考电压要做好去耦。开关电源的噪声会通过地平面耦合到采样信号里尤其是采样电阻的地和功率地上的噪声经常是电流波形的毛刺来源。我的习惯是采用单点接地功率地、控制地、模拟地在板子上某一点汇合避免噪声通过地环路进入采样回路。最后每个采样通道在接近ADC引脚的位置加一个100Ω串联电阻加一个1nF电容到地这个小滤波能挡住板上的高频串扰。这个位置不要再加大的电容否则又会把采样建立时间拖慢。5. 常见问题与排查技巧实录5.1 典型故障速查表故障现象可能原因排查方向电流波形全是毛刺采样点落在开关切换边沿用示波器看PWM中点检查ADC触发时刻过流保护启动瞬间误触发开关噪声叠加到运放输出检查RC滤波、保护比较器延时、采样窗口电流环发散占空比逐渐饱和采样滤波相位滞后过大提高RC截止频率或减小滤波时间常数某个电角度区间电流异常跳变双电阻/单电阻扇区表与SVPWM不匹配逐扇区开环验证重构公式电机转动一顿一顿像缺相零矢量采样窗口不足增大最小脉宽补偿或改用三电阻低速/启动阶段电流反馈噪声大采样电阻压降小信噪比不足增大增益、使用三电阻方案长时间满载运行后电流误差变大采样电阻温漂换成低温度系数合金电阻5.2 逐级定位问题的方法第一步一定是先看示波器。把探头夹在采样电阻两端观察零矢量时刻的波形是否平整。如果波形上有大尖刺或者毛刺先解决硬件噪声再去调软件。第二步看ADC实际采到的数值。固定一个电角度开环输出把ADC转换结果通过DMA抓出来打印和理论电流值对比。如果偏差恒定可能是偏置或标定问题如果偏差和占空比相关可能是采样窗口不够或采样点偏移。第三步检查采样点位置。用TIM1的TRGO触发一个GPIO翻转示波器同时看PWM输出和这个翻转信号确认ADC触发时刻确实在零矢量中心。很多人配完觉得没问题一测发现触发在边沿就是因为没做这个验证。第四步做闭环保护验证。系统上电前把电流环限幅设到很小比如0.5A先单步推电角度看电流反馈方向是不是和给定方向一致。如果方向反了多半是采样电阻位置接反或重构公式符号不对。确认反馈方向和增益没问题后再逐步放大限幅。5.3 我踩过的几个坑和教训第一个坑是RC滤波时间常数设计得太大。当时想让ADC读数“更干净”把截止频率设到了1kHz结果电流环带宽被滤波器拖到不到几百赫兹一加载就震荡。后来把截止频率提到100kHz电流环才恢复正常。滤波的目标不是把信号变成一条直线而是滤掉开关频率以上的噪声不能牺牲环路带宽。第二个坑是采样电阻温漂。满载跑了几分钟电流反馈慢慢偏大保护阈值越来越小最后过流保护频繁误触发。换了低温度系数的合金电阻后问题消失。做FOC如果长时间带载采样电阻的温漂指标一定要重视。第三个坑是死区时间配得不够。有一版用了500ns死区MOS管Qg比较大实际关断延时超出死区上电瞬间上下桥直通直接炸了一组MOS。后来查数据手册按开关管的实际关断延时留了一倍余量死区放到1.5微秒以上才稳定。第四个坑是双电阻扇区表顺序搞反。按照标准SVPWM的扇区划分写的重构逻辑但实际代码里的扇区编号和我参考的文档不一致结果每次换扇区时第三相电流突然反号电机跑起来一顿一顿还伴随剧烈噪声。后面把所有扇区逐一打印出来和理论波形对照才发现问题。我个人现在做FOC板子第一件事不是调控制算法而是先把PWM触发、ADC采样点、滤波参数和死区配置用示波器从头到尾验证一遍。采样时序这块如果没搞清楚算法调得再漂亮也是空中楼阁。希望这篇把中心对齐PWM下采样时间轴说清楚的梳理能帮你省下几块功率板的钱。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门