首页 / 资讯中心 / 文章详情

电机控制入门到精通:PWM、FOC与RTOS实战指南

电机控制入门到精通:PWM、FOC与RTOS实战指南 ★ FEATURED ARTICLE
1. 电机控制到底在控什么从标题拆解核心脉络“电机控制一文看懂”这个标题看着简单实际上背后藏着一整条从硬件到算法、从裸机到实时操作系统的技术链路。我做了十多年嵌入式开发接触过从几块钱的有刷直流电机驱动到工业级永磁同步电机伺服控制的各种项目每次有人问我“电机控制该怎么入门”我都会先反问一句你要控的是什么电机用什么平台做到什么精度这三个问题不搞清楚后面全是白费功夫。电机控制的核心目标就一个让电机按照我们期望的转速、转矩或位置去运转。听起来像废话但拆开来看转速控制需要反馈、转矩控制需要电流环、位置控制需要编码器或者无感估算每一条路都对应着不同的硬件配置和算法复杂度。而贯穿所有这些的底层技术其实就是几个关键词PWM、ADC、定时器、中断以及在此之上的控制算法和实时调度。这篇文章我打算按实际项目的推进顺序来写从最基础的有刷电机PWM调速讲起逐步过渡到BLDC和PMSM的FOC控制中间把ADC采样、RTOS任务调度、故障保护这些环节都串起来。不管你是刚拿到一块STM32开发板的新手还是已经在做无感FOC但卡在某个环节的老手应该都能从中找到对自己有用的东西。提示本文涉及的平台以STM32系列为主但原理和方法适用于大多数MCU包括国产的峰岹、芯圣等方案。2. 从有刷到无感FOC电机控制方案怎么选2.1 直流有刷电机最朴素的PWM调速有刷直流电机的控制逻辑极其简单给电就转电压越高转得越快。所以调速的本质就是调电压而调电压最高效的方式就是PWM。PWM的全称是脉冲宽度调制说白了就是通过快速开关MOS管控制在一个周期内导通时间的占比从而改变等效输出电压。举个例子供电12VPWM占空比50%等效电压就是6V。电机绕组本身有电感电流不会突变所以只要PWM频率足够高一般选10kHz到20kHz电机看到的就是一个平滑的等效电压。频率选低了电机会听到啸叫选高了MOS管开关损耗会增大10kHz到20kHz这个区间是人耳听觉范围的上限附近既能避开噪音又不会让开关损耗太离谱。在STM32上配置PWM通常用通用定时器或高级定时器。以TIM1为例配置成PWM模式1设置预分频器和自动重装载值来决定频率然后写比较寄存器来调占空比。这里有个细节PWM模式1和模式2的区别在于有效电平的极性。模式1是计数器小于比较值时输出有效电平模式2反过来。选哪个取决于你的驱动电路是高边驱动还是低边驱动搞反了会出现上电就满速或者完全不转的情况。有刷电机控制虽然简单但它是理解PWM、死区、驱动电路这些基础概念的最佳入口。我建议每个刚接触电机控制的人都先拿有刷电机练手把PWM波形用示波器看明白再去碰更复杂的方案。2.2 BLDC与PMSM为什么最终都走向FOC无刷直流电机BLDC和永磁同步电机PMSM在结构上很相似定子绕组、转子永磁体区别主要在于反电动势波形和驱动方式。BLDC的反电动势接近梯形波通常用六步换相法驱动PMSM的反电动势接近正弦波更适合用FOC磁场定向控制来驱动。六步换相的逻辑是根据转子位置依次给两相通电、第三相悬空每60度电角度换一次相。这种方法实现简单但转矩脉动大低速时尤其明显。FOC的思路则完全不同它把三相电流通过Clarke变换和Park变换从静止坐标系转到旋转坐标系把交流量变成直流量然后用PID控制器分别控制d轴和q轴电流。d轴电流控制磁场q轴电流控制转矩这样就能像控制有刷电机一样去控制无刷电机转矩脉动小、效率高、低速性能好。FOC的运算量比六步换相大得多一次完整的FOC循环包括ADC采样三相电流、Clarke变换、Park变换、两个PID运算、反Park变换、SVPWM生成。这一套下来在STM32F4上大概需要几微秒到十几微秒所以PWM频率一般设在10kHz到20kHz对应中断周期50到100微秒留给FOC计算的时间是够的。2.3 有感和无感转子位置从哪来FOC控制的前提是知道转子位置。有感方案用霍尔传感器或编码器直接测量简单可靠但增加了硬件成本和接线复杂度。无感方案则通过检测反电动势或高频注入来估算转子位置省掉了传感器但在低速和零速时估算困难启动阶段需要特殊处理。无感FOC的启动通常分三段预定位、开环加速、闭环切换。预定位是给一个固定的电流矢量把转子强行拉到已知位置开环加速是按预设的加速度逐步提高频率让电机转起来当转速足够高、反电动势足够大时再切换到闭环估算。这个切换点选不好电机会失步或者抖动我一般会在反电动势达到母线电压的10%到15%左右时尝试切换具体值要根据电机参数和负载特性来调。注意无感FOC的启动参数是调试中最耗时的部分。不同电机的绕组电阻、电感、反电动势常数都不一样同一套参数换一个电机可能就完全跑不起来。3. 硬件层的关键细节PWM、ADC与定时器3.1 PWM配置频率、死区与互补输出在电机控制中PWM不只是调速工具它还决定了整个控制系统的时序基准。FOC的电流采样通常在PWM周期的特定时刻触发一般是计数器下溢或者上溢的时刻因为这时候开关管状态稳定电流纹波最小。STM32的高级定时器TIM1、TIM8支持互补输出和死区插入这是驱动三相全桥的必备功能。互补输出意味着每个通道有两个输出引脚一个高边一个低边两者不能同时导通否则会炸管。死区时间就是在这两者之间插入的一段全关断时间防止因开关延迟导致直通。死区时间一般设几百纳秒到一微秒具体值取决于MOS管和驱动芯片的开关速度。以STM32CubeMX配置为例TIM1的通道1、2、3配置为PWM Generation CH1/CH2/CH3通道1N、2N、3N配置为互补输出死区时间在Break and Dead-Time寄存器里设置。时钟源选内部时钟预分频器设为0自动重装载值根据目标频率计算。比如系统时钟168MHz目标PWM频率20kHz自动重装载值就是168000000/200008400实际写8399因为从0开始计数。中心对齐模式在电机控制中比边沿对齐模式更常用因为中心对齐产生的PWM波形对称谐波含量低而且ADC采样可以在计数器上溢或下溢时触发采样时刻更精准。3.2 ADC采样电流检测的时机与滤波FOC需要实时获取三相电流通常用采样电阻或霍尔电流传感器。采样电阻方案成本低但需要运放放大信号而且采样时机很关键。在PWM周期中只有特定时刻的电流才反映真实的相电流一般是下桥臂导通的时候。STM32的ADC支持注入通道和规则通道注入通道可以打断规则通道的转换适合用于电机电流采样这种需要精确时序的场景。配置时把ADC的触发源设为定时器的特定事件比如TIM1的TRGO或CC4事件这样每次PWM周期到特定时刻就自动触发ADC采样不需要CPU干预。ADC采样值难免有噪声软件滤波是必须的。最简单的是一阶低通滤波公式是滤波值 系数 × 本次采样值 (1 - 系数) × 上次滤波值。系数越小滤波效果越强但延迟越大一般取0.1到0.3之间。如果噪声特别大可以用中值滤波加低通滤波的组合先用中值滤波去掉脉冲干扰再用低通滤波平滑。// 一阶低通滤波示例 #define ALPHA 0.2f float adc_filtered 0.0f; float low_pass_filter(float new_sample) { adc_filtered ALPHA * new_sample (1.0f - ALPHA) * adc_filtered; return adc_filtered; }提示ADC采样时刻如果和PWM开关时刻重合会采到开关噪声。一般把采样点设在PWM周期中间远离开关沿。3.3 定时器中断与FOC循环时序整个FOC控制循环跑在定时器中断里中断频率就是PWM频率。以20kHz为例每50微秒进一次中断在这50微秒内要完成电流采样、坐标变换、PID计算、SVPWM输出。时间很紧所以代码效率很重要。我一般的做法是把FOC循环分成两部分ADC注入通道转换完成中断里做电流采样和Clarke/Park变换然后在一个更低优先级的中断或者主循环里做PID和SVPWM。但这样会引入延迟对高速电机不利。更好的方案是全部放在PWM周期中断里用DMA搬运ADC数据减少CPU开销。STM32F4系列有FPU和DSP指令做浮点运算很快一次FOC循环大概5到10微秒。如果用的是没有FPU的MCU比如STM32F1就得用定点数运算Q格式是常用的方法。Q15格式把-1到1的浮点数映射到-32768到32767的整数运算时注意溢出和精度损失。4. FOC算法实现从Clarke到SVPWM4.1 坐标变换把交流量变成直流量Clarke变换是把三相电流ia、ib、ic从三相静止坐标系转到两相静止坐标系α-β。因为三相电流之和为零所以实际上只需要采样两相电流第三相可以通过计算得出。Clarke变换的公式是iα ia iβ (ia 2ib) / √3Park变换是把α-β坐标系转到随转子旋转的d-q坐标系需要知道转子角度θid iα × cosθ iβ × sinθ iq -iα × sinθ iβ × cosθ变换之后id和iq都是直流量id控制磁场iq控制转矩。对于表贴式永磁电机id的参考值通常设为0因为永磁体已经提供了磁场不需要额外的d轴电流。对于内置式永磁电机可以利用磁阻转矩给一个负的id参考值来提高效率。反Park变换和反Clarke变换则是把PID输出的vd、vq转回α-β再转成三相电压最后通过SVPWM输出。4.2 电流环PID参数怎么调电流环是FOC的内环响应速度要求最快。PID参数整定的目标是让电流在最短时间内跟踪参考值同时不产生振荡。我一般先用理论计算得到大致参数再在实际系统中微调。理论计算的方法是这样的电流环的被控对象是电机绕组传递函数近似为1/(LsR)L是相电感R是相电阻。PI控制器的零点用来抵消被控对象的极点所以积分时间常数设为L/R。比例增益则根据期望的带宽来定带宽一般设为PWM频率的1/10到1/5。比如PWM频率20kHz带宽设2kHz比例增益大约等于带宽乘以电感。实际调试时先把积分增益设为0逐渐增大比例增益直到电流出现轻微振荡然后回调到振荡消失。再加入积分增益从小到大调直到稳态误差消除但超调不过大。这个过程需要配合示波器观察电流波形或者用MCU的DAC输出实时观察。注意电流环的采样和PWM输出之间有延迟这个延迟会降低相位裕度。如果发现电流环怎么调都不稳定检查一下ADC采样时刻和PWM更新时刻是否对齐。4.3 SVPWM比正弦PWM更高效SVPWM全称是空间矢量脉宽调制它把三相逆变器的八个开关状态映射到六个扇区通过相邻两个矢量和零矢量的组合来合成目标电压矢量。相比正弦PWMSVPWM的直流电压利用率高15%左右而且谐波含量更低。SVPWM的实现步骤是先判断目标电压矢量在哪个扇区然后计算相邻两个矢量的作用时间最后分配给三个通道的比较寄存器。扇区判断可以用Clarke变换后的vα和vβ来计算作用时间涉及√3和除法运算在MCU上可以用查表或者定点数来加速。在STM32上SVPWM的输出直接写到TIM1的CCR1、CCR2、CCR3寄存器配合互补输出和死区插入就能驱动三相全桥。中心对齐模式下比较值在计数器上溢和下溢时都会匹配所以实际输出的PWM波形是对称的。5. RTOS在电机控制中的角色必要还是累赘5.1 裸机 vs RTOS什么时候需要上系统很多初学者会问电机控制需要跑RTOS吗我的回答是看情况。如果只是单一电机控制FOC循环跑在定时器中断里主循环处理一些简单的通信和状态机裸机完全够用而且更简单、更可控。但如果系统里有多个任务需要协调比如电机控制、CAN通信、上位机协议解析、故障记录、参数存储这时候RTOS的价值就体现出来了。RTOS的核心作用是任务调度和资源管理。在电机控制中FOC中断的优先级最高必须保证按时执行不能被其他任务打断。RTOS的任务优先级机制可以确保这一点同时把低优先级的通信、显示、存储任务安排在空闲时间执行。我做过一个项目系统里有三个电机需要协调控制还要通过CAN总线和上位机通信同时记录运行数据到SD卡。裸机方案下主循环里要处理的事情太多稍微一个函数阻塞就会影响电机响应。换成RTOS之后每个电机一个任务通信一个任务存储一个任务优先级从高到低排列系统稳定性明显提升。5.2 中断优先级与任务优先级的配合在RTOS环境下中断优先级和任务优先级是两套独立的机制但需要配合好。FOC中断的硬件优先级必须是最高的确保任何时候都能抢占。RTOS的任务优先级则决定哪个任务先运行电机控制任务应该比通信和显示任务优先级高。有一个坑我踩过RTOS的临界区会关闭中断如果临界区太长FOC中断会被延迟导致电流环失控。所以电机控制项目中RTOS的临界区要尽可能短或者用调度器锁代替中断锁。提示FreeRTOS中configMAX_SYSCALL_INTERRUPT_PRIORITY决定了哪些中断可以调用RTOS的API。FOC中断如果优先级高于这个值就不能调用任何RTOS函数只能做纯计算。5.3 任务划分与栈大小估算电机控制项目的RTOS任务划分一般是这样一个高优先级任务处理FOC中断或者直接在中断里做一个中优先级任务处理状态机和故障保护一个低优先级任务处理通信和参数存储。栈大小的估算是个经验活。FOC任务如果涉及浮点运算和三角函数栈需求比较大我一般给512字到1KB。通信任务看协议复杂度CAN通信一般256字够用TCP/IP协议栈就需要几KB。栈溢出是RTOS项目最常见的死机原因建议在调试阶段开启栈检测功能或者给每个任务的栈填充特定模式运行一段时间后检查高水位线。6. 故障保护与调试实战那些文档里不会写的事6.1 PWM故障保护硬件刹车与软件保护电机控制中最怕的就是过流和过压轻则烧MOS管重则炸母线电容。STM32的高级定时器有刹车输入功能检测到故障信号后硬件自动关闭PWM输出响应时间只有几十纳秒比软件保护快得多。刹车输入可以接到过流比较器的输出一旦电流超过阈值比较器翻转刹车触发PWM立即关断。软件保护作为第二道防线在ADC采样后判断电流是否超限超限则逐步降低占空比或者直接关断。软件保护的响应时间在微秒级虽然比硬件慢但可以实现更复杂的保护策略比如限流运行而不是直接停机。调试时我习惯先调好硬件保护确保任何情况下都不会炸管然后再调软件保护。硬件保护的阈值一般设为电机额定电流的2到3倍软件保护设为1.5倍。6.2 ADC噪声与PWM干扰的排查ADC采样值跳动大是电机控制调试中的常见问题。原因通常有三个一是采样时刻不对采到了开关噪声二是地线布局不好功率地和信号地混在一起三是PWM频率和ADC采样频率产生了拍频。排查方法先用示波器看ADC输入引脚的波形如果看到尖峰说明是开关噪声耦合。解决办法是调整采样时刻把ADC触发点设在PWM周期中间远离开关沿。如果是地线问题检查PCB布局功率地和信号地单点连接采样电阻的接地端要靠近ADC的模拟地。还有一种情况是PWM背光干扰显示这通常发生在电机控制和显示屏共用一个电源的项目中。PWM调光信号通过电源线耦合到显示屏导致闪烁。解决办法是给显示屏单独加LC滤波或者把PWM调光频率提高到人眼不可见的范围。6.3 无感FOC启动失败的常见原因无感FOC启动失败的表现通常是电机抖动但不转或者转一下就停。原因可能有这几个预定位时间太短转子还没稳定就进入开环加速开环加速的斜率太陡电机跟不上切换点太早反电动势还太小估算不准切换点太晚开环运行时间太长效率低。我的经验是预定位时间给到500毫秒到1秒确保转子完全稳定。开环加速的斜率根据负载惯量来定轻载可以快一点重载要慢。切换点通过实验确定从低到高逐步提高切换转速观察切换时的电流波形选择电流最平稳的那个点。还有一个容易忽略的点是电机参数识别。无感FOC的估算器需要知道电机的相电阻和相电感如果参数不准估算角度会有偏差。我一般会在启动前做一次参数识别给电机注入一个小电流测量电压和电流的相位差计算出电阻和电感。6.4 常见问题速查表现象可能原因排查方向电机不转电流很大相序接错、死区不够、MOS管直通检查接线、示波器看PWM波形电机抖动不转无感启动参数不对、转子位置估算错误调整预定位和开环加速参数电流采样跳动大采样时刻不对、地线干扰调整ADC触发时刻、检查PCB布局高速时失步电流环带宽不够、母线电压不足提高电流环增益、检查母线电压低速时转矩脉动大死区补偿不够、电流环响应慢加入死区补偿、优化PID参数RTOS任务卡死栈溢出、优先级反转检查栈使用、使用互斥量7. 开源固件与进阶方向站在别人的肩膀上7.1 VESC与Moteus值得研究的开源方案VESC是一个开源的电调固件最初用于电动滑板后来扩展到各种电机控制场景。它的代码结构清晰FOC实现完整支持有感和无感模式还有丰富的配置参数。我建议想深入FOC的人把VESC的代码读一遍特别是它的观测器实现和故障保护逻辑很多细节在教科书里是找不到的。Moteus是另一个开源方案专注于高精度力矩控制用了更先进的观测器和控制算法。它的代码更现代用了C和Python适合有一定基础之后进阶研究。读开源代码的时候不要一上来就啃全部先跑起来用示波器看波形然后带着问题去读对应的代码段。比如电流采样不准就去看ADC配置和采样时刻的计算启动失败就去看启动状态机的实现。7.2 从有感到无感观测器设计的入门思路无感FOC的核心是观测器它的作用是从可测量的电压和电流中估算出转子位置和转速。最常用的观测器是滑模观测器和龙伯格观测器。滑模观测器实现简单鲁棒性强但抖振大龙伯格观测器基于电机模型精度高但对参数敏感。入门的话我建议先从滑模观测器入手因为它的数学推导相对简单代码实现也直观。基本思路是根据电机模型计算电流的估计值和实际电流比较误差经过符号函数和低通滤波后得到反电动势的估计值再从反电动势中提取转子角度。观测器的调试关键是滤波器的截止频率。截止频率太低角度估算滞后太高噪声抑制不够。一般设为电机运行频率的2到5倍具体值通过实验确定。7.3 带宽FOC控制中容易被忽略的概念FOC控制中经常提到带宽但很多人说不清楚它到底是什么。简单来说带宽就是控制系统能够有效响应的频率范围。电流环带宽决定了电流跟踪指令的速度速度环带宽决定了转速跟踪指令的速度。带宽和响应时间的关系是带宽越高响应越快但对噪声越敏感稳定性越差。电流环带宽一般设为PWM频率的1/10到1/5速度环带宽设为电流环的1/5到1/10。这样设计是为了保证内环比外环快避免外环干扰内环的稳定性。实际调试时带宽不是越高越好。我见过有人把电流环带宽设到PWM频率的1/2结果电流振荡得厉害电机根本没法正常运行。合适的带宽是在响应速度和稳定性之间找平衡这个平衡点需要通过实验来确定。8. 写在最后一些零散但有用的经验电机控制这个领域理论很重要但动手更重要。我见过太多人把FOC的公式推导得滚瓜烂熟一上电就抓瞎。原因很简单实际系统里有太多理想模型里没有的东西比如死区效应、开关延迟、参数漂移、电磁干扰。我的建议是先让电机转起来哪怕是用最简单的六步换相先建立信心。然后逐步加入电流环、速度环、位置环每加一个环节就观察波形理解它的作用。遇到问题不要急着改代码先用示波器看波形用万用表量电压把现象搞清楚再动手。还有一点电机控制没有一套参数走天下的说法。同一个电机不同的负载、不同的母线电压、不同的温度最优参数都不一样。所以自适应控制和参数辨识是进阶的必修课但那是后面的事了先把基础打牢。最后分享一个小技巧调试FOC的时候把关键变量通过DAC输出到示波器上观察比用printf打印快得多也不会干扰中断时序。STM32的DAC可以配置成定时器触发每个PWM周期更新一次这样就能实时看到电流、角度、转速的波形调试效率翻倍。
阅读完成 · 觉得有帮助?
咨询建站