DSP 三电平SVPWM调制算法详解

2021/7/29 12:05:55

本文主要是介绍DSP 三电平SVPWM调制算法详解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

空间矢量图

Step1 扇区判定 

Step2 区域判定

Step3 矢量作用时间计算

 

调制时间波形

SVPWM代码

#define PI_1_3 1.0471975512
#define sqrt_3 1.7320508076
#define sqrt_3_p2 	3.4641016151377545870548926830117
#define sqrt_3_1 0.577350269
#define PI_D_6 0.52359877559829887307710723054658
#define sqrt_3_d6	0.28867513459481288225457439025098



void svgendq_threelevel_calc(SVGENDQ_THREELEVEL *v,PWM_ABC_3_LEVEL *PWMOut)
{	
	//--------Input Variables--------


	Uint16 N=0;
	Uint16 n=0;
	float theta;
	float sine,cosine;
	float m1,m2,m3;
	float Zeta=0;
	float Uref = 0;
	float Ma = 0;
	float x,y;

	float Ta=0,Tb=0,Tc=0;//矢量作用时间

	float T1,T2,T3;    //矢量作用时间-按照先后排序
	float D1,D2,D3;    //占空比,未分相,由瘦到胖
	float DNp1,DNp2,DNp3;

	float DutyA1,DutyA2,DutyB1,DutyB2,DutyC1,DutyC2;//ABC 三相占空比

	theta = v->theta*PI2;
	//------------------Step 2---------------
	if(theta >= 0 && theta < PI_1_3) N = 1;
	else if(theta >= PI_1_3 && theta < PI_1_3 * 2)	N = 2;
	else if(theta >= PI_1_3*2 && theta < PI) N = 3;
	else if(theta >= PI && theta < PI_1_3*4) N = 4;
	else if(theta >= PI_1_3*4 && theta < PI_1_3*5) N = 5;
	else if(theta >= PI_1_3*5 && theta < PI2) N = 6;
	else N = 1;

	//------------------Step 3---------------
	Zeta = theta - PI_1_3*(N-1);
	//------------------Step 4---------------
	Uref = sqrt(v->Ualpha_In * v->Ualpha_In + v->Ubeta_In * v->Ubeta_In);
	//------------------Step 5----------------
//	sincos(Zeta,&sine,&cosine);
	sine = sin(Zeta);
	cosine= cos(Zeta);

	x = Uref*cosine;
	y = Uref*sine;
	if(Zeta <= PI_D_6)  //Region 1 3 5
	{
	    if(y <= (-sqrt_3*x +sqrt_3_1*v->Udc_In))
	    {
	    	n = 1;
	    }
	    else if(y <= (sqrt_3*x - sqrt_3_1*v->Udc_In))
	    {
	        n = 5;
	    }
	    else
	    {
	        n = 3;
	    }
	}
	else  //Region 2 4 6
	{
	    if(y <= (-sqrt_3*x +sqrt_3_1*v->Udc_In))
	    {
	        n = 2;
	    }
	    else if(y >= sqrt_3_d6*v->Udc_In)
	    {
	        n = 6;
	    }
	    else
	    {
	        n = 4;
	    }
	}
	Ma = sqrt_3_p2*Uref/v->Udc_In;
	m3 = Ma * sine;
	sine = sin(PI_1_3 - Zeta);
	m1 = Ma*sine;
	sine = sin(PI_1_3 + Zeta);
	m2 = Ma*sine;


	//------------------Step 6----------------
	if(N == 1 || N==3 || N==5)
	{
		switch(n)
		{
			case 1:Ta = m1;Tb = 1 - m2;Tc = m3;	break;
			case 2:Ta = m1;Tb = 1 - m2;Tc = m3; break;
			case 3:Ta = 1 - m3;Tb = m2 - 1;Tc = 1 - m1;break;
			case 4:Ta = 1 - m3;Tb = m2 - 1;Tc = 1 - m1;break;
			case 5:Ta = 2- m2;Tb = m3;Tc = m1 - 1;break;
			case 6:Ta = m3 - 1;Tb = m1;Tc = 2- m2;break;
			default:Ta = 0;Tb = 0;Tc = 0;break;
		}
	}
	else
	{
		switch(n)
		{
			case 1:Ta = m3;Tb = 1 - m2;Tc = m1;break;
			case 2:Ta = m3;Tb = 1 - m2;Tc = m1;break;
			case 3:Ta = 1 - m1;Tb = m2 - 1;Tc = 1 - m3;break;
			case 4:Ta = 1 - m1;Tb = m2 - 1;Tc = 1 - m3;break;
			case 5:Ta = m1 - 1;Tb = m3;Tc = 2- m2;break;
			case 6:Ta = 2- m2;Tb = m1;Tc = m3 - 1;break;
			default:Ta = 0;Tb = 0;Tc = 0;break;
		}
	}

	//------------------Step 7----------------
	if((N == 1)||(N == 3)||(N == 5))
	{
	    if((n == 1)||(n == 3)||(n == 5))
	    {
	        T1 = Ta;
			T2 = Tc;
			T3 = Tb;
	    }
		else
		{
	        T1 = Tc;
	        T2 = Tb;
			T3 = Ta;
		}
	}
	else
	{
	    if((n == 1)||(n == 3)||(n == 5))
	    {
	        T1 = Tc;
	        T2 = Tb;
			T3 = Ta;
	    }
		else
		{
			T1 = Ta;
			T2 = Tc;
			T3 = Tb;
		}
	}

	//------------------Step 8----------------
	D1 = T1*0.5;
	D2 = T1*0.5+T3;
	D3 = T1*0.5+T3+T2;
	//------------------Step 9----------------
	if (v->NPFactor_In > (T1*0.8))
	{
		v->NPFactor_In  = T1*0.8;
	}
	else if(v->NPFactor_In < (-T1*0.8))
	{
		v->NPFactor_In  = -T1*0.8;
	}
	switch(N)
	{
		case 1:  //N
			if((n == 1)||(n == 3)||(n==5))
			{
				if(v->Ia_In >= 0)
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
			}
			else
			{
				if(v->Ic_In >= 0)
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
			}
		break;

		case 2:  //N
			if((n == 1)||(n == 3)||(n==5))
			{
				if(v->Ic_In >= 0)
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
			}
			else
				{
				if(v->Ib_In >= 0)
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
			}
		break;

		case 3:  //N
			if((n == 1)||(n == 3)||(n==5))
			{
				if(v->Ib_In >= 0)
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
			}
			else
			{
				if(v->Ia_In >= 0)
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
			}
		break;

		case 4:  //N
			if((n == 1)||(n == 3)||(n==5))
			{
				if(v->Ia_In >= 0)
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
			}
			else
			{
				if(v->Ic_In >= 0)
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
			}
		break;

		case 5:  //N
			if((n == 1)||(n == 3)||(n==5))
			{
				if(v->Ic_In >= 0)
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
			}
			else
			{
				if(v->Ib_In >= 0)
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
			}
		break;


		case 6:  //N
			if((n == 1)||(n == 3)||(n==5))
			{
				if(v->Ib_In >= 0)
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
			}
			else
			{
				if(v->Ia_In >= 0)
				{
					DNp1 = D1 - v->NPFactor_In*0.5;
					DNp2 = D2 - v->NPFactor_In*0.5;
					DNp3 = D3 - v->NPFactor_In*0.5;
				}
				else
				{
					DNp1 = D1 + v->NPFactor_In*0.5;
					DNp2 = D2 + v->NPFactor_In*0.5;
					DNp3 = D3 + v->NPFactor_In*0.5;
				}
			}
		break;
	}


	//------------------Step 10----------------

	LIMIT(DNp1,v->pMaxDuty,v->pMinDuty);
	LIMIT(DNp2,v->pMaxDuty,v->pMinDuty);
	LIMIT(DNp3,v->pMaxDuty,v->pMinDuty);


	//------------------Step 11----------------
		switch(N)
		{
		    case 1:
				switch(n)
				{
				    case 1:
						DutyA1 = DNp1;
						DutyA2 = 1;
						DutyB1 = 0;
						DutyB2 = DNp3;
						DutyC1 = 0;
						DutyC2 = DNp2;
					break;

				    case 2:
						DutyA1 = DNp2;
						DutyA2 = 1;
						DutyB1 = DNp1;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp3;
					break;

				    case 3:
						DutyA1 = DNp2;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp3;
	                    DutyC1 = 0;
						DutyC2 = DNp1;
					break;

					case 4:
						DutyA1 = DNp3;
						DutyA2 = 1;
						DutyB1 = DNp1;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp2;
					break;

					case 5:
						DutyA1 = DNp3;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp2;
	                    DutyC1 = 0;
						DutyC2 = DNp1;
					break;

					case 6:
						DutyA1 = DNp3;
						DutyA2 = 1;
						DutyB1 = DNp2;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp1;
					break;
				}
			break;

		    case 2:
				switch(n)
				{
				    case 1:
						DutyA1 = DNp1;
						DutyA2 = 1;
						DutyB1 = DNp2;
						DutyB2 = 1;
						DutyC1 = 0;
						DutyC2 = DNp3;
					break;

				    case 2:
						DutyA1 = 0;
						DutyA2 = DNp3;
						DutyB1 = DNp1;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp2;
					break;

				    case 3:
						DutyA1 = DNp1;
						DutyA2 = 1;
						DutyB1 = DNp3;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp2;
					break;

					case 4:
						DutyA1 = 0;
						DutyA2 = DNp3;
						DutyB1 = DNp2;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp1;
					break;

					case 5:
						DutyA1 = DNp2;
						DutyA2 = 1;
						DutyB1 = DNp3;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp1;
					break;

					case 6:
						DutyA1 = 0;
						DutyA2 = DNp2;
						DutyB1 = DNp3;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp1;
					break;
				}
			break;

		    case 3:
				switch(n)
				{
				    case 1:
						DutyA1 = 0;
						DutyA2 = DNp2;
						DutyB1 = DNp1;
						DutyB2 = 1;
						DutyC1 = 0;
						DutyC2 = DNp3;
					break;

				    case 2:
						DutyA1 = 0;
						DutyA2 = DNp3;
						DutyB1 = DNp2;
	                    DutyB2 = 1;
	                    DutyC1 = DNp1;
						DutyC2 = 1;
					break;

				    case 3:
						DutyA1 = 0;
						DutyA2 = DNp1;
						DutyB1 = DNp2;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp3;
					break;

					case 4:
						DutyA1 = 0;
						DutyA2 = DNp2;
						DutyB1 = DNp3;
	                    DutyB2 = 1;
	                    DutyC1 = DNp1;
						DutyC2 = 1;
					break;

					case 5:
						DutyA1 = 0;
						DutyA2 = DNp1;
						DutyB1 = DNp3;
	                    DutyB2 = 1;
	                    DutyC1 = 0;
						DutyC2 = DNp2;
					break;

					case 6:
						DutyA1 = 0;
						DutyA2 = DNp1;
						DutyB1 = DNp3;
	                    DutyB2 = 1;
	                    DutyC1 = DNp2;
						DutyC2 = 1;
					break;
				}
			break;

		    case 4:
				switch(n)
				{
				    case 1:
						DutyA1 = 0;
						DutyA2 = DNp3;
						DutyB1 = DNp1;
						DutyB2 = 1;
						DutyC1 = DNp2;
						DutyC2 = 1;
					break;

				    case 2:
						DutyA1 = 0;
						DutyA2 = DNp2;
						DutyB1 = 0;
	                    DutyB2 = DNp3;
	                    DutyC1 = DNp1;
						DutyC2 = 1;
					break;

				    case 3:
						DutyA1 = 0;
						DutyA2 = DNp2;
						DutyB1 = DNp1;
	                    DutyB2 = 1;
	                    DutyC1 = DNp3;
						DutyC2 = 1;
					break;

					case 4:
						DutyA1 = 0;
						DutyA2 = DNp1;
						DutyB1 = 0;
	                    DutyB2 = DNp3;
	                    DutyC1 = DNp2;
						DutyC2 = 1;
					break;

					case 5:
						DutyA1 = 0;
						DutyA2 = DNp1;
						DutyB1 = DNp2;
	                    DutyB2 = 1;
	                    DutyC1 = DNp3;
						DutyC2 = 1;
					break;

					case 6:
						DutyA1 = 0;
						DutyA2 = DNp1;
						DutyB1 = 0;
	                    DutyB2 = DNp2;
	                    DutyC1 = DNp3;
						DutyC2 = 1;
					break;
				}
			break;

			case 5:
				switch(n)
				{
				    case 1:
						DutyA1 = 0;
						DutyA2 = DNp3;
						DutyB1 = 0;
						DutyB2 = DNp2;
						DutyC1 = DNp1;
						DutyC2 = 1;
					break;

				    case 2:
						DutyA1 = DNp1;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp3;
	                    DutyC1 = DNp2;
						DutyC2 = 1;
					break;

				    case 3:
						DutyA1 = 0;
						DutyA2 = DNp3;
						DutyB1 = 0;
	                    DutyB2 = DNp1;
	                    DutyC1 = DNp2;
						DutyC2 = 1;
					break;

					case 4:
						DutyA1 = DNp1;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp2;
	                    DutyC1 = DNp3;
						DutyC2 = 1;
					break;

					case 5:
						DutyA1 = 0;
						DutyA2 = DNp2;
						DutyB1 = 0;
	                    DutyB2 = DNp1;
	                    DutyC1 = DNp3;
						DutyC2 = 1;
					break;

					case 6:
						DutyA1 = DNp2;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp1;
	                    DutyC1 = DNp3;
						DutyC2 = 1;
					break;
				}
			break;

			case 6:
				switch(n)
				{
				    case 1:
						DutyA1 = DNp2;
						DutyA2 = 1;
						DutyB1 = 0;
						DutyB2 = DNp3;
						DutyC1 = DNp1;
						DutyC2 = 1;
					break;

				    case 2:
						DutyA1 = DNp1;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp2;
	                    DutyC1 = 0;
						DutyC2 = DNp3;
					break;

				    case 3:
						DutyA1 = DNp3;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp2;
	                    DutyC1 = DNp1;
						DutyC2 = 1;
					break;

					case 4:
						DutyA1 = DNp2;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp1;
	                    DutyC1 = 0;
						DutyC2 = DNp3;
					break;

					case 5:
						DutyA1 = DNp3;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp1;
	                    DutyC1 = DNp2;
						DutyC2 = 1;
					break;

					case 6:
						DutyA1 = DNp3;
						DutyA2 = 1;
						DutyB1 = 0;
	                    DutyB2 = DNp1;
	                    DutyC1 = 0;
						DutyC2 = DNp2;
					break;
				}
			break;
		}



	//-----------Update Output-------------

	    PWMOut->Ta13 = DutyA1;
	    PWMOut->Ta24 = DutyA2;
	    PWMOut->Tb13 = DutyB1;
	    PWMOut->Tb24 = DutyB2;
	    PWMOut->Tc13 = DutyC1;
	    PWMOut->Tc24 = DutyC2;

}

 应用示例

 // 开环给定
   Sp->SpsCtlInner.Pwm_Udq.dp  =  Sp->SpsCtlCfg.InvUdRef  *Sp->SpsCtlInner.BaseValue.Ubase_1;
    Sp->SpsCtlInner.Pwm_Udq.qp  =  0;
    Sp->SpsCtlInner.Pwm_Udc     =  Sp->SpsCtlCfg.InvUdcRef *Sp->SpsCtlInner.BaseValue.Udcbase_1;
