【FOC控制】英飞凌TC264无刷驱动方案simplefoc移植(2)-SVPWM波实现

SVPWM波实现就是无数电机foc控制的核心,所以这一节就如何在英飞凌无刷驱动上时间互补pwm波形做讲解

  • 【FOC控制】英飞凌TC264无刷驱动方案simplefoc移植(2)-SVPWM波实现
    • 一、 无刷驱动svpwm控制的由来
    • 二、驱动电路的实现
    • 三、旋转的三相电机波形
    • 四、英飞凌互补pwm配置
    • 五、Simplefoc正弦svpwm输出
    • 六、总结

一、 无刷驱动svpwm控制的由来

在这部分可以参考其他文章
【自制FOC驱动器】深入浅出讲解FOC算法与SVPWM技术
逐飞基于英飞凌AURIX的平衡单车组BLDC项目开源
无刷电机模型其实可以看到,由于转子在磁场中只有6个稳定的状态,因此旋转过程其实是不平滑的,存在扭矩的抖动(没有通电的时候可以用手转一下无刷电机,会感受到这种“颗粒感”)。因此为了解决这个问题,从“硬件”和从“软件”出发有两个解决方。

BLDC由于反电动势接近梯形波,所以肯定是会有上面说的抖动问题的,但是转一圈抖6下太明显了,如果我增加电机槽、极对数(也就是磁铁对数),那以前是360度里面抖6下,现在变成120度里面抖6下,甚至更小,这样“颗粒感”不就变得更小了嘛?实际中买到的BLDC电机基本都是多极对的(比如下图),原理跟之前的分析是一样的,出来的都是三相信号(图中的三根线),可以自己进行类推


而另一方面 将bldc的反电动势设计为正弦波的形状,我们用软件和算法结合PWM技术将方波转变成等效的SPWM正弦波或者SVPWM马鞍波,再来驱动电机,结果美滋滋,控制效果很理想。当然为了产生更好的波形、更好的旋转磁场,驱动器、控制算法就变得非常复杂,这也是FOC的实现原理,后面会进行详细介绍。

二、驱动电路的实现

无刷电机的驱动电路主要使用三相逆变电路来实现,如下图:

所谓逆变电路,即把直流电变换为交流电,或者简单点说就是一个可以产生不同电流流向的电路,通过前面的电机模型分析我们也可以看出,对于无刷电机的驱动是需要在不同时刻施加不同方向的电压(电流)的,因此需要逆变电路。

而逆变电路具体的实现则一般是采用半桥MOS电路来制作的。半桥电路的原型如下,其实很简单,就是两个MOS管组成的上桥臂和下桥臂,中间引出一条输出线:

用3个半桥电路就可以组合成三相逆变电路,每个半桥引出的一根输出线跟无刷电机的一根相线相连,就完成了最基本的无刷驱动电路。

原理方面,MOS管可以看作电压控制的高速电子开关,在MOS管的栅极(上图中的High Drive和Low Drive)施加高电平或者低电平,就可以控制MOS源极和漏极的导通或者关闭。比如在下图中,我们打开第一组半桥的上桥臂、第二组和第三组半桥的下桥臂(其余的关闭),那么就可以让电流从电源正极流过电机的a相,流经b、c相,然后回到电源负极:

于是通过控制三个半桥的不同开关状态,我们可以控制电流在电机中的不同流向了。

这样,三组半桥就一共有8种组合方式,编码分别为:000、001、010、011、100、101、110、111

三、旋转的三相电机波形

按照前面的无刷电机基本模型,假设我们拿到这样一个电机,手动匀速转动它的转子,然后用示波器观察它的三相输出电压(也就是反电动势产生的电压),会看到什么波形呢?

其实很自然可以想到,我们会得到3根正弦曲线,而且三根曲线两两相位差为120°:

实际上三相发电机的发电原理就是这样的,输出的就是三相幅值为220V的交流电(线电压为380V,即 3∗220 ​V)。

发电机反过来就是电动机啦,所以假如反过来我们在三相无刷电机的三相线圈上输入上述三相正弦电压,那么就可以驱动无刷电机平稳高效地旋转了。

而这也是FOC驱动无刷电机的基本手段,即通过计算所需电压矢量,使用 SVPWM 技术产生调试信号,驱动三相逆变电路,合成出等效的三相正弦电压驱动电机。

四、英飞凌互补pwm配置

GTM模块简述

GTM(Generic Timer Module),直译出来就是通用定时器模块的意思,但是它又与我们平时理解的通用定时器有点不同,我们平时用定时器无非就是用来输出PWM信号或者用于周期中断等等,这些功能GTM模块都支持,而且还有一些我们没了解过的功能,大家看下图:

