ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

电机控制实战:PWM、ADC、RTOS与FOC关键环节调试指南

电机控制实战:PWM、ADC、RTOS与FOC关键环节调试指南 电机控制这个方向说它简单也简单说它复杂也复杂。简单在于一个直流有刷电机加个MOS管和PWM信号就能转起来复杂在于一旦涉及无感FOC、转子初始位置检测、ADC采样时序、RTOS任务调度这些环节任何一个细节没处理好电机要么不转要么抖要么直接炸管。我接触电机控制这些年从最基础的PWM调速到BLDC无感FOC踩过的坑比调通的参数多得多。这篇文章不打算写成教科书而是把电机控制这条链路上真正关键的几个环节——PWM、ADC、RTOS、FOC——拆开来讲清楚每个部分都说说为什么这么设计、实际调试中会遇到什么问题、怎么排查。不管你是刚入门想搞懂PWM怎么调速还是已经在调FOC但卡在某个环节应该都能从里面找到对自己有用的东西。1. 从PWM调速说起为什么方波能控制转速1.1 PWM调速的本质不是调电压而是调平均功率很多人第一次接触电机控制都是从“PWM调速”这四个字开始的。但不少人心里其实有个疑问PWM输出的是方波电压要么是高电平要么是低电平凭什么能控制电机转速答案在于电机的机械惯性远大于PWM的开关周期。假设PWM频率是20kHz周期就是50微秒而电机的机械时间常数通常在几十毫秒甚至几百毫秒量级。在这个50微秒的周期里电机转子根本来不及响应电压的跳变它感受到的是电压的平均值。这个平均值就是占空比乘以电源电压。占空比50%电源12V电机感受到的就是6V的平均电压。转速和平均电压近似成正比所以调节占空比就能调节转速。理解这一点很关键因为它解释了为什么PWM频率不能太低——如果PWM频率降到几百赫兹电机会在每一个周期内明显加速和减速产生可听噪声和转矩脉动甚至出现啸叫。那PWM频率是不是越高越好也不是。频率越高MOS管的开关损耗越大驱动电路的发热越严重。实际选型时有刷直流电机常用1kHz到20kHzBLDC和PMSM的FOC控制通常用10kHz到20kHz具体要看MOS管的开关特性和电机的电感值。我一般会先用10kHz跑通再根据发热和噪声情况往上调。1.2 PWM模式1和模式2的区别一个容易被忽略的细节如果你用的是STM32这类MCU的高级定时器配置PWM时会遇到“PWM模式1”和“PWM模式2”的选项。很多人随手选一个能用就不管了但在电机控制里这个选择会影响互补输出的死区行为。简单说PWM模式1下当计数器值小于比较值时输出有效电平PWM模式2则相反。对于单路PWM调速两者只是极性相反改一下占空比的计算方式就能互换。但在互补PWM输出场景下——比如三相逆变器的上下桥臂驱动——模式选择会影响死区插入后有效电平的分布。如果模式选错可能导致上下桥臂的导通时间出现异常重叠或间隙轻则波形畸变重则直通炸管。我的习惯是在配置阶段就明确统一用PWM模式1占空比寄存器直接写比较值这样代码可读性好团队协作时不容易搞混。如果硬件驱动芯片有反相要求在驱动端处理不要在PWM模式上反复横跳。1.3 死区时间不是加上去就万事大吉三相逆变器的上下桥臂不能同时导通否则电源直接短路。所以互补PWM之间必须插入死区时间。死区时间太短直通风险大太长输出波形畸变严重尤其在高占空比和低占空比区域有效电压会明显偏离预期。死区时间的计算取决于MOS管的关断延迟和驱动电路的传输延迟。一般来说MOS管的数据手册会给出开通延迟和关断延迟驱动芯片也有传输延迟参数。死区时间至少要大于“关断延迟减去开通延迟”的差值再留一定裕量。实际工程中我通常从500纳秒起步用示波器看上下桥臂驱动信号的死区是否足够再根据MOS管温度调整。这里有个容易踩的坑不同批次的MOS管关断延迟可能不一致。如果你用的是分立MOS管搭的逆变器死区时间要按最慢的那颗来设。我遇到过一批管子标称关断延迟200纳秒实际测出来接近400纳秒死区设了300纳秒结果直通炸了三颗管。后来养成习惯每批新管子都先测一下开关波形再定死区。2. ADC采样FOC控制的“眼睛”怎么擦亮2.1 电流采样的时机比精度更致命FOC控制的核心是实时获取三相电流然后通过Clarke变换和Park变换把交流量变成直流量去控制。如果电流采样时机不对采到的值根本不能反映真实的相电流后续所有计算都是错的。在三相逆变器中电流采样通常放在下桥臂导通期间。因为下桥臂导通时采样电阻上的电压直接反映相电流。但PWM是不断开关的下桥臂导通的时间窗口很窄。如果ADC采样时刻落在开关瞬间采到的就是振铃和噪声完全不能用。正确的做法是把ADC触发时刻对齐到PWM周期的特定位置。以中心对齐PWM为例计数器从0往上数到峰值再往下数回0。下桥臂导通通常发生在计数器接近0或者接近峰值的时刻。STM32的定时器可以配置ADC触发事件比如在计数器下溢时触发ADC采样。这样每次采样都落在下桥臂稳定导通的中点避开开关瞬间。我调试时习惯用示波器同时看PWM驱动信号和ADC采样触发信号确认采样点确实落在下桥臂导通窗口的中间位置。如果偏移了就调整定时器的触发比较值。这个步骤看起来简单但很多FOC跑不起来或者电流波形畸变根源就在采样时机偏了。2.2 ADC采样周期和信噪比的权衡ADC的采样保持时间决定了采样电容充电是否充分。如果采样时间太短采样电容没充到输入电压转换结果就偏低。如果采样时间太长虽然精度上去了但ADC转换总时间变长可能影响控制环路的实时性。对于电机电流采样信号源阻抗通常不高——采样电阻一般在毫欧到几十毫欧量级加上运放缓冲后阻抗更低。所以采样时间不需要设得太长。以STM32F407为例ADC时钟设为21MHz时采样周期设为15个时钟周期总转换时间大约1微秒左右。对于20kHz的PWM频率周期50微秒1微秒的转换时间完全够用。但要注意ADC的参考电压和电源噪声会直接影响信噪比。电机驱动板上开关噪声很大如果ADC参考电压不稳采样值会跳动。我的做法是在ADC参考引脚旁边放一个1微法到10微法的陶瓷电容尽量靠近引脚。另外电流采样运放的输出端加RC低通滤波截止频率设在PWM频率的十分之一左右比如PWM是20kHz滤波截止频率设2kHz能有效抑制开关噪声。2.3 多通道ADC切换的坑采样顺序影响结果FOC需要同时采样至少两相电流有时还要采样母线电压和温度。多个通道轮流转换时如果通道切换后立即启动转换采样电容可能还残留上一个通道的电荷导致串扰。STM32的ADC在多通道扫描模式下每个通道转换完成后会自动切换到下一个通道。但采样电容的电荷残留问题确实存在。解决办法是增加采样时间让采样电容有足够时间充到新通道的电压。或者在通道切换后插入一个空的采样周期作为“丢弃采样”不取转换结果只用来清掉残留电荷。我在实际项目中的做法是如果两个电流通道的电压差异不大采样时间设长一点就能解决如果差异大比如一相电流接近零而另一相电流很大就必须加丢弃采样。这个细节在数据手册里不会明说但实测中如果发现两相电流采样值有相关性异常基本就是通道串扰。3. RTOS在电机控制中的角色不是所有场景都需要3.1 裸机中断够用的时候别上RTOS很多初学者一上来就想用RTOS觉得任务调度看起来更“专业”。但电机控制的电流环通常跑在10kHz到20kHz也就是每50到100微秒执行一次。这个频率下用中断直接触发电流环计算是最直接、最确定的方式。RTOS的任务切换本身有开销如果电流环作为一个任务去调度任务切换的抖动可能达到几微秒甚至十几微秒对于高动态响应要求的场合是不可接受的。我的建议是电流环和PWM更新放在中断里用最高优先级。速度环和位置环可以放在RTOS任务里因为这些环路的执行频率低得多通常1kHz到5kHz就够了。通信、状态监测、参数存储这些对实时性要求不高的功能放在低优先级任务里。这样既保证了电流环的确定性又利用了RTOS管理复杂任务的优势。3.2 RTOS任务优先级分配的实际经验如果确实要用RTOS优先级分配是个关键问题。电流环中断的优先级必须高于所有RTOS任务这个不用讨论。在RTOS任务层面我的分配原则是这样的速度环任务优先级最高因为它直接影响电机的动态响应。通信任务优先级次之因为上位机可能随时发指令响应太慢会影响体验。状态监测和故障保护任务优先级再次之但要比参数存储和日志任务高。参数存储和日志任务优先级最低因为它们可以慢慢做不影响控制性能。这里有个容易忽略的点RTOS的tick中断和电流环中断可能产生优先级冲突。如果RTOS的tick中断优先级高于电流环中断tick中断会打断电流环计算导致电流环执行时间抖动。所以电流环中断的优先级必须高于RTOS的tick中断。在Cortex-M内核上RTOS的tick中断通常用SysTick它的优先级是可以配置的记得把它设得比电流环中断低。3.3 中断和任务之间的数据传递电流环在中断里算出来的电流值速度环任务需要读取。如果直接读全局变量可能读到一半被中断打断数据不一致。对于32位变量在Cortex-M上单次读写是原子的问题不大。但如果是一个结构体或者多个相关变量就需要保护。我通常用双缓冲或者环形缓冲区来传递数据。中断里往缓冲区写任务从缓冲区读。如果只是单个32位变量直接读写就行不用加锁。如果是一组数据用内存屏障或者关中断短暂保护一下。关中断的时间要尽可能短只保护数据拷贝那几行代码不要在整个计算过程中关中断。4. FOC控制的核心环节从Clarke到SVPWM4.1 FOC到底在控制什么FOC的全称是磁场定向控制。它的核心思想是把三相电流通过坐标变换分解成产生磁场的分量和产生转矩的分量然后分别控制。这样做的目的是让电机像直流电机一样好控制——直流电机通过独立控制励磁电流和电枢电流来实现转矩控制FOC就是把这个思路搬到交流电机上。具体来说三相电流Ia、Ib、Ic经过Clarke变换变成两相静止坐标系下的Iα和Iβ再经过Park变换变成两相旋转坐标系下的Id和Iq。Id控制磁场Iq控制转矩。对于表贴式永磁同步电机通常让Id等于零只控制Iq这样单位电流产生的转矩最大。这个变换过程听起来抽象但用代码实现并不复杂。Clarke变换就是几个乘法和加减法Park变换需要正弦和余弦值。正弦余弦可以用查表法或者CORDIC算法计算。查表法简单直接但精度受表长限制CORDIC算法精度高但计算量大一些。在STM32F4这类带FPU的MCU上直接调arm_sin_f32和arm_cos_f32就够快了。4.2 SVPWM和普通PWM的区别FOC的调制环节通常用SVPWM也就是空间矢量PWM。它和普通正弦PWM的区别在于SVPWM利用了两个相邻基本矢量和零矢量的组合来合成目标电压矢量电压利用率比正弦PWM高约15%。为什么高因为正弦PWM的相电压峰值最多到母线电压的一半而SVPWM通过注入零序分量可以让相电压峰值达到母线电压除以根号三也就是约0.577倍的母线电压。对于同样的母线电压SVPWM能输出更大的基波电压电机的最高转速也就更高。SVPWM的实现步骤是先判断目标电压矢量落在哪个扇区然后计算两个相邻基本矢量的作用时间和零矢量作用时间最后转换成三路PWM的比较值。扇区判断可以用Iα和Iβ的符号和大小关系来做也可以用反正切算出角度再判断。前者计算量小后者逻辑简单。我一般用前者因为电流环执行频率高能省一点计算时间是一点。4.3 无感FOC的转子位置估计滑模观测器的实际调参无感FOC最大的难点是不知道转子位置。有传感器的时候编码器或者霍尔直接告诉你角度无感的时候只能从电机的电压和电流反推。常用的方法是滑模观测器或者龙伯格观测器。滑模观测器的思路是构造一个电流观测器让观测电流和实际电流的误差趋近于零。当误差趋近于零时观测器中的切换项就包含了反电动势的信息从反电动势就能算出转子角度。听起来很美好但实际调参很头疼。滑模增益太小观测器收敛慢低速时角度估计不准增益太大抖振严重电流波形毛刺多。我的经验是从小增益开始逐步加大同时观察电流波形和角度估计的波动。如果电流波形出现明显毛刺说明增益太大了。另外滑模观测器在低速时反电动势很小信噪比差所以通常需要配合高频注入或者IF启动来覆盖低速段。IF启动就是先不管转子位置强制给一个旋转的电流矢量让电机先转起来等转速升到一定值再切换到无感观测器。切换时机很关键切早了观测器还没收敛电机会失步切晚了浪费启动时间。我一般会在转速达到额定转速的10%到15%时切换切换前先让观测器和IF并行运行一段时间确认观测器角度和IF角度接近了再切。5. 调试工具和排查思路示波器之外还需要什么5.1 串口波形输出低成本但有效的调试手段不是每个人都有高端示波器和电流探头。串口输出关键变量到上位机画波形虽然采样率低但对于观察速度环响应、角度估计趋势、电流环给定和反馈的跟随情况已经够用了。我的做法是在电流环中断里把关键变量存到缓冲区然后在低优先级任务里通过串口发出去。缓冲区用环形结构避免数据覆盖。上位机用Python或者现成的串口示波器工具画图。注意串口波特率要够高至少921600否则数据发不完会丢帧。这个方法的好处是不需要额外硬件而且能同时观察多个变量的长期趋势。缺点是采样率受串口带宽限制看不到高频细节。所以串口波形用来调速度环和观察趋势电流环的高频细节还是得靠示波器。5.2 常见故障的排查顺序电机控制调试中遇到问题我一般按这个顺序排查先确认PWM输出是否正常。用示波器看六路PWM驱动信号确认频率、占空比、死区都符合预期。如果PWM不对后面都不用看。然后确认ADC采样是否正常。让电机静止给一个固定的PWM占空比看ADC采到的电流值是否合理。如果电流值跳动很大或者明显不对检查采样时机和滤波电路。接着确认角度估计是否收敛。如果是无感FOC让电机开环转起来观察观测器输出的角度是否平滑变化。如果角度跳动或者不变化检查观测器参数和反电动势计算。最后确认电流环和速度环的PI参数是否合理。先调电流环给一个阶跃的Iq给定看Iq反馈的响应。超调太大就减小比例增益响应太慢就增大比例增益。电流环调好了再调速度环。这个顺序的核心逻辑是从底层到上层从硬件到软件。底层不对上层怎么调都是白费。5.3 开源固件的参考价值VESC和Moteus是两个比较知名的开源电机控制固件。VESC偏重电动滑板和电动车的应用功能全但代码量大。Moteus偏重机器人和精密控制代码结构清晰适合学习FOC的实现细节。我的建议是不要一上来就啃VESC的全部代码容易迷失。先看Moteus的FOC核心部分理解Clarke、Park、SVPWM、观测器这几个模块怎么组织和调用。然后自己动手写一个最小FOC实现哪怕性能差一点但每一行代码都是自己写的理解会深得多。等最小实现跑通了再去看VESC怎么处理故障保护、参数识别、通信协议这些工程化的问题。看开源代码时特别注意它的中断优先级配置和ADC触发配置这两个地方最能体现作者对实时性的理解。如果中断优先级配错了再好的算法也跑不出效果。6. 从能转到转好几个容易被忽视的工程细节6.1 母线电压采样和过压保护母线电压采样看起来简单分压电阻加ADC就完事了。但电机减速时电机会变成发电机能量回馈到母线母线电压会升高。如果没有过压保护电容可能炸MOS管可能击穿。我的做法是在母线电压采样基础上加一个比较器硬件比较器直接触发PWM关断不经过软件。软件里也做母线电压监测但软件响应有延迟硬件保护是最后一道防线。比较器的阈值设在电容耐压的80%左右留一定裕量。另外分压电阻的精度和温漂要注意。电机驱动板温度变化大普通电阻的温漂可能导致电压采样偏差。我用的是低温漂的金属膜电阻分压比计算好后实际测一下根据实测值微调软件里的换算系数。6.2 电流采样运放的共模抑制三相电流采样通常用采样电阻加差分运放。运放的共模抑制比直接影响电流采样精度。电机驱动时采样电阻两端的共模电压会在零到母线电压之间跳变如果运放共模抑制比不够输出会有很大误差。选运放时共模抑制比至少要80dB以上带宽要足够覆盖PWM频率的谐波。另外运放的输入共模范围要包含零伏因为下桥臂导通时采样电阻两端的共模电压接近零。如果运放输入共模范围不包含零低占空比时电流采样会失真。我在一个项目里用过一款运放数据手册标称共模抑制比85dB但实际在低占空比时电流采样明显偏低。后来换了另一款轨到轨输入输出的运放问题解决。所以选型时不要只看数据手册的典型值有条件的话实际测一下。6.3 参数识别的必要性电机的相电阻和相电感直接影响电流环PI参数的整定。如果不知道这两个参数PI参数只能试凑效率低而且效果不一定好。参数识别就是通过给电机施加特定的电压脉冲测量电流响应从而算出电阻和电感。相电阻的测量比较简单给电机某一相通一个已知电压测量稳态电流电压除以电流就是电阻。相电感的测量稍微复杂给电机施加一个电压阶跃测量电流上升的斜率斜率等于电压除以电感。有了电阻和电感电流环的PI参数就可以按公式算出来。比例增益等于电感乘以带宽积分增益等于电阻乘以带宽。带宽一般取电流环执行频率的十分之一到五分之一。比如电流环跑10kHz带宽取1kHz到2kHz。这样算出来的PI参数比试凑法靠谱得多而且有理论依据调整方向明确。6.4 温度对参数的影响电机的相电阻随温度升高而增大铜的电阻温度系数大约是每摄氏度0.4%。如果电机从室温25度升到100度电阻增大了30%。如果电流环PI参数是按冷态电阻整定的热态时响应会变慢。解决办法有两种一是留足够的带宽裕量让PI参数在电阻变化范围内都能稳定二是用温度传感器实时监测电机温度根据温度修正电阻值进而修正PI参数。第一种方法简单但带宽裕量留太多会影响动态响应。第二种方法复杂但性能更好。我一般先用第一种方法跑通如果动态响应要求高再上第二种。6.5 PCB布局对电机控制的影响电机驱动板的PCB布局直接影响EMI和采样精度。几个关键原则功率地和信号地要分开最后单点连接。功率地上的开关电流很大如果和信号地混在一起信号地上会有很大噪声。采样电阻的走线要对称差分运放的输入走线要等长尽量靠近采样电阻。采样电阻的 Kelvin 连接很重要电压采样点要在电阻焊盘内侧不要从电流路径上取。MOS管的栅极驱动走线要短而粗减少驱动回路的电感。驱动回路的电感太大会导致栅极电压振铃严重时MOS管会误导通。去耦电容要靠近芯片的电源引脚尤其是MCU的电源引脚和ADC参考引脚。电机驱动板上开关噪声大去耦不好会导致MCU复位或者ADC采样异常。这些布局细节在原理图上看不出来但实际调试时问题往往就出在这里。我遇到过一块板子电流采样噪声大得没法用查了半天发现是采样电阻的接地走线太长改短之后噪声立刻降下来了。7. 写在最后一些零散但有用的经验调试电机控制这些年有几个体会比较深。一是不要迷信仿真仿真跑通了不代表实际能跑。电机的参数非线性、驱动电路的延迟、采样噪声这些在仿真里很难完全模拟。二是不要一次改多个参数每次只改一个观察效果否则出了问题不知道是哪个参数导致的。三是保留调试日志每次调试的参数、现象、结论都记下来下次遇到类似问题能快速定位。还有一点电机控制是个交叉学科电力电子、控制理论、嵌入式软件、PCB设计都得懂一点。不需要每个方向都精通但至少要知道每个环节的基本原理和常见问题这样出了问题才能判断是哪个环节的毛病。我见过不少做电机控制的人算法很熟但硬件不懂遇到采样噪声就束手无策也见过硬件很熟但控制理论不扎实的PI参数调来调去调不好。两边都懂一点调试效率会高很多。最后说一个具体的技巧如果FOC跑起来电流波形有周期性畸变先检查ADC采样时刻是否和PWM中心对齐。这个问题的表现是电流波形在每个PWM周期内有一个固定的偏差看起来像波形被“削”了一块。我遇到过好几次都是采样时刻偏了几个微秒导致的。把定时器的ADC触发比较值调一下波形立刻干净。这个坑不踩几次很难想到但一旦知道了排查起来就是几分钟的事。
返回列表