C语言SVPWM代码与软件测试

在电机控制中矢量输出主要由三部分构成,一是速度控制块;二是角度控制块,三是矢量计算输出。

速度控制结构

typedef struct { 
s32    TargetValue; 	// Input: Target input (pu)
u32    RampDelayMax;	// Parameter: Maximum delay rate (Q0) - independently with global Q
s32    RampLowLimit;	// Parameter: Minimum limit (pu)
s32    RampHighLimit;	// Parameter: Maximum limit (pu)
u32    RampDelayCount; // Variable: Incremental delay (Q0) - independently with global Q
s32    SetpointValue;	// Output: Target output (pu)
u32    EqualFlag;		// Output: Flag output (Q0) - independently with global Q
s32	   Tmp;			// Variable: Temp variable
} RMPCNTL;

定义一个速度控制块

RMPCNTL rap_cntl = RMPCNTL_DEFAULTS;
RMPCNTL *p_rap_cntl = &rap_cntl;

调用速度控制函数,设置目标速度:

p_rap_cntl->TargetValue = SpeedRef;//目标速度 此处目标速度采用Q15定标 即#define Q15    32768  最大速度对应32768
RC_Cal(p_rap_cntl);//加减速控制块

线性加减速函数实现,在该函数中可以实现不同的加减速曲线,使得运行曲线更为平滑

void RC_Cal(RMPCNTL *v)
{
	v->Tmp = v->TargetValue - v->SetpointValue; //Q15
    /*  0.0000305 is resolution of Q15 */
    if (abs_1(v->Tmp) >= Q4)//最小速度误差 Q4 即 #define Q4     16
    {
            v->RampDelayCount++	; 
            if (v->RampDelayCount >= v->RampDelayMax)//速度给定延时
            {
                if (v->TargetValue >= v->SetpointValue)//线性加减速
                    v->SetpointValue += Q4;
                else
                    v->SetpointValue -= Q4;
                v->SetpointValue=SatLimit(v->SetpointValue,v->RampHighLimit,v->RampLowLimit);//速度上线限定
                v->RampDelayCount = 0;
            }
    }
    else v->EqualFlag = 0x7FFFFFFF;
}

角度生成模块

角度模块为速度模块的积分,其实现结构如下:

typedef struct {
 s32  Freq; 		// Input: Ramp frequency (pu)
s32  StepAngleMax;	// Parameter: Maximum step angle (pu)
s32  Angle;		// Variable: Step angle (pu)
s32  Gain;			// Input: Ramp gain (pu)
s32  Out;  	 	// Output: Ramp signal (pu)
s32  Offset;		// Input: Ramp offset (pu)
s32  Angle_L;		// Variable: Step angle (pu)
} RAMPGEN;

定义

RAMPGEN rg1 = RAMPGEN_DEFAULTS;
RAMPGEN *p_rg1 = &rg1;

调用

p_rg1->Freq = p_rap_cntl->SetpointValue;
RG_Cal(p_rg1); //angle

实现

void RGInit(RAMPGEN *v)
{
   v->StepAngleMax = 2*Q14*F1Max/F2Set;//最大步进角度  F1Max是最大电气频率,F2Set为载波频率,Q14为角度定标 #define Q14    16384 对应180度,比如载波频率1K,最大电频率100Hz,那么最大步进叫度则为360/(1K/100) = 36度 归一化之后则是Q14*(360/(F2Set/F1Max))/180 =>Q14*(2*F1Max/F2Set);
   v->Angle_L = 0;
}

void RG_Cal(RAMPGEN *v)
{
/* Compute the angle rate */
/*此处即求余也求商目的是防止积分累计时舍去误差过大,将余数累计避免余数舍去时造成较大误差*/
	v->Angle += (v->StepAngleMax*v->Freq)/32768;
	v->Angle_L += (v->StepAngleMax*v->Freq)%32768;
	if(v->Angle_L > 32768 )
    {
        v->Angle+=1;
        v->Angle_L -= 32768;
    }													\
/* Saturate the angle rate within (-1,1) 控制角度范围*/
        if(v->Angle > Q14)
        {
            v->Angle = v->Angle - Q14;
        }else if(v->Angle < -Q14)
        {
            v->Angle = Q14- v->Angle;
        }
}

加入dq值之后进行坐标变换

