DSP电机控制PMSM.docx
《DSP电机控制PMSM.docx》由会员分享,可在线阅读,更多相关《DSP电机控制PMSM.docx(22页珍藏版)》请在冰豆网上搜索。
DSP电机控制PMSM
#include"DSP28_Device.h"
EVAeva=EVA_DEFAULTS;
EVBevb=EVB_DEFAULTS;
RAMPGENrampgen=RAMPGEN_DEFAULTS;
VHZPROFvhzprof=VHZPROF_DEFAULTS;
SVGENDQsvgendq=SVGENDQ_DEFAULTS;
ROTATEVECTORrotatevector=ROTATEVECTOR_DEFAULTS;
staticunsignedintRBBuf;
staticunsignedintRABuf;
interruptvoidISRTimer1(void);
interruptvoidISRTimer2(void);
interruptvoidT1UFINT_ISR(void);
longf_given=0;
longf_now=0;
floathappy=0;
//显示相关
unsignedintf_given_disp=0;//接到的的值
unsignedintku=10;//输入电压与电机额定电压的比
unsignedintDispBuf[2];//显示缓存,存在EEPROM,(ku,f_given)
unsignedintRunFlag=0;//运行标志
unsignedintTurnFlag=0;//正反转
//_iqha=65545;
//_iqhb=65521;
//_iqhc;
voidShowDisp(void);//显示函数,用于将数据显示到显示板
_iqtest1[20];
_iqtest2[20];
voidmain(void)
{
/*初始化系统*/
InitSysCtrl();
/*关中断*/
DINT;
IER=0x0000;
IFR=0x0000;
/*初始化PIE控制寄存器*/
InitPieCtrl();
/*初始化PIE矢量表*/
InitPieVectTable();
/*初始化SCIb寄存器*/
InitSci();
//初始化24Vxx
//Init24Cxx();
/*设置CPU定时器*/
InitCpuTimers();
ConfigCpuTimer(&CpuTimer2,150,20000);
ConfigCpuTimer(&CpuTimer1,150,100000);//每0.1秒加1Hz,每秒加Y*1000000赫兹
StartCpuTimer1();
StartCpuTimer2();
/*初始化IO口*/
//InitGpio();
/*初始化EV*/
eva.Init(&eva);
evb.Init(&evb);
/*设置中断服务程序入口地址*/
EALLOW;//ThisisneededtowritetoEALLOWprotectedregisters
PieVectTable.T1UFINT=&T1UFINT_ISR;
PieVectTable.TXBINT=&SCITXINTB_ISR;//设置串口B发送中断的中断向量
PieVectTable.RXBINT=&SCIRXINTB_ISR;//设置串口B接受中断的中断向量
PieVectTable.TXAINT=&SCITXINTA_ISR;//设置串口A发送中断的中断向量
PieVectTable.RXAINT=&SCIRXINTA_ISR;//设置串口A接受中断的中断向量
PieVectTable.TINT2=&ISRTimer2;
PieVectTable.XINT13=&ISRTimer1;//定时器1和外部中断合用一个中断标志位
//此处为XINT13并不是TINT1
EDIS;//ThisisneededtodisablewritetoEALLOWprotectedregisters
/*使能位于PIE中组2的第6个中断定时器1下溢中断*/
PieCtrl.PIEIER2.bit.INTx6=1;
/*开中断*/
IER|=M_INT2;//EVA
IER|=M_INT9;//SCI//允许串口中断
IER|=M_INT14;//cputimer2
IER|=M_INT13;//cputimer1
EINT;//EnableGlobalinterruptINTM
ERTM;//EnableGlobalrealtimeinterruptDBGM
eva.Close(&eva);
evb.Open(&evb);
rampgen.StepAngleMax=_IQ(0.0128);//最大频率128hz中断频率10k
while
(1)
{
//hc=_IQmpy(ha,hb);只进行保留整数位,对于小数位不进行四舍五入。
hc=(ha*hb)/65536
}
}
//===========================================================================
//定时器1下溢中断服务程序.
//===========================================================================
interruptvoidT1UFINT_ISR(void)//EV-A
{
//asm("ESTOP0");
//PieCtrl.PIEACK.bit.ACK2=1;
//EvaRegs.EVAIFRA.bit.T1UFINT=1;//清中断标志位
//rampgen模块产生矢量旋转的角度需要设置StepAngleMax这里是控制转速的。
//rampgen.Freq=_IQ(50)>>7;
rampgen.Freq=_IQ((float)f_now)>>7;//因为最大频率128Hz,是2的7次方,那么除以128就是以最大频率来看的标幺值
rampgen.calc(&rampgen);
//vhzprof模块vvvf控制,根据频率比例控制输出电压的量
//vhzprof.Freq=_IQ(50);
vhzprof.Freq=_IQ((float)f_now)+_IQ(0.11);
vhzprof.calc(&vhzprof);
//RotateVector模块产生旋转矢量对应的UalphaUbeta
if(TurnFlag==0)
{
rotatevector.Angle=rampgen.Angle;//停止标志
}
else
{
rotatevector.Angle=-rampgen.Angle;
}
rotatevector.k=vhzprof.VoltOut;
rotatevector.calc(&rotatevector);
//svgendq模块根据UalphaUbeta产生比较器需要的TATBTC
svgendq.Ualpha=rotatevector.Ualpha;
svgendq.Ubeta=rotatevector.Ubeta;
svgendq.calc(&svgendq);
happy=rotatevector.Angle;
//ev模块
eva.Ta=svgendq.Ta;
eva.Tb=svgendq.Tb;
eva.Tc=svgendq.Tc;
eva.SetPwm(&eva);
evb.Ta=svgendq.Ta;
evb.Tb=svgendq.Tb;
evb.Tc=svgendq.Tc;
evb.SetPwm(&evb);
PieCtrl.PIEACK.bit.ACK2=1;
EvaRegs.EVAIFRA.bit.T1UFINT=1;//清中断标志位
}
interruptvoidSCIRXINTA_ISR(void)
{
PieCtrl.PIEACK.bit.ACK9=1;
RABuf=SciaRegs.SCIRXBUF.all;
switch(RABuf)
{}
EINT;
}
interruptvoidSCIRXINTB_ISR(void)//SCI-B
{
PieCtrl.PIEACK.bit.ACK9=1;//相应PIE组9的其他中断
RBBuf=ScibRegs.SCIRXBUF.all;
switch(RBBuf)
{
case0:
//增加输入电压百分比
break;
case1:
//运行
break;
case2:
//增加频率
break;
case3:
//增加频率
break;
case4:
//减少输入电压百分比
break;
case5:
//停止
f_given=0;
break;
case6:
//减小频率
break;
case7:
//减小频率
break;
}
EINT;
}
interruptvoidISRTimer1(void)
{
//内部定义的计数变量
if(RABuf==0)
{
CpuTimer1.InterruptCount=0;
f_given=0;
SciaRegs.SCITXBUF=(unsignedint)f_now;
f_given_disp=f_now;
}
if(RABuf==1)//FWDAuto
{
//unsignedinta;
RunFlag=1;
eva.Open(&eva);
f_given_disp=f_now;
TurnFlag=0;
CpuTimer1.InterruptCount++;
if((CpuTimer1.InterruptCount<20)&&(CpuTimer1.InterruptCount>0))
{
f_given++;
f_now=f_given;
//f_given=f_now;
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
if((CpuTimer1.InterruptCount>=20)&&(CpuTimer1.InterruptCount<30))
{
f_given=f_now;
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
if((CpuTimer1.InterruptCount>=30)&&(CpuTimer1.InterruptCount<50))
{
f_given--;
f_now=f_given;
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
if(CpuTimer1.InterruptCount>=50)
{f_given=0;
f_now=0;
SciaRegs.SCITXBUF=(unsignedint)f_now;
eva.Close(&eva);
//RABuf=0;
}
}
if(RABuf==2)//REVAuto
{
RunFlag=1;
eva.Open(&eva);
f_given_disp=f_now;
TurnFlag=1;
CpuTimer1.InterruptCount++;
if((CpuTimer1.InterruptCount<20)&&(CpuTimer1.InterruptCount>0))
{
f_given++;
f_now=f_given;
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
if((CpuTimer1.InterruptCount>=20)&&(CpuTimer1.InterruptCount<40))
{
f_given=f_now;
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
if(CpuTimer1.InterruptCount>=40)
{
f_given=0;
f_now=0;
SciaRegs.SCITXBUF=(unsignedint)f_now;
eva.Close(&eva);
//RABuf=0;
}
}
if(RABuf==3)//FWDHigh
{
CpuTimer1.InterruptCount=0;
TurnFlag=0;
RunFlag=1;
eva.Open(&eva);
f_now=10;
f_given=10;
f_given_disp=f_now;
//CpuTimer1.InterruptCount++;
//if(CpuTimer1.InterruptCount>=10)
//{
//RABuf=0;
//CpuTimer1.InterruptCount=0;
//}
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
if(RABuf==4)//REVHigh
{
CpuTimer1.InterruptCount=0;
TurnFlag=1;
RunFlag=1;
eva.Open(&eva);
f_now=10;
f_given=10;
f_given_disp=f_now;
//if(CpuTimer1.InterruptCount>=10)
//{
//RABuf=0;
//CpuTimer1.InterruptCount=0;
//}
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
if(RABuf==5)//FWDLow
{
CpuTimer1.InterruptCount=0;
TurnFlag=0;
RunFlag=1;
eva.Open(&eva);
f_now=5;
f_given=5;
f_given_disp=f_now;
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
if(RABuf==6)//REVLow
{
CpuTimer1.InterruptCount=0;
TurnFlag=1;
RunFlag=1;
eva.Open(&eva);
f_now=5;
f_given=5;
f_given_disp=f_now;
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
if(RABuf==7)//AllPause
{
//CpuTimer1Regs.TCR.bit.TRB=1;/*暂停*/
//f_now=50;
eva.Close(&eva);
SciaRegs.SCITXBUF=(unsignedint)f_now;
}
CpuTimer1Regs.TCR.bit.TIF=1;
ShowDisp();
PieCtrl.PIEACK.all=PIEACK_GROUP1;
//SciaRegs.SCITXBUF=(unsignedint)f_now;
EINT;
}
interruptvoidISRTimer2(void)
{
CpuTimer2.InterruptCount++;
if(CpuTimer2.InterruptCount>1)//20ms
{
if(f_given>f_now)
{
if(f_now<1)
f_now=1;
else
f_now++;
}
elseif(f_given{
if(f_now<1)
{
eva.Close(&eva);
f_now=0;
f_given=0;
RunFlag=0;//停止标志
}
else
f_now--;
}
SciaRegs.SCITXBUF=(unsignedint)f_now;
CpuTimer2.InterruptCount=0;
}
ShowDisp();
EINT;
}
voidShowDisp(void)//更新显示
{
staticunsignedinti=0;
switch(i)
{
case0:
i++;
ScibRegs.SCITXBUF=(ku&0xf)+(3<<5);
break;
case1:
if(RunFlag)ScibRegs.SCITXBUF=23+(2<<5);
elseScibRegs.SCITXBUF=24+(2<<5);
i++;
break;
case2:
if(RunFlag)ScibRegs.SCITXBUF=f_now/10+(1<<5);
elseScibRegs.SCITXBUF=f_given_disp/10+(1<<5);
i++;
break;
case3:
if(RunFlag)ScibRegs.SCITXBUF=f_now%10;
elseScibRegs.SCITXBUF=f_given_disp%10;
i=0;
break;
default:
i=0;
break;
}
}
//===========================================================================
//Nomore.
//===========================================================================
//Don'tforgettosetaproperGLOBAL_Qin"IQmathLib.h"file
#include"vhzprof.h"
#include
voidvhz_prof_calc(VHZPROF*v)
{
_iqVfSlope,AbsFreq;
//Takeabsolutefrequencytoallowtheoperationofbothrotationaldirections
AbsFreq=labs(v->Freq);
if(AbsFreq<=v->LowFreq)
//Computeoutputvoltageinprofile#1
v->VoltOut=v->VoltMin;
elseif((AbsFreq>v->LowFreq)&&(AbsFreq<=v->HighFreq))
{
//ComputeslopeofV/fprofile
VfSlope=_IQdiv((v->VoltMax-v->VoltMin),(v->HighFreq-v->LowFreq));//就是压频比的斜率
//Computeoutputvoltageinprofile#2
v->VoltOut=v->VoltMin+_IQmpy(VfSlope,(AbsFreq-v->LowFreq));
}
elseif((AbsFreq>v->HighFreq)&&(AbsFreqFreqMax))
//Computeoutputvoltageinprofile#3
v->VoltOut=v->VoltMax;//最大的VoltMax线电压就是直流侧的电压DC直流,可以看思路图,任意时刻是上下桥臂导通。
}
#include"RotateVector.h"
#include"iqmathlib.h"
voidRotateVecotr_calc(RotateVecotr_Handlev)
{
_iqUa,Ub;
//Usinglook-upIQsinetable
Ub=_IQsinPU(v->Angle);//正弦函数标幺值,你站着个圆周的几分之几
Ua=_IQcosPU(v->Angle);
v->Ualpha=_IQmpy(v->k,Ua);
v->Ubeta=_IQmpy(v->k,Ub);
#include"IQmathLib.h"//IncludeheaderforIQmathlibrary
//Don'tforgettosetaproperGLOBAL_Qin"IQmathLib.h"file
#include"rampgen.h"
voidrampgen_calc(RAMPGEN*v)
{
//Computetheanglerate
v->Angle+=_IQmpy(v->StepAngleMax,v->Freq);
//这里“v->Freq”是以最大频率(128Hz)来看的给定频率标幺值,乘最大频率再乘中
//断周期就是每一个中短周期增加给定频率那么多的角度(只是线性对应关系,给定越
//大增加越快,给定越小增加就小)
//Saturatetheangleratewithin(-1,1)
if(v->Angle>_IQ(1.0))
v->Ang