// 自生成角度
    genvf.Frequency = Sp->SpsCtlCfg.InvFreqRef*Sp->SpsCtlInner.BaseValue.Fbase_1;
    genvf.dt = Sp->SpsCtlOutPort.SwiCalTime.CtlDt;
    Sp->SpsCtlOutPort.Freqs_toRms = genvf.Frequency *Sp->SpsCtlInner.BaseValue.Fbase;

    gen_vf_pll(&genvf);

    ipark_calc(Sp->SpsCtlInner.Pwm_Udq.dp,
               0,
               genvf.SineTheta,
               genvf.CoseTheta,
               &Sp->SpsCtlInner.PwmAlphaBeta.alpha_p,
               &Sp->SpsCtlInner.PwmAlphaBeta.beta_p);

//Svpwm 给定
    Sp->SpsCtlInner.Svpwm_In.Ualpha_In = Sp->SpsCtlInner.PwmAlphaBeta.alpha_p;
    Sp->SpsCtlInner.Svpwm_In.Ubeta_In  = Sp->SpsCtlInner.PwmAlphaBeta.beta_p;


    Sp->SpsCtlInner.Svpwm_In.Udc_In =Sp->SpsCtlInner.Pwm_Udc;
    Sp->SpsCtlInner.Svpwm_In.theta =genvf.theta;

    Sp->SpsCtlInner.Svpwm_In.NPFactor_In=0;
    Sp->SpsCtlInner.Svpwm_In.Ia_In=0;
    Sp->SpsCtlInner.Svpwm_In.Ib_In=0;
    Sp->SpsCtlInner.Svpwm_In.Ic_In=0;
    Sp->SpsCtlInner.Svpwm_In.pMinDuty=0;
    Sp->SpsCtlInner.Svpwm_In.pMaxDuty=100;

    svgendq_threelevel_calc(&(Sp->SpsCtlInner.Svpwm_In),&(Sp->SpsCtlOutPort.PwmOut3L));

    LIMIT(Sp->SpsCtlOutPort.PwmOut3L.Ta13,1,0);
    LIMIT(Sp->SpsCtlOutPort.PwmOut3L.Ta24,1,0);
    LIMIT(Sp->SpsCtlOutPort.PwmOut3L.Tb13,1,0);
    LIMIT(Sp->SpsCtlOutPort.PwmOut3L.Tb24,1,0);
    LIMIT(Sp->SpsCtlOutPort.PwmOut3L.Tc13,1,0);
    LIMIT(Sp->SpsCtlOutPort.PwmOut3L.Tc24,1,0);

RP3220 控制器 在  PLECS RTLAB仿真测试 

 

 



这篇关于DSP 三电平SVPWM调制算法详解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程