这个就是GTM模块的总体框图啦,我们第一眼肯定看到的就是里面最大的模块-ARU模块,它是用来处理数据流的,并且可以控制整个GTM模块的输出,但是它不是我们今天的主角,我们的主角在ARU模块的左侧和左下部分,分别是TIM模块、SPE模块、TOM模块。

所以互补pwm输出也正是使用的gtm模块的输,具体的配置如下

头文件声明:

#define FCY             ((uint32)100000000)     //系统时钟
#define FPWM            ((uint16)20000)         //PWM频率
#define PWM_PRIOD_LOAD  (uint16)(5000)          //PWM周期装载值#define PWM_PRODUCE_PIN IfxGtm_TOM0_0_TOUT26_P33_4_OUT  //PWM生成引脚
#define A_PHASE_PIN_H   IfxGtm_TOM0_2_TOUT28_P33_6_OUT  //电机A相上桥控制引脚
#define A_PHASE_PIN_L   IfxGtm_TOM0_3_TOUT29_P33_7_OUT  //电机A相下桥控制引脚
#define B_PHASE_PIN_H   IfxGtm_TOM0_4_TOUT30_P33_8_OUT  //电机B相上桥控制引脚
#define B_PHASE_PIN_L   IfxGtm_TOM0_5_TOUT40_P32_4_OUT  //电机B相下桥控制引脚
#define C_PHASE_PIN_H   IfxGtm_TOM0_6_TOUT42_P23_1_OUT  //电机B相上桥控制引脚
#define C_PHASE_PIN_L   IfxGtm_TOM0_7_TOUT64_P20_8_OUT  //电机B相下桥控制引脚

初始化函数:

Ifx_CCU6 *ccu6SFR = &MODULE_CCU61;
void ccu6_pwm_init(void)
{IfxCcu6_enableModule(ccu6SFR);if (IfxCcu6_getTimerAvailabilityStatus(ccu6SFR, IfxCcu6_TimerId_t12) == FALSE){IfxCcu6_enableTimer(ccu6SFR, IfxCcu6_TimerId_t12);}IfxCcu6_setT12Frequency(ccu6SFR, (float32)FCY, FCY/FPWM, IfxCcu6_T12CountMode_centerAligned);IfxCcu6_setT12CounterValue(ccu6SFR, 0);IfxCcu6_setDeadTimeValue(ccu6SFR, 50);IfxCcu6_enableDeadTime(ccu6SFR, IfxCcu6_T12Channel_0);IfxCcu6_enableDeadTime(ccu6SFR, IfxCcu6_T12Channel_1);IfxCcu6_enableDeadTime(ccu6SFR, IfxCcu6_T12Channel_2);IfxCcu6_setT12ChannelMode(ccu6SFR, IfxCcu6_T12Channel_0, IfxCcu6_T12ChannelMode_compareMode);IfxCcu6_setT12ChannelMode(ccu6SFR, IfxCcu6_T12Channel_1, IfxCcu6_T12ChannelMode_compareMode);IfxCcu6_setT12ChannelMode(ccu6SFR, IfxCcu6_T12Channel_2, IfxCcu6_T12ChannelMode_compareMode);IfxCcu6_setT12CompareValue(ccu6SFR, IfxCcu6_T12Channel_0, 0);IfxCcu6_setT12CompareValue(ccu6SFR, IfxCcu6_T12Channel_1, 0);IfxCcu6_setT12CompareValue(ccu6SFR, IfxCcu6_T12Channel_2, 0);IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t12, IfxCcu6_ChannelOut_cc0);IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t12, IfxCcu6_ChannelOut_cc1);IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t12, IfxCcu6_ChannelOut_cc2);IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t12, IfxCcu6_ChannelOut_cout0);IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t12, IfxCcu6_ChannelOut_cout1);IfxCcu6_enableModulationOutput(ccu6SFR, IfxCcu6_TimerId_t12, IfxCcu6_ChannelOut_cout2);ccu6SFR->CMPSTAT.U = (ccu6SFR->CMPSTAT.U & (~((uint16)0x3f<<8))) | (0x15<<8);const IfxCcu6_Cc60_Out *cc60Out = &IfxCcu61_CC60_P20_8_OUT;const IfxCcu6_Cc61_Out *cc61Out = &IfxCcu61_CC61_P20_9_OUT;const IfxCcu6_Cc62_Out *cc62Out = &IfxCcu61_CC62_P20_10_OUT;IfxCcu6_Cout60_Out *cout60 = &IfxCcu61_COUT60_P33_12_OUT;IfxCcu6_Cout61_Out *cout61 = &IfxCcu61_COUT61_P33_10_OUT;IfxCcu6_Cout62_Out *cout62 = &IfxCcu61_COUT62_P33_8_OUT;IfxCcu6_initCc60OutPin(cc60Out, IfxPort_OutputMode_pushPull, IfxPort_PadDriver_cmosAutomotiveSpeed1);//Q1IfxCcu6_initCc61OutPin(cc61Out, IfxPort_OutputMode_pushPull, IfxPort_PadDriver_cmosAutomotiveSpeed1);//Q3IfxCcu6_initCc62OutPin(cc62Out, IfxPort_OutputMode_pushPull, IfxPort_PadDriver_cmosAutomotiveSpeed1);//Q5IfxCcu6_initCout60Pin(cout60, IfxPort_OutputMode_pushPull, IfxPort_PadDriver_cmosAutomotiveSpeed1);//Q2IfxCcu6_initCout61Pin(cout61, IfxPort_OutputMode_pushPull, IfxPort_PadDriver_cmosAutomotiveSpeed1);//Q4IfxCcu6_initCout62Pin(cout62, IfxPort_OutputMode_pushPull, IfxPort_PadDriver_cmosAutomotiveSpeed1);//Q6IfxCcu6_enableShadowTransfer(ccu6SFR, TRUE, FALSE);IfxCcu6_startTimer(ccu6SFR, TRUE, FALSE);}

