SVPWM原理及编程实现(Ti的库)

这篇文章中介绍到的符号及其含义参考:

永磁同步电机SVPWM技术参考

1. 标幺值

标幺值是相对于某一基准值而言的,同一有名值,当基准值选取不同时,其标幺值也不同。

标幺值 = 某物理量的实际值/该物理量的基准值

2. 标幺化处理

2.1 电压幅值进行标幺(归一)化处理

线电压最大值为U_{dc},q轴电压最大值的绝对值为U_{dc}/\sqrt{3},选择U_{dc}/\sqrt{3}为基(准)值,则有:

U_{4}=U_{6}=\frac{2}{3}U_{dc} ,其标幺值  为\frac{2}{\sqrt{3}}U_{dc}被标幺化之后,其值为\sqrt{3}。注意一点,U_{dc}标幺化意味着跟电压相关的量都进行了处理

2.2 对矢量作用时间进行标幺化

根据参考文章,可知U_{4}U_{6}的作用时间为:

 这里的U_{dc}=\sqrt{3},然后式(2-20)可以写成

T_{4}=\frac{T_{s}}{2}(\sqrt{3}u_{\alpha }-u_{\beta }) ,T_{6}=\frac{T_{s}}{2}u_{\beta }

对时间进行归一化处理:以载波周期T为基准值,则有:

T_{4}=\frac{1}{2}(\sqrt{3}u_{\alpha }-u_{\beta }),T_{6}=\frac{1}{2}u_{\beta }

同理可以得出其他扇区各矢量的作用时间。令

 也就是

 因为涉及到多个扇区,因此制定下面一个标准

扇区 U4和U6 U2和U6 U2和U3 U1和U3 U1和U5 U4和U5
t1 -Z Z X -X -Y Y
t2 X    Y -Y Z -Z -X

   

扇区 1 2 3 4 5 6
t1对应矢量 U4 U2 U2 U1 U1 U4
t2对应矢量 U6 U6 U3 U3 U5 U5

那么N与作用时间的关系为,其中T4=T1,T6=T2

 采用七段式SVPWM调制,每个载波周期中依次有:1个开关导通–>2个开关导通–>3个开关导通–>2个开关导通–>1个开关导通

3. 硬件实现SVPWM流程

1. 确定扇区(还有N),注意一点N和扇区不是一个东西;参考文章

2. 计算X、Y、Z,进而计算t1,t2;

3. 确定taon、tbon、tcon赋值给Ta、Tb、Tc;这一步也参考 参考文章中的表2-2,很容易推出各个开关管的开启关断时间。

4. 把Ta、Tb、Tc赋给CMPRx。   

下面是Ti的代码,注意一点Sector表示的是N的值,其他很简单。

/* =================================================================================
File name:       SVGEN_DQ.H  (IQ version)                    
                    
Originator:	Digital Control Systems Group
			Texas Instruments

Description: 
Header file containing constants, data type, and macro  definitions for the SVGEN_DQ module .
=====================================================================================
 History:
-------------------------------------------------------------------------------------
 4-15-2010	Version 1.1                                                 
------------------------------------------------------------------------------*/
#ifndef __SVGEN_DQ_H__
#define __SVGEN_DQ_H__



typedef struct 	{ _iq  Ualpha; 			// Input: reference alpha-axis phase voltage 
				  _iq  Ubeta;			// Input: reference beta-axis phase voltage 
				  _iq  Ta;				// Output: reference phase-a switching function		
				  _iq  Tb;				// Output: reference phase-b switching function 
				  _iq  Tc;				// Output: reference phase-c switching function
				  Uint16 N;
				} SVGENDQ;
																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																				
typedef SVGENDQ *SVGENDQ_handle;
/*-----------------------------------------------------------------------------
Default initalizer for the SVGENDQ object.
-----------------------------------------------------------------------------*/                     
#define SVGENDQ_DEFAULTS { 0,0,0,0,0,0 }

/*------------------------------------------------------------------------------
	Space Vector PWM Generator (SVGEN_DQ) Macro Definition
------------------------------------------------------------------------------*/


_iq Va,Vb,Vc,t1,t2,temp_sv1,temp_sv2;
Uint16 Sector = 0;  // Sector is treated as Q0 - independently with global Q

#define SVGEN_MACRO(v)															\
																				\
	Sector = 0;																	\
	temp_sv1=_IQdiv2(v.Ubeta); 					/*divide by 2*/					\
	temp_sv2=_IQmpy(_IQ(0.8660254),v.Ualpha);	/* 0.8660254 = sqrt(3)/2*/		\
																				\
/* Inverse clarke transformation */												\
	Va = v.Ubeta;																\
	Vb = -temp_sv1 + temp_sv2;													\
	Vc = -temp_sv1 - temp_sv2;													\
/* 60 degree Sector determination */											\
	if (Va>_IQ(0)) Sector = 1;													\
	if (Vb>_IQ(0)) Sector = Sector+2;											\
	if (Vc>_IQ(0)) Sector = Sector+4;											\
	v.N = Sector;                                                               \
