本文转载自微信公众号“小麦大叔”,可通过以下二维码关注。转载本文请联系小麦大叔公众号。SVPWMMSVPWM是空间矢量脉冲宽度调制(SpaceVectorPulseWidthModulation)的缩写。它通常由一个三相逆变器的六个功率开关管组成。经过特定的定时和换向,最终输出的脉宽调制波的波形可以非常接近理想的正弦波形。详情如下图所示;左边是复平面,即空间矢量,右边是时域的正弦波形;关于SVPWM原理的文章很多,这里我可以推荐一个很好的网上教程《SVPWM的原理及法则推导和控制算法详解第五修改版》,这篇文章将如何实现SVPWM做一个简单的介绍。IQMATHTI的片子很香。在控制方面,TI无疑是最好的解决方案之一。相对来说,资料也很齐全;此外,TI还推出了用于不带浮点运算符的定点DSP的IQMATH库。在使用Q格式进行数据分析处理的过程中,非常方便,代码也变得更加简洁。本文将使用TI提供的SVPWM算法实现基于STM32平台的SVPWM调制。测试平台参数:硬件:stm32f103软件:StandardPeripheralLibrary3.5IDE:MDK-ARMIQmathLib本文使用Cortex-M3版本的IQMathLib。这样,对于没有浮点处理器的定点MCU,Q格式的处理会变得更加方便和高效;首先解压IQmathlib得到如下文件,其中包含各平台下的静态库。本文使用STM32F1在keil环境下开发,需要rvmdk-cm3。打开一个keil工程,在菜单界面点击下图图标进入工程项;添加IQmath组,在rvmdk-cm3路径下添加静态库和头文件;点击下图图标,进入熟悉的项目设置;添加rvmdk-cm3静态库路径和头文件include路径,如下图;最后,只需构建整个项目。测试部分程序/**#include"stm32f10x.h"#include#include#include"serial_scope.h"#include"common.h"#include"IQmathLib.h"#include"usart_driver.h"#include"clarke.h"#include"park.h"#include"svpwm.h"/***@briefMainprogram.*@paramNone*@retvalNone*/sv_mod_tsvpwm=SVGEN_DEFAULTS;#defineCLARK0#definePARK1#defineSVPWM2#defineSVPWM_REG3intmain(void){intuser_data[4]={0};staticint16_ttime_cnt=0;Trig_Componentsa;Trig_Componentsb;_iqfinal_angle;usart_init();while(1){time_cnt-=32;clarke_parameter.As=_IQsinPU(timearke_cnt_parameter);.Bs=_IQsinPU(time_cnt-0x5555);if(clarke_parameter.As>32767){clarke_parameter.As=32767;}if(clarke_parameter.As<-32768){clarke_parameter.As=-32768;}if(clarke_parameter.As=-32768;}if(clarke_parameter.Bs>32767){clarke_parameter.Bs=32767;}if(clarke_parameter.Bs<-32768){clarke_parameter.Bs=-32768;}clarke_calc(&clarke_parameter);park_parameter.Alpha=clarke_parameter.Alpha;park_parameter.Beta=clarke_parameter.Beta;park_parameter.Sin=trig_functions(time_cnt).hsin;park_parameter.Cos=trig_functions(time_cnt).hcos;park_parameter.Angle=-time_cnt;park_calc(&park_parameter);svpwm.Ualpha=clarke_parameter.Alpha;svpwm.Ubeta=clarke_parameter.Beta;svpwm_calc(&svpwm);#defineFOC_DEBUGSVPWM_REG#if(FOC_DEBUG==CLEAK)user_data[0]=clarke_parameter.As;user_data[1]=clarke_parameter.Bs;user_data[2]=clarke_parameter.Alpha;user_data[3]=clarke_parameter.Beta;#elif(FOC_DEBUG==PARK)user_data[0]=clarke_parameter.As;user_data[1]=clarke_parameter.Bs;user_data[2]=park_parameter.Ds;user_data[3]=park_parameter.Qs;#elif(FOC_DEBUG==SVPWM)user_data[0]=(uint16_t)svpwm.Ta;user_data[1]=(uint16_t)svpwm.Tb;user_data[2]=(uint16_t)svpwm.Tc;user_data[3]=svpwm.VecSector*5000;#elif(FOC_DEBUG==SVPWM_REG)//转换计算的CCRx寄存器的值sv_regs_mod_tsv_regs=svpwm_get_regs_mod(7200,&svpwm);user_data[0]=sv_regs_data[1]user=sv_regs.ccr2;用户数据[2]=sv_regs.ccr3;user_data[3]=svpwm.VecSector*1000;#endifSDS_OutPut_Data_INT(user_data);}return0;}最后通过串口输出串口图形软件的Ta,Tb,Tc如下图;STM32的配置,需要配置三个互补的PWM波形输出;例如配置TIM1的CH1、CH2、CH3三个PWM输出,然后将Ta、Tb、Tc的值分别赋值给CCR1、CCR2、CCR3;具体如下图所示;左侧为复平面矢量合成动态图;右边是三个PWM输出通道的比较状态;开关状态附件