ARTICLE DETAIL

资讯详情

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

STM32G4硬件加速器CORDIC与FMAC在电机FOC中的实战应用

STM32G4硬件加速器CORDIC与FMAC在电机FOC中的实战应用 1. 为什么STM32G4在电机FOC里值得单独拿出来说如果你最近两年做过无刷电机或者永磁同步电机的FOC控制应该有一个很直观的感受传统的STM32F1、F4系列虽然也能跑FOC但一旦电流环频率往上提或者要叠加观测器、锁相环、前馈补偿CPU的算力就开始捉襟见肘。我最早用STM32F103RCT6搭无刷电机FOC驱动的时候电流环跑到10kHz就已经很吃力了主频72MHz单电阻采样的重构、Clarke/Park变换、两个PID、SVPWM七段式生成一套下来CPU占用率直接飙到70%以上稍微加点保护逻辑或者通信就顶不住了。STM32G4系列出来之后情况完全不一样。它本质上是ST把F3的混合信号能力和F4的浮点性能揉在一起再针对电机控制、数字电源这类场景做了定向加强。170MHz的Cortex-M4F带FPU和DSP指令这还只是基础真正让它在FOC里脱颖而出的是两个硬件加速器CORDIC和FMAC。这两个东西不是噱头是实打实能把CPU从三角函数和滤波运算里解放出来的硬件单元。这篇内容我打算把STM32G4的CORDIC和FMAC在电机FOC中的实际用法讲透包括它们各自解决什么问题、怎么配置、和传统软件实现比到底快多少、踩过哪些坑。适合已经做过FOC、想进一步优化性能的工程师也适合正在选型、纠结要不要从F1/F4迁移到G4的朋友。核心关键词就围绕STM32G4、CORDIC、FMAC、FOC、电机控制这几个点展开不跑题。先说结论CORDIC负责把Park变换、反Park变换、以及观测器里的三角函数运算硬件化FMAC负责把电流环里的滤波、滑模观测器的滤波环节硬件化。两者配合能把FOC电流环的CPU占用率压到原来的三分之一甚至更低同时把电流环频率轻松推到20kHz以上。下面我按设计思路、核心细节、实操过程、问题排查四个大块来讲。2. 整体设计思路为什么是CORDIC加FMAC这套组合2.1 传统FOC的算力瓶颈到底卡在哪要理解G4这两个加速器的价值得先搞清楚标准FOC里CPU时间都花在哪了。一个典型的电流环周期按顺序大概要做这些事相电流采样和ADC转换完成中断响应单电阻或三电阻的电流重构如果是单电阻还要做PWM移相Clarke变换三相到两相Park变换需要sin和cos两个电流PI调节器反Park变换又需要sin和cosSVPWM扇区判断和占空比计算如果有观测器还要做滑模或者龙伯格运算里面同样有三角函数和滤波你数一下一个电流环周期里sin/cos至少要用两次Park和反Park如果观测器里还有那就是四次以上。在F1/F4上这些sin/cos要么用查表加插值要么用CMSIS-DSP的arm_sin_f32/arm_cos_f32前者占Flash和RAM后者单次调用大概几十个周期。电流环20kHz意味着50微秒一个周期四次三角函数加上其他运算光三角函数就能吃掉好几微秒。滤波这块也一样。滑模观测器的输出需要低通滤波电流采样需要抗混叠滤波传统做法是用IIR或者FIRCMSIS-DSP的arm_biquad_cascade_df1_f32一次二阶节大概也要几十个周期。这些运算累加起来就是FOC跑不快的根本原因。2.2 CORDIC和FMAC各自的分工STM32G4的CORDIC是一个专门做坐标旋转数字计算的硬件单元它能在几个时钟周期内完成sin、cos、atan2、模长、相角这些运算。注意它是硬件流水线配置好之后写一个参数进去等几个周期读结果就行完全不占CPU的运算单元。在FOC里Park变换和反Park变换需要的sin/cos以及观测器里需要的atan2用来算转子角度都可以直接丢给CORDIC。FMAC是滤波数学加速器它本质上是一个带预加法的乘累加单元专门用来做FIR和IIR滤波。它有自己的本地内存256个16位字可以存系数和状态CPU只需要把输入样本写进去读输出就行。在FOC里电流环的滤波、滑模观测器的低通滤波、甚至速度环的滤波都可以交给FMAC。这两个加速器的分工很清晰CORDIC管三角函数和坐标变换FMAC管滤波和卷积。它们都是独立外设可以并行工作CPU在它们运算的时候可以去处理别的逻辑比如保护判断、通信、状态机。2.3 为什么这套组合特别适合FOCFOC的本质是把三相电流通过坐标变换解耦成励磁分量和转矩分量然后在旋转坐标系下分别控制。这个过程中坐标变换是核心而坐标变换的核心就是三角函数。CORDIC把三角函数硬件化等于把FOC最核心的运算从软件搬到了硬件。同时FOC对电流采样的质量很敏感噪声会直接影响转矩脉动。FMAC做滤波可以在不占CPU的情况下把采样噪声压下去提升电流环的信噪比。这两者结合正好覆盖了FOC里最耗算力和最影响性能的两个环节。还有一个很实际的原因G4的CORDIC和FMAC都是通过CubeMX可以直接配置的ST提供了HAL库和LL库的支持迁移成本不高。如果你原来用F4跑FOC把三角函数和滤波替换成硬件加速代码改动量其实不大但性能提升很明显。3. 核心细节解析CORDIC和FMAC在FOC里怎么用3.1 CORDIC的配置要点和精度取舍CORDIC在G4上有几个关键配置项直接决定它的精度和速度。第一个是精度模式G4的CORDIC支持不同的迭代次数迭代次数越多精度越高但延迟也越大。在FOC里Park变换对精度的要求其实没有想象中那么高因为电流环本身有反馈小的角度误差会被PI调节器修正。我一般用默认的精度配置实测角度误差在0.1度以内完全够用。第二个是函数模式CORDIC支持sine、cosine、phase、modulus、arctangent等模式。Park变换需要sin和cos可以分别调用sine和cosine模式也可以用sine模式配合相位偏移。反Park变换同理。观测器里算角度用phase模式算模长用modulus模式。第三个是数据格式CORDIC的输入输出都是Q格式定点数通常是Q1.31或者Q1.15。这里有个坑如果你用浮点做FOC需要把浮点转成Q格式再喂给CORDIC算完再转回浮点。这个转换本身有开销所以我的建议是如果决定用CORDIC电流环内部尽量用定点运算减少转换次数。或者用G4的CORDIC配合FPU只在CORDIC前后做转换中间保持浮点。配置CORDIC的代码大概长这样用LL库// 配置CORDIC为sine模式Q1.31格式 LL_CORDIC_Config(CORDIC, LL_CORDIC_FUNCTION_SINE, LL_CORDIC_PRECISION_6CYCLES, LL_CORDIC_SCALE_0, LL_CORDIC_NBWRITE_1, LL_CORDIC_NBREAD_1, LL_CORDIC_INSIZE_32BITS, LL_CORDIC_OUTSIZE_32BITS); // 写入角度读取sin值 LL_CORDIC_WriteData(CORDIC, angle_q31); sin_value LL_CORDIC_ReadData(CORDIC);注意CORDIC的读写是阻塞式的写完要等结果就绪。G4的CORDIC有状态寄存器可以查询也可以用中断或者DMA。在FOC电流环里我一般用轮询因为CORDIC延迟只有几个周期轮询的开销比中断响应还小。3.2 FMAC的滤波配置和系数设计FMAC的配置比CORDIC稍微复杂一点因为它涉及到滤波器的结构。FMAC支持FIR和IIR两种模式在FOC里我主要用IIR做低通滤波用FIR做电流采样的抗混叠。FMAC的本地内存分两部分系数区和状态区。系数区存滤波器的系数状态区存历史输入输出。配置的时候要把系数写进去然后设置输入输出的缓冲区地址。FMAC的工作方式是CPU把输入样本写到输入缓冲区FMAC自动运算结果放到输出缓冲区CPU读出来。一个二阶IIR低通滤波器的系数设计可以用MATLAB或者Python的scipy来算。假设采样率20kHz截止频率1kHz用巴特沃斯设计得到的系数大概是b00.0201, b10.0402, b20.0201, a1-1.5610, a20.6414。这些系数要转成Q格式写进FMAC。FMAC配置的代码示例// 配置FMAC为IIR模式输入输出都是16位 LL_FMAC_Config(FMAC, LL_FMAC_FUNC_IIR, LL_FMAC_COEFF_SIZE_16BITS, LL_FMAC_INPUT_SIZE_16BITS, LL_FMAC_OUTPUT_SIZE_16BITS, LL_FMAC_MULT_16BITS, LL_FMAC_ACC_32BITS); // 写入系数 LL_FMAC_WriteCoeff(FMAC, coeff, 5); // 启动FMAC LL_FMAC_Enable(FMAC);这里有个细节FMAC的IIR模式对系数的排列有要求a1和a2要取负号因为FMAC内部做的是减法。这个在ST的参考手册里有说明但很容易看漏我第一次配的时候就是因为符号搞反了滤波器直接发散。3.3 电流环里CORDIC和FMAC的协同在实际的电流环里CORDIC和FMAC是交替工作的。一个典型的20kHz电流环周期时间线大概是这样ADC中断触发读取相电流把相电流喂给FMAC做滤波如果开了滤波同时做Clarke变换从FMAC读滤波后的电流把电角度喂给CORDIC读sin/cos做Park变换电流PI调节把新的角度喂给CORDIC读sin/cos做反Park变换SVPWM生成CORDIC和FMAC的运算时间都是几个周期到十几个周期相比软件实现动辄几十上百周期节省非常明显。而且它们可以并行比如FMAC在滤波的时候CORDIC可以同时算sin/cosCPU在等结果的时候可以做Clarke变换或者PI调节的准备。这里的关键是流水线设计。不要让CPU傻等CORDIC或者FMAC的结果而是把依赖关系理清楚能并行的并行。比如Park变换需要sin/cos但Clarke变换不需要所以可以在CORDIC算sin/cos的同时做Clarke变换。4. 实操过程从CubeMX配置到代码落地4.1 CubeMX里的CORDIC和FMAC配置在CubeMX里配置G4的CORDIC和FMAC其实比想象中简单。打开CubeMX选好G4的型号在左侧外设列表里找到CORDIC和FMAC勾选启用。CORDIC的配置界面有几个下拉框Function选Sine或者PhasePrecision选迭代次数Data size选32位或者16位。我一般选32位精度和范围都更好。FMAC的配置界面要选FunctionFIR或IIR、Coeff size、Input size、Output size。这些和前面代码里的配置对应。CubeMX会自动生成初始化代码但要注意它生成的只是外设的基础配置滤波器的系数和CORDIC的具体调用还是要自己写。我建议在CubeMX里把CORDIC和FMAC的时钟打开G4的这两个外设挂在AHB上时钟频率和主频一致170MHz。还有一个容易忽略的点CORDIC和FMAC的中断优先级。如果你用中断方式要确保它们的优先级低于ADC电流采样中断否则会影响电流环的实时性。我一般用轮询省去中断配置的麻烦。4.2 电流环的定点化改造如果你原来用浮点跑FOC迁移到CORDIC和FMAC的时候最大的工作量是定点化。CORDIC和FMAC都是定点外设虽然G4的FPU很强但既然用了硬件加速就没必要在中间再转回浮点。定点化的关键是Q格式的选择。电流采样一般是12位ADC范围0到4095对应实际电流。我一般把电流转成Q1.15格式范围-1到1对应额定电流的倍数。电角度用Q1.31格式范围-1到1对应-π到π。sin/cos输出也是Q1.15。定点化的过程中要注意溢出和饱和。PI调节器的输出要做限幅Park变换的中间结果要检查范围。G4的CORDIC有饱和保护但FMAC没有所以FMAC的输入要自己保证不溢出。我实测下来定点化的FOC和浮点FOC在控制性能上几乎没有区别但定点化的代码在G4上跑20kHz电流环CPU占用率只有15%左右而浮点版本要40%以上。这个差距在需要叠加观测器和保护逻辑的时候非常关键。4.3 滑模观测器里的CORDIC和FMAC应用无感FOC里滑模观测器是常用的转子位置估计方法。传统的滑模观测器里反电动势的滤波和角度计算都是软件做的很耗算力。用G4的CORDIC和FMAC可以大幅优化。具体做法是滑模观测器的输出经过FMAC做低通滤波滤除高频抖振然后用CORDIC的atan2模式算转子角度。这样观测器的运算几乎不占CPU可以把它放在和电流环相同的频率下运行提升估计精度。这里有个经验滑模观测器的滤波截止频率要仔细调。截止频率太低角度估计滞后高速时误差大截止频率太高抖振滤不干净角度波动大。我一般从500Hz开始调根据电机的高速性能往上加。用FMAC的好处是改截止频率只需要重新算系数写进去不用改代码结构。4.4 实测性能对比我在一块G431的板子上做过对比测试电机是一个24V、额定转速3000rpm的PMSM电流环20kHz速度环1kHz无感FOC用滑模观测器。方案电流环CPU占用观测器CPU占用总占用电流环频率上限F4浮点软件实现38%22%60%约15kHzG4浮点软件实现25%15%40%约20kHzG4 CORDICFMAC12%5%17%30kHz以上这个数据是实测的不是理论值。可以看到G4本身比F4快但真正拉开差距的是CORDIC和FMAC。用了硬件加速之后CPU占用从40%降到17%意味着你可以把电流环频率翻倍或者在同一频率下加入更多功能比如参数辨识、故障诊断、更复杂的观测器。5. 常见问题与排查技巧实录5.1 CORDIC结果不对的几种典型情况CORDIC用起来简单但结果不对的时候排查起来有点烦。我遇到过几种情况第一种是角度范围搞错。CORDIC的sine模式输入是Q1.31对应-1到1也就是-π到π。如果你传进去的是0到2π对应的Q格式结果就会错。解决办法是在传之前把角度归一化到-π到π。第二种是精度模式选太低。G4的CORDIC有6周期、12周期、18周期等精度选项6周期最快但精度最低。在FOC里如果电流环频率很高6周期够用但如果做观测器的atan2建议用12周期以上否则角度误差会影响估计精度。第三种是读写顺序错。CORDIC是流水线写完数据要等几个周期才能读。如果你写完立刻读读到的可能是上一次的结果。G4的CORDIC有状态位可以查或者用固定的延时。我一般用LL_CORDIC_IsReady()轮询。5.2 FMAC滤波器发散的排查FMAC的IIR滤波器发散基本上都是系数问题。最常见的是符号搞反。前面说过FMAC的IIR模式内部做的是减法所以a1和a2要取负号。如果你直接把MATLAB算出来的系数写进去滤波器就会发散。第二个是Q格式不匹配。FMAC的系数和输入都是定点如果系数的Q格式和输入的Q格式不一致结果会错。我一般把系数和输入都统一成Q1.15输出用Q1.15中间累加用32位。第三个是状态区没清零。FMAC的状态区存的是历史输入输出如果初始化的时候没清零第一次滤波的结果会受随机值影响。解决办法是在启动FMAC之前把状态区全部写0。5.3 电流环时序冲突的处理用了CORDIC和FMAC之后电流环的时序变得更复杂因为多了两个外设的读写。如果时序没安排好会出现CORDIC还没算完就去读、FMAC还在滤波就去取结果的情况。我的做法是画一个时序图把每个步骤的依赖关系标清楚。ADC中断触发后先启动FMAC滤波同时做Clarke变换Clarke做完FMAC的结果也应该好了读出来做Park变换Park变换需要sin/cos所以在启动FMAC的同时也启动CORDIC算sin/cosPark做完PI调节然后启动CORDIC算反Park的sin/cos反Park做完SVPWM。这个流水线设计的关键是提前启动。不要等到需要结果了才去启动外设而是在依赖它的步骤之前就启动让外设和CPU并行工作。5.4 常见问题速查表问题现象可能原因排查方法解决办法CORDIC输出恒定或为0外设时钟未使能查RCC寄存器使能CORDIC时钟CORDIC角度误差大精度模式太低换12周期模式测试提高迭代次数FMAC输出发散系数符号错误检查a1/a2符号取负号FMAC输出为0状态区未初始化读状态区内容启动前清零电流环抖动滤波截止频率太低提高截止频率重算系数CPU占用反而升高定点浮点转换太多统计转换次数统一用定点5.5 几个我踩过的坑第一个坑是CORDIC的sin和cos要分别调用。G4的CORDIC一次只能算一个函数算sin和cos要调用两次或者用sine模式配合相位偏移π/2。我一开始以为可以一次算两个结果发现不行后来改成两次调用反正CORDIC快多一次调用也就多几个周期。第二个坑是FMAC的系数数量。FMAC的IIR模式二阶节需要5个系数b0, b1, b2, a1, a2但FMAC的系数区是按16位字存的如果系数是32位要占两个位置。我一开始没注意系数写进去错位了滤波器完全不对。第三个坑是CubeMX生成的代码和外设配置不一致。CubeMX生成的CORDIC配置有时候和实际需求不符比如精度模式默认是6周期但你需要12周期。解决办法是生成代码后手动改初始化部分或者在CubeMX里仔细核对每个选项。6. 从F1/F4迁移到G4的实际建议如果你现在用的是STM32F103RCT6或者F4系列跑FOC想迁移到G4用CORDIC和FMAC我的建议是分步走。第一步先把代码从F1/F4移植到G4保持软件实现不变只利用G4的主频优势。这一步主要是改时钟配置、外设初始化、中断向量表。G4的HAL库和F4的很像移植工作量不大。第二步把Park变换和反Park变换的sin/cos替换成CORDIC。这一步改动集中在坐标变换函数里把arm_sin_f32/arm_cos_f32换成CORDIC的读写。注意定点化转换。第三步把电流采样滤波和观测器滤波替换成FMAC。这一步要设计滤波器系数配置FMAC替换原来的滤波函数。第四步优化时序把CORDIC和FMAC的启动提前做流水线设计。这一步需要仔细分析电流环的每个步骤找出可以并行的部分。整个迁移过程如果顺利的话一周左右可以完成。性能提升是立竿见影的尤其是电流环频率和CPU占用率。最后分享一个小技巧G4的CORDIC和FMAC在低功耗模式下也可以工作如果你做电池供电的电机驱动可以在电机低速时降低CPU频率让CORDIC和FMAC承担更多运算进一步省电。这个我在一个手持设备项目里试过效果不错。
返回列表