基于DSP280049C的正点原子PMSM电机驱动(二):FOC文件的建立与开环代码编写

FOC.h文件的建立

FOC头文件中,主要放入源文件中将会用到的部分参数值,以及电机相关的参数。

/*
 * FOC.h
 *
 *  Created on: 2023年7月10日
 *      Author: 24460
 */

#ifndef USER_INC_FOC_H_
#define USER_INC_FOC_H_

#include "driverlib.h"
#include "device.h"

/*常用数学值*/
#define pi      3.14159                 //pi
#define pi_2    6.28318                 //2*pi
#define pi_180  0.01745                 //2*pi/360
#define sqrt3   1.73205                 //sqrt(3)
#define sqrt3_2 0.86603                 //sqrt(3)/2
#define sqrt23  0.81649                 //sqrt(2/3)
#define sqrt24  0.70710                 //sqrt(2/4)

/*逆变器相关参数*/
#define Udc     24                      //母线电压
#define fsw     5000                    //MOSFET开关频率,也是PWM的周期频率
#define Ts      0.0002                  //MOSFET开关时间,也是PWM的周期时间,200us
#define K       (sqrt3*Ts)/Udc          //SVPWM中间参数
#define K_park  0.6667                  //clark以及park变换为等大小变换

/*PMSM参数*/
#define rpm_rated   3000    //电机额定机械转速
#define Ed          0.0043  //反电动势系数:0.0043v/rpm
#define Pn          8/2     //极对数
#define R           1.02    //定子电阻,单位为Ω
#define L           0.00059  //定子电感
#define Ld          0.00059  //直轴电感0.59mH
#define Lq          0.00059  //交轴电感0.59mH

void Open_FOC_contral(void);

#endif /* USER_INC_FOC_H_ */

FOC.c文件的建立

FOC源文件中主要是FOC控制的计算过程,并且以函数的形式能够被PWM中断周期性的调用。

/*
 * FOC.c
 *
 *  Created on: 2023年7月10日
 *      Author: 24460
 */

#include "F28x_Project.h"
#include "IQmathLib.h"
#include "FOC.h"
#include "PWM.h"