p_ipark1->Angle = p_rg1->Angle;
p_ipark1->Sine = SinQ14(p_rg1->Angle); //Q15
p_ipark1->Cosine = CosQ14(p_rg1->Angle);
p_ipark1->Ds  = VdTesting = Q15;//Q15
p_ipark1->Qs  = VqTesting = Q15;
p_ipark1->Sine=   p_ipark1->Sine;
p_ipark1->Cosine= p_ipark1->Cosine;
IPARK_Cal(p_ipark1);
p_svgen1->Ualpha = p_ipark1->Alpha/Q15;
p_svgen1->Ubeta = p_ipark1->Beta/Q15;

SVPWM处理结构

SVPWM处理结构

typedef struct 	{ 
s32  Ualpha; 			// Input: reference alpha-axis phase voltage
s32  Ubeta;			// Input: reference beta-axis phase voltage
s32  Ta;				// Output: reference phase-a switching function
s32  Tb;				// Output: reference phase-b switching function
s32  Tc;				// Output: reference phase-c switching function
s32  tmp1;			// Variable: temp variable
s32  tmp2;			// Variable: temp variable
s32  tmp3;			// Variable: temp variable
s32 VecSector;		// Space vector sector
} SVGEN;

输入alpha beta轴参数,计算三个矢量的作用时间(Ta,Tb,Tc)

void SvTimeCal(SVGEN *v)
{
	v->tmp1= v->Ubeta;
	v->tmp2= v->Ubeta/2 + 866*v->Ualpha/1000;
    v->tmp3= v->tmp2 - v->tmp1;

	v->VecSector=3;
	v->VecSector=(v->tmp2> 0)?( v->VecSector-1):v->VecSector;
	v->VecSector=(v->tmp3> 0)?( v->VecSector-1):v->VecSector;
	v->VecSector=(v->tmp1< 0)?(7-v->VecSector) :v->VecSector;

	if(v->VecSector==1 || v->VecSector==4)
	{
			v->Ta= v->tmp2;
			v->Tb= v->tmp1-v->tmp3;
			v->Tc=-v->tmp2;
	}
  else if(v->VecSector==2 || v->VecSector==5)
	{
			v->Ta= v->tmp3+v->tmp2;
			v->Tb= v->tmp1;
			v->Tc=-v->tmp1;
	}
	else
	{   
		v->Ta= v->tmp3;
		v->Tb=-v->tmp3;
		v->Tc=-(v->tmp1+v->tmp2);
	}
}

调用函数产生波形并输出到文件

int main()
{
    u32 SpeedRef = Q15;
    u32 TIME = 10000;
    u32 i=0;
    s32 VdTesting = 10;
    s32 VqTesting = 10;
    file = fopen("01.txt","w");
    RcInit(p_rap_cntl);
    RGInit(p_rg1);
    for (i=0;i<TIME;i++)
    {
        SvpwmGen(p_svgen1);
        fprintf(file ,"%d\n",p_svgen1->Ta );
    }
    fclose(file);
    return 0;
}

在这里插入图片描述

  • 4
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
SVPWM(Space Vector Pulse Width Modulation)是一种用于三相逆变器控制的PWM技术。它通过控制电压矢量的方向和幅值,实现对输出电压的精确控制。 以下是一个简单的C语言实现SVPWM发波算法的示例: ```c #include <stdio.h> #include <math.h> #define PI 3.14159265359 // 定义电压矢量结构体 typedef struct { double u; double v; double w; } VoltageVector; // 计算电压矢量幅值和相位 VoltageVector calculateVoltageVector(double amplitude, double angle) { VoltageVector vector; vector.u = amplitude * cos(angle); vector.v = amplitude * cos(angle - (2.0 * PI / 3.0)); vector.w = amplitude * cos(angle + (2.0 * PI / 3.0)); return vector; } // SVPWM发波算法 void svpwm(double amplitude, double angle) { VoltageVector vector = calculateVoltageVector(amplitude, angle); // 根据电压矢量确定PWM占空比 double dutyCycleU = (vector.u + amplitude) / (2.0 * amplitude); double dutyCycleV = (vector.v + amplitude) / (2.0 * amplitude); double dutyCycleW = (vector.w + amplitude) / (2.0 * amplitude); // 输出PWM占空比 printf("Duty Cycle U: %.2f\n", dutyCycleU); printf("Duty Cycle V: %.2f\n", dutyCycleV); printf("Duty Cycle W: %.2f\n", dutyCycleW); } int main() { double amplitude = 1.0; // 电压幅值 double angle = 0.0; // 电压矢量相位 svpwm(amplitude, angle); return 0; } ``` 这个示例演示了如何使用SVPWM发波算法计算三相逆变器的PWM占空比。你可以根据实际需求调整电压幅值和相位角来生成不同的PWM波形。注意,这只是一个简单的示例,实际的SVPWM算法可能需要更复杂的计算和控制逻辑。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值