五、Simplefoc正弦svpwm输出

一下代码源自simplefoc,用于输出的正弦信号控制电压,从而驱使电机转动

/******************************************************************************/
void setPhaseVoltage(float Uq, float Ud, float angle_el)
{float Uout;uint32_t sector;float T0,T1,T2;float Ta,Tb,Tc;if(Ud) // only if Ud and Uq set {// _sqrt is an approx of sqrt (3-4% error)Uout = _sqrt(Ud*Ud + Uq*Uq) / voltage_power_supply;// angle normalisation in between 0 and 2pi// only necessary if using _sin and _cos - approximation functionsangle_el = _normalizeAngle(angle_el + atan2(Uq, Ud));}else{// only Uq available - no need for atan2 and sqrtUout = Uq / voltage_power_supply;// angle normalisation in between 0 and 2pi// only necessary if using _sin and _cos - approximation functionsangle_el = _normalizeAngle(angle_el + _PI_2);}if(Uout> 0.577)Uout= 0.577;if(Uout<-0.577)Uout=-0.577;sector = (angle_el / _PI_3) + 1;T1 = _SQRT3*_sin(sector*_PI_3 - angle_el) * Uout;T2 = _SQRT3*_sin(angle_el - (sector-1.0)*_PI_3) * Uout;T0 = 1 - T1 - T2;// calculate the duty cycles(times)switch(sector){case 1:Ta = T1 + T2 + T0/2;Tb = T2 + T0/2;Tc = T0/2;break;case 2:Ta = T1 +  T0/2;Tb = T1 + T2 + T0/2;Tc = T0/2;break;case 3:Ta = T0/2;Tb = T1 + T2 + T0/2;Tc = T2 + T0/2;break;case 4:Ta = T0/2;Tb = T1+ T0/2;Tc = T1 + T2 + T0/2;break;case 5:Ta = T2 + T0/2;Tb = T0/2;Tc = T1 + T2 + T0/2;break;case 6:Ta = T1 + T2 + T0/2;Tb = T0/2;Tc = T1 + T0/2;break;default:  // possible error stateTa = 0;Tb = 0;Tc = 0;}Hall.Ta = (uint16)(Ta*2500);Hall.Tb = (uint16)(Tb*2500);Hall.Tc = (uint16)(Tc*2500);/** 三通道互补pwm输出,* IfxCcu6_setT12CompareValue() 时钟来源,通道选择,占空比设置,最大占空比值2500,50%占空比1250* IfxCcu6_enableShadowTransfer(ccu6SFR, TRUE, FALSE); 设置输出互补pwm波形* */IfxCcu6_setT12CompareValue(ccu6SFR, IfxCcu6_T12Channel_0, Hall.Ta);IfxCcu6_setT12CompareValue(ccu6SFR, IfxCcu6_T12Channel_1, Hall.Tb);IfxCcu6_setT12CompareValue(ccu6SFR, IfxCcu6_T12Channel_2, Hall.Tc);IfxCcu6_enableShadowTransfer(ccu6SFR, TRUE, FALSE);}

六、总结

互补pwm和SVpwm的输出这里就算移植完毕了,明天写,具体的foc控制算法,以及相关的理论。

【FOC控制】英飞凌TC264无刷驱动方案simplefoc移植(2)-SVPWM波实现相关推荐

  1. 【FOC控制】英飞凌TC264无刷驱动方案simplefoc移植(5)-磁编码器移植AS5600 软件IIC

    [FOC控制]英飞凌TC264无刷驱动方案simplefoc移植(5)-磁编码器移植 [FOC控制]英飞凌TC264无刷驱动方案simplefoc移植(5)-磁编码器移植 一.编码器选择 二.通讯方式 ...

  2. 【FOC控制】英飞凌TC264无刷驱动方案simplefoc移植(6)- foc速度闭环控制

    [FOC控制]英飞凌TC264无刷驱动方案simplefoc移植(6)- foc速度闭环控制 [FOC控制]英飞凌TC264无刷驱动方案simplefoc移植(6)- foc速度闭环控制 一.电机选择 ...

  3. 【FOC控制】英飞凌TC264无刷驱动方案simplefoc移植(3)-FOC控制原理矢量控制

    英飞凌TC264无刷驱动方案simplefoc移植(3)-FOC控制原理矢量控制 无刷电机是矢量控制,是交流电机调速的核心,也是Foc控制的核心 以下内容学习自[自制FOC驱动器]深入浅出讲解FOC算 ...

  4. [开源]圆形FOC无刷驱动Baize_foc

    介绍 由于做四足机器狗的需要,所以做了这块圆形无刷电机驱动板,自己取名叫Baize_foc了. 上面集成了as5600磁编码器,电流环等功能.形状为圆形,因此可以非常方便的直接用螺丝固定到电机的后面: ...

  5. 电钻有刷好还是无刷好_高中物理好的来看看,永磁同步直流电机是怎样实现无刷驱动的?...

    相信很多新能源车的车主或者打算购买新能源车的用户都听说过永磁同步直流电机这个名词,因为它在市售的纯电动车中使用率非常高,特别是对于那些20万以下,续航里程400公里以下的纯电动车型,应用非常广泛.吉利 ...

  6. DC12-24V直流无刷驱动器方案,原理图,源代码都有

    DC12-24V直流无刷驱动器方案,原理图,源代码都有

  7. 风筒电吹风无刷驱动设计-电吹风无刷电机PCBA方案设计

    1.电吹风市场现状 近年来伴随居民消费实力和意愿的提升,消费者对产品品质和功能的需求日益增加.随着电吹风产品的升级革新,零售额不断增长.数据显示,2021年,电吹风全年零售额53.8亿元,同比增长10 ...

  8. 深入浅出讲解FOC控制与SVPWM技术

    深入浅出讲解FOC控制与SVPWM技术 0.前言 0.1 什么是FOC 0.2 FOC驱动器和无刷电调的区别 1.从电机原理说起 1.1 一些基础知识 1.2 无刷电机原理 1.3 关于BLDC和PM ...

  9. ACS606开发方案… 源码,伺服驱动,无刷,直流…

    ACS606开发方案- 源码,伺服驱动,无刷,直流- tb341810831

最新文章

  1. kali linux 安装java_kali linux安装java
  2. Google Chrome 超详细使用教程
  3. python exec函数_Python3 exec 函数
  4. 网吧电源和网络布线经验谈(1)
  5. 【枚举】【SPFA】Urozero Autumn Training Camp 2016 Day 5: NWERC-2016 Problem I. Iron and Coal
  6. rsync+sersync实现数据文件实时同步
  7. Modelsim仿真如何查看内部信号
  8. 好文转载—为程序员量身定制的12个目标
  9. 谈谈阿里所谓的——要性
  10. 三星5nm产品开发进度出问题,高通紧急向台积电求援
  11. 数据库单表数据过亿_我也能写数据库 —— 单表查询
  12. 炫彩色块海报设计背景PSD素材,跟上设计趋势
  13. 多个线程对串口读取 modbus_看完这个,如果还不懂Modbus,那您去撞豆腐吧
  14. HTTP请求方式: GET和POST的比较
  15. JS调用服务器端方法
  16. macos 10.15.2 iso镜像网盘下载
  17. IP转发引擎的三种核心处理器区别介绍
  18. Flash Timer的用法 计时器
  19. DCDC电源芯片的引脚功能及应用-BUCK芯片和BOOST芯片
  20. keil中断函数的写法_keil中怎样定义外部中断函数原型?

热门文章

  1. SQL Server 2012附加数据库失败解决办法
  2. mysql iostat_iostat的深入理解
  3. 你是为了什么而做网站的?
  4. java setscale_BigDecimal.setScale(int newScale, int roundingMode)方法实例
  5. 当代年轻人,办过卡=健过身
  6. Qt实现360安全卫士登录界面
  7. Windows环境下下载并安装VMware Workstation Pro 17
  8. 浏览器渲染机制的原理和过程
  9. git 开源的分布式版本控制系统
  10. Amazon SES介绍 - 服务特点