SVPWM设计规则第15章用TMS320LF2407实现空间矢量PWM(SVPWM)15.3利用TMS320LF240x实现SVPWM算法的程序下面给出了利用TMS320LF2407实现SVPWM算法的一个应用程序。在该程序中,我们假设有200个电压矢量Uout平均分布在电角度为2π的范围内,通过改变SVPWM的调制周期T可以改变输出的3相正弦波的频率。源程序代码:(1)所需的复位和中断矢量定义文件“vectors.asm”请读者参考本书相关章节。(2)主程序//该程序用于简单的SVPWM演示,产生3相互差120度电角度的正弦交流电压,此程序实//时计算cmp1和cmp2的值#includeregister.h#includefloat.h#includemath.hfloatualfa[200],ubeta[200];//存储电压矢量Uout的(α,β)轴分量ualfa、ubeta的数组intsector[200];//定义存储扇区数的数组#definePI22*3.1415926//定义2π的值#defineDETAPI2/200//定义相临两个Uout之间的电角度的差值#defineINIA3.1415926/180//定义Uout的初始电角度#defineTP1200//t1的周期寄存器的值,其值等于SVPWM调制周期T的一半,//因为在该程序中2π电角度内Uout的点数一定,故改变此值//可以改变输出的3相正弦交流电压的频率#defineKP0.7//定义Uout的标幺值,KP的值在0和1之间,改变此值可以//改变逆变桥输出电压的幅值//屏蔽中断子程序voidinlinedisable(){asm(setcINTM);}//系统初始化子程序viodinitial(){*IFR=0xFFFF;//清除所有的中断标志*IMR=0X0;//屏蔽所有中断*SCSR1=0x81FE;//CLKIN=6M,CLKOUT=24M*WDCR=0xE8;//不使能看门狗*T3PER=TP;//通用定时器1的周期=PWM的周期/指令周期/2*T3CON=0X0802;//设置通用定时器1为连续增减模式,以产生对称的PWM,//且为了便于调试,使仿真一挂起时时钟就停止运行*ACTRB=0X666;//PWM7、9、11高有效,PWM8、10、12低有效*COMCONB=0X9200;//使能PWM输出和比较动作*EVBIMRA=0X00;//禁止EVB和时钟及比较有关的中断*T3CNT=0X00;//T1的计数器清0*EVBIFRA=0x0FFFF;//清除EVB相应的中断标志*MCRC=*MCRC|0X7E;//PWM7-PWM12输出使能,使能IOPE1-IOPE6第二功能WSGR=0x0000;//不使能所有的等待状态}//根据Uout的标幺值KP计算ualfa,ubeta子程序voidcalu(){inti;for(i=0;i200;i++){ualfa=KP*cos(INIA+i*DETA);ubeta=KP*sin(INIA+i*DETA);}}//各点的扇区确定子程序voidSECTOR(){inti,a,b,c;floatvref1,vref2,vref3;for(i=0;i200;i++){vref1=ubeta;vref2=(-ubeta+ualfa*1.732051)/2;vref3=(-ubeta-ualfa*1.732051)/2;//计算确定扇区数需要的3个参考量//vref1、vref2、vref3if(vref10)a=1;elsea=0;if(vref20)b=1;elseb=0;if(vref30)c=1;elsec=0;a=4*c+2*b+a;switch(a){case1:sector=1;break;case2:sector=5;break;case3:sector=0;break;case4:sector=3;break;case5:sector=2;break;case6:sector=4;break;default:break;}//根据相应的关系确定各个Uout所在的扇区}}//主程序main(){intanticlk[6]={0x1666,0x3666,0x2666,0x6666,0x4666,0x5666};//逆时针旋转的6个基本矢量inti,k=0,cmp1,cmp2;floatx,y,z;disable();//屏蔽所有中断initial();//系统初始化calu();//计算ualfa,ubeta的值SECTOR();//确定各点的扇区,在实际应用时应该由即时//的ualfa和ubeta即时算出while(1){for(i=0;i200;i++){*ACTRB=anticlk[sector];//重新装配ACTRAx=ubeta;y=(1.732051*ualfa+ubeta)/2;z=(-1.732051*ualfa+ubeta)/2;//以上3句计算3个相应的参考量switch(sector){case0:cmp1=(int)(-z*TP),cmp2=(int)(x*TP);break;case1:cmp1=(int)(y*TP),cmp2=(int)(z*TP);break;case2:cmp1=(int)(x*TP),cmp2=(int)(-y*TP);break;case3:cmp1=(int)(z*TP),cmp2=(int)(-x*TP);break;case4:cmp1=(int)(-y*TP),cmp2=(int)(-z*TP);break;case5:cmp1=(int)(-x*TP),cmp2=(int)(y*TP);break;default:break;}//以上根据uout所处的扇区计算相应的cmp1和cmp2的值*CMPR4=cmp1;//比较寄存器4赋值*CMPR5=cmp1+cmp2;//比较寄存器5赋值if((i+k)==0)*T3CON=*T3CON|0X040;//启动定时器,只启动一次while(1){k=*EVBIFRA&0X0200;if(k==0x0200)break;//如果T3的中断标志建立,则停止等待}}}}//如果由于干扰引起中断,则执行此直接返回程序voidinterruptnothing(){return;}以上是从刘和平光盘里拷贝的。使用TITMS2407实现SVPWM同步电机控制算法。源代码在闻廷科技的2407开发板上已经调试成功#includeregister.h#defineFs2//Fs为采样频率kHz(载波频率)#definePI180constintcsin[180]={0,//查表法计算正弦值174,348,523,697,871,1045,1218,1391,1564,1736,1908,2079,2249,2419,2588,2756,2923,3090,3255,3420,3583,3746,3907,4067,4226,4383,4539,4694,4848,5000,5150,5299,5446,5591,5735,5877,6018,6156,6293,6427,6560,6691,6819,6946,7071,7193,7313,7431,7547,7660,7771,7880,7986,8090,8191,8290,8386,8480,8571,8660,8746,8829,8910,8987,9063,9135,9205,9271,9335,9396,9455,9510,9563,9612,9659,9702,9743,9781,9816,9848,9876,9902,9925,9945,9961,9975,9986,9993,9998,10000,9998,9993,9986,9975,9961,9945,9925,9902,9876,9848,9816,9781,9743,9702,9659,9612,9563,9510,9455,9396,9335,9271,9205,9135,9063,8987,8910,8829,8746,8660,8571,8480,8386,8290,8191,8090,7986,7880,7771,7660,7547,7431,7313,7193,7071,6946,6819,6691,6560,6427,6293,6156,6018,5877,5735,5591,5446,5299,5150,5000,4848,4694,4539,4383,4226,4067,3907,3746,3583,3420,3255,3090,2923,2756,2588,2419,2249,2079,1908,1736,1564,1391,1218,1045,871,697,523,348,174,};//存储sin函数的91个单元,每个单元存递增一度的sin值,放大了100000倍;unsignedinti=0,j=0;unsignedlongintk=0,t=0,N=0,M=9;//M值的大小和Fc有关系,Ud不变,Uc随着Fc的改变而改变,所以M=Uc/Us值改变。unsignedlonginttm1=0,tm2=0,tm3=0;unsignedintADAcount=0,ischange=0,result=0,Fc=25;voidinitial(void);voidsysinit(void);voidintinit(void);voidevainit(void);voidADInit(void);voidinterruptgptime1(void);voidinterruptnothing(void);unsignedlongintgettime(unsignedlongint);main(){initial();//系统初始化sysinit();intinit();ADInit();evainit();N=1000*Fs/Fc;while(1){if(ADAcount=200)//如果ADAcount=200,以下开始转换和保存转换结果{ADAcount=0;//清保存标志result=(*RESULT0);//取ADCINT0通道转换结果result=6;//取有效位if(result!=0){Fc=result*50/1024;//将采进的电压值Uc转换为频率Fcif(Fc=2)Fc=2;M=10*Fc/50;if(M=1)M=1;if(M=10)M=10;ischange=1;}*ADCTRL2=0x2000;}}}voidinitial(void){asm(setcINTM);//禁止中断asm(clrcSXM);//清标志位asm(clrcOVM);//OVM清零,累加器中结果正常溢出asm(clrcCNF);//CNF清零,B0被设置为数据存储区}voidsysinit(void){*WDCR=0x68;//看门狗定时控制寄存器*SCSR1=0x81fe;//系统控制及状态寄存器1,CPU时钟频率设置,设为40MHZ*XINT1CR=*XINT2CR=0x8006;//禁止外部中断//*WSGR=0x0000;//设置外部存储器的接口}voidintinit(void){*IFR=0x003f;//清所有系统中断标志*IMR=0x0002;//开INT2中断*EVAIFRA=0xffff;//清事件管理器A所有中断标志*EVAIFRB=0xffff;//清事件管理器A所有中断标志*EVAIFRC=0xffff;//清事件管理器A所有中断标志*EVAIMRA=0x0200;//T1下溢中断使能T1PINT*EVAIMRB=0;//屏蔽所有中断*EVAIMRC=0;//屏蔽所有中断}voidevainit(void){*MCRA=*MCRA|0X0fc0;//设置PWM1~6引脚*ACTRA=0X0999;/