/* X,Y,Z (Va,Vb,Vc) calculations X = Va, Y = Vb, Z = Vc */						\
	Va = v.Ubeta;																\
	Vb = temp_sv1 + temp_sv2;													\
	Vc = temp_sv1 - temp_sv2;													\
/* Sector 0: this is special case for (Ualpha,Ubeta) = (0,0)*/					\
switch(Sector)																	\
{																				\
	case 0:																		\
	v.Ta = _IQ(0.5);															\
	v.Tb = _IQ(0.5);															\
	v.Tc = _IQ(0.5);															\
	break;																		\
	case 1:   /*Sector 1: t1=Z and t2=Y (abc ---> Tb,Ta,Tc)*/					\
	t1 = Vc;																	\
	t2 = Vb;																	\
	v.Tb=_IQdiv2((_IQ(1)-t1-t2)); 												\
	v.Ta = v.Tb+t1;			 	/* taon = tbon+t1		*/						\
	v.Tc = v.Ta+t2;			  	/* tcon = taon+t2		*/						\
	break;																		\
	case 2:	  /* Sector 2: t1=Y and t2=-X (abc ---> Ta,Tc,Tb)*/ 				\
	t1 = Vb;																	\
	t2 = -Va;																	\
	v.Ta=_IQdiv2((_IQ(1)-t1-t2)); 												\
	v.Tc = v.Ta+t1;				/*  tcon = taon+t1		*/						\
	v.Tb = v.Tc+t2;				/*  tbon = tcon+t2		*/						\
	break;																		\
	case 3:	  /* Sector 3: t1=-Z and t2=X (abc ---> Ta,Tb,Tc)*/					\
	t1 = -Vc;																	\
	t2 = Va;																	\
	v.Ta=_IQdiv2((_IQ(1)-t1-t2)); 												\
	v.Tb = v.Ta+t1;				/*	tbon = taon+t1		*/						\
	v.Tc = v.Tb+t2;				/*	tcon = tbon+t2		*/						\
	break;																		\
	case 4:	  /* Sector 4: t1=-X and t2=Z (abc ---> Tc,Tb,Ta)*/					\
	t1 = -Va;																	\
	t2 = Vc;																	\
	v.Tc=_IQdiv2((_IQ(1)-t1-t2)); 												\
	v.Tb = v.Tc+t1;				/*	tbon = tcon+t1		*/						\
	v.Ta = v.Tb+t2;				/*	taon = tbon+t2		*/						\
	break;																		\
	case 5:	  /* Sector 5: t1=X and t2=-Y (abc ---> Tb,Tc,Ta)*/					\
	t1 = Va;																	\
	t2 = -Vb;					/*	tbon = (1-t1-t2)/2	*/						\
	v.Tb=_IQdiv2((_IQ(1)-t1-t2)); 												\
	v.Tc = v.Tb+t1;				/*	taon = tcon+t2		*/						\
	v.Ta = v.Tc+t2;																\
	break;																		\
	case 6:	  /* Sector 6: t1=-Y and t2=-Z (abc ---> Tc,Ta,Tb)*/				\
	t1 = -Vb;																	\
	t2 = -Vc;																	\
	v.Tc=_IQdiv2((_IQ(1)-t1-t2)); 												\
	v.Ta = v.Tc+t1;				/*	taon = tcon+t1		*/						\
	v.Tb = v.Ta+t2;				/*	tbon = taon+t2		*/						\
	break;																		\
}																				\
/*  Convert the unsigned GLOBAL_Q format (ranged (0,1)) ->.. */					\
/* 	..signed GLOBAL_Q format (ranged (-1,1))*/									\
v.Ta = _IQmpy2(v.Ta-_IQ(0.5));													\
v.Tb = _IQmpy2(v.Tb-_IQ(0.5));													\
v.Tc = _IQmpy2(v.Tc-_IQ(0.5));													\

#endif // __SVGEN_DQ_H__

    Ts(时基周期寄存器的值)=2* v.HalfPerMax,v.MfuncC1,v.MfuncC2,v.MfuncC2,分别等于v.Ta,v.Tb,v.Tc。

#define PWM_MACRO(ch1,ch2,ch3,v)													\
																					\
/*  Mfuncx range is (-1,1)														*/	\
/*  The code below changes PeriodMax*Mfuncx range ....  						*/	\
/*  from (-PeriodMax,PeriodMax) to (0,PeriodMax) where HalfPerMax=PeriodMax/2	*/	\
																					\
	(*ePWM[ch1]).CMPA.half.CMPA = _IQmpy(v.HalfPerMax,v.MfuncC1)+ v.HalfPerMax;		\
	(*ePWM[ch2]).CMPA.half.CMPA = _IQmpy(v.HalfPerMax,v.MfuncC2)+ v.HalfPerMax;		\
	(*ePWM[ch3]).CMPA.half.CMPA = _IQmpy(v.HalfPerMax,v.MfuncC3)+ v.HalfPerMax;		\

           


版权声明:本文为qq_34539334原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。