void Open_FOC_contral(void)
{
    //电流参数
    static _iq ia;static _iq ib;static _iq ic;
    static _iq ialpha;static _iq ibeta;
    static _iq id;static _iq iq;
    //电压参数
    static _iq ua;static _iq ub;static _iq uc;
    static _iq ualpha;static _iq ubeta;
    static _iq ud;static _iq uq;
    //磁通参数定义
    static _iq phi_a;static _iq phi_b;static _iq phi_c;
    static _iq phi_alpha;static _iq phi_beta;
    static _iq phi_d;static _iq phi_q;

    //运行状态参数
    static _iq now_Etheta = _IQ(0);              //当前的电角度值
    static _iq now_Mtheta = _IQ(0);              //当前的机械角度值

    //SVPWM相关参数
    static _iq cos_Etheta;              //当前电角度的cos值,用以坐标变换
    static _iq sin_Etheta;              //当前电角度的sin值,用以坐标变换
    _iq u1;_iq u2;_iq u3;               //中间计算变量
    float U1;  float U2;  float U3;                             //SVPWM电压计算的中间变量
    int A;int B;int C;int N;                                    //扇区判断的中间变量
    float T[8];                                                 //各方向向量作业时间
    float Fu;float Fv;float Fw;                                 //uvw上桥臂置高时间
    float Tu;float Tv;float Tw;                                 //Fu,Fv,Fw与Ts的比值
    /*SVPWM相关参数end*/


    /*************************函数程序开始位置*********************************/
    now_Etheta = now_Etheta + _IQmpy( _IQ(5) , _IQ(pi_180) );  //开环控制,角度自增,每周期增加n°
    cos_Etheta = _IQcos(now_Etheta);
    sin_Etheta = _IQsin(now_Etheta);
    ud = _IQ(0);
    uq = _IQ(5);

    ualpha = _IQmpy( ud , cos_Etheta ) - _IQmpy( uq , sin_Etheta ) ;
    ubeta = _IQmpy( uq , cos_Etheta ) + _IQmpy( ud , sin_Etheta ) ;
    u1 = ubeta;
    u2 = _IQmpy( _IQ(sqrt3_2) , ualpha ) - _IQmpy(_IQ(0.5) , ubeta);
    u3 = _IQmpy( _IQ(-sqrt3_2) , ualpha ) - _IQmpy(_IQ(0.5) , ubeta);
    U1 = _IQtoF(u1);U2 = _IQtoF(u2);U3 = _IQtoF(u3);

    if (U1 > 0)  {A=1;} else {A=0;}
    if (U2 > 0)  {B=1;} else {B=0;}
    if (U3 > 0)  {C=1;} else {C=0;}
    N=4*C+2*B+A;

    switch (N){
            case 1://第二扇区
                T[2]=-K*U3;
                T[6]=-K*U2 ;
                if ( T[2]+T[6]>Ts)
                {
                    T[2]=T[2]*Ts/(T[2]+T[6]);
                    T[6]=T[6]*Ts/(T[2]+T[6]);
                }
                T[0]=(Ts-T[2]-T[6])/2;
                T[7]=T[0];
                T[1]=0.0;
                T[3]=0.0;
                T[4]=0.0;
                T[5]=0.0;
                Fu=T[6]+T[7];
                Fv=T[2]+T[6]+T[7];
                Fw=T[7];
                break;
            case 2://第六扇区
                T[4]=-K*U2;
                T[5]=-K*U1 ;
                if ( T[4]+T[5]>Ts)
                {
                    T[4]=T[4]*Ts/(T[4]+T[5]);
                    T[5]=T[5]*Ts/(T[4]+T[5]);
                }
                T[0]=(Ts-T[4]-T[5])/2;
                T[7]=T[0];
                T[2]=0.0   ;
                T[6]=0.0    ;
                T[1]=0.0               ;
                T[3]=0.0;
                Fu=T[4]+T[5]+T[7];
                Fv=T[7];
                Fw=T[5]+T[7];
                break;
            case 3://第一扇区
                T[4]=K*U3;
                T[6]=K*U1 ;
                if ( T[4]+T[6]>Ts)
                {
                    T[4]=T[4]*Ts/(T[4]+T[6]);
                    T[6]=T[6]*Ts/(T[4]+T[6]);
                }
                T[0]=(Ts-T[4]-T[6])/2;
                T[7]=T[0];
                T[1]=0.0;
                T[2]=0.0;
                T[3]=0.0;
                T[5]=0.0;
                Fu=T[4]+T[6]+T[7];
                Fv=T[6]+T[7];
                Fw=T[7];
                break;
            case 4://第四扇区
                T[1]=-K*U1;
                T[3]=-K*U3 ;
                if ( T[1]+T[3]>Ts)
                {
                    T[1]=T[1]*Ts/(T[1]+T[3]);
                    T[3]=T[3]*Ts/(T[1]+T[3]);
                }
                T[0]=(Ts-T[1]-T[3])/2;
                T[7]=T[0];
                T[2]=0.0   ;
                T[6]=0.0    ;
                T[4]=0.0               ;
                T[5]=0.0;
                Fu=T[7];
                Fv=T[3]+T[7];
                Fw=T[1]+T[3]+T[7];
                break;
            case 5://第三扇区
                T[2]=K*U1;
                T[3]=K*U2;
                if ( T[2]+T[3]>Ts)
                {
                    T[2]=T[2]*Ts/(T[2]+T[3]);
                    T[3]=T[3]*Ts/(T[2]+T[3]);
                }
                T[0]=(Ts-T[2]-T[3])/2;
                T[7]=T[0];
                T[1]=0.0;
                T[6]=0.0;
                T[4]=0.0;
                T[5]=0.0;
                Fu=T[7];
                Fv=T[2]+T[3]+T[7];
                Fw=T[3]+T[7];
                break;
            case 6://第五扇区
                T[1]=K*U2;
                T[5]=K*U3 ;
                if ( T[1]+T[5]>Ts)
                {
                    T[1]=T[1]*Ts/(T[1]+T[5]);
                    T[5]=T[5]*Ts/(T[1]+T[5]);
                }
                T[0]=(Ts-T[1]-T[5])/2;
                T[7]=T[0];
                T[2]=0.0   ;
                T[6]=0.0    ;
                T[4]=0.0               ;
                T[3]=0.0;
                Fu=T[5]+T[7];
                Fv=T[7];
                Fw=T[1]+T[5]+T[7];
                break;
            default :
                break;
        }
        /*以上为电压矢量及其作用时间计算过程*/
        Tu=Fu/Ts;Tv=Fv/Ts;Tw=Fw/Ts;

}

到此,FOC开环控制的程序逻辑基本上明了了,但是此时仅仅是得到了三相桥上桥臂的占空比,下一步就是要配置PWM,并在每个周期中将占空比代入。

基于DSP280049C的电机驱动系列回顾:

(一):CCS文件夹的建立与IQmath导入
(二):FOC文件的建立与开环代码编写

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tony0925

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值