DSP电机控制PMSM.docx
- 文档编号:26434305
- 上传时间:2023-06-19
- 格式:DOCX
- 页数:26
- 大小:20.19KB
DSP电机控制PMSM.docx
《DSP电机控制PMSM.docx》由会员分享,可在线阅读,更多相关《DSP电机控制PMSM.docx(26页珍藏版)》请在冰豆网上搜索。
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)&&(AbsFreq //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->Angl
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DSP 电机 控制 PMSM