电机控制DSP编程

合集下载

DSP无刷直流电动机驱动控制程序

DSP无刷直流电动机驱动控制程序

DSP无刷直流电动机驱动控制程序————————————————————————————————作者:————————————————————————————————日期:2.4 无刷直流电动机驱动控制程序//########################################################################## ###/////无刷电机控制源程序//TMS320F2812////########################################################################## ###//=====================================================================//头文件调用//=====================================================================#include "DSP28_Device.h"#include "math.h"#include "float.h"//=====================================================================//常量附值//=====================================================================#define Idc_max 3000 //电流给定最大值#define Idc_min 0 //电流给定最小值//=====================================================================//标志位//=====================================================================char Iab_Data=0;struct Flag_Bits { // bits descriptionUint16 Send:1; // 0 串口发数Uint16 Test:1; // 1 串口测试Uint16 Vflag:1; // 2 转速更新Uint16 SendEnd:1; // 3 串口发送结束Uint16 Sign1:1; // 4 上一次给定转向标志Uint16 Sign2:1; // 5 本次给定转向标志Uint16 Openint:1; // 6 启动标志Uint16 Adfrist:1; // 7 保留Uint16 Spdoff:1; // 8 保留Uint16 Zero:1; // 9 转速过零标志Uint16 Mode:3; // 10-12 保留Uint16 Dshow:1; // 13 保留Uint16 Sign:1; // 14 当前转向标志};union Flag_Reg {Uint16 all;struct Flag_Bits bit;}FlagRegs;//===================================================================== //全局变量//===================================================================== //串口通信变量unsigned int Sci_Rx[8]={0,0,0,0,0,0,0,0}; //接收数据数组unsigned int Sci_Tx[8]={0,0,0,0,0,0,0,0}; //发送数据数组char T_pointer=0; //发送数据数组指针char R_pointer=0; //接收数据数组指针char T_length=1; //发送数据长度char R_length=0; //接收数据长度char a2=0;//控制参数unsigned int spd_kp=0; //转速环P参数unsigned int spd_ki=0; //转速环I参数unsigned int id_kp=0,id_ki=0; //电流PI参数signed int spd_given=0; //转速给定signed int spd_given1=0; //转速给定signed int spd_given2=0; //转速给定//控制变量unsigned int cap1=0; //前次换向标志位unsigned int cap2=0; //本次换向标志位unsigned int intruptcount=0; //定时器1下溢中断次数unsigned int speed_given = 1000; //转速给定signed int Idc_given2=0; //算得本次电流给定值signed int speed_e1=0; //前次转速误差signed int speed_e2=0; //本次转速误差signed int Ia_e1=0; //前次电流误差signed int Ia_e2=0; //本次电流误差char t2first=0;signed int COMP2=0; //装比较寄存器值//转速反馈char Spd_Data=0; //滤波计数int speed_counter=0; //速度环计数器unsigned int cap_a; //本次捕获单元数据unsigned int cap_b; //上次捕获单元数据long cap_c; //捕获单元数据差signed int BLDC_SPD[10]={0,0,0,0,0,0,0,0,0,0};//转速滤波signed int spd_fd_q1=0; //转速反馈临时变量unsigned int spd_fd_q0=0; //转速检测值char cc=0;//电流反馈unsigned int ia[6]={0,0,0,0,0,0}; //A相电流反馈值unsigned int ib[6]={0,0,0,0,0,0}; //B相电流反馈值signed int ia_fd=0,ib_fd=0; //电流反馈signed int Temp_filter=0; //临时变量unsigned int t1per=0; //周期寄存器数值//临时变量signed long long1_tmp=0;signed long long2_tmp=0;signed int u16_tmp1=0;signed int u16_tmp2=0;//===================================================================== //子程序声明//===================================================================== interrupt void t1uf_int(void);interrupt void cap_int(void);void Ad(void);void speed(void); //计算速度void Ia_PI(void); //电流环调节Iavoid speed_PI(void); //速度环调节void bldc(void);void Check_Rxdata(void);void Sci_Send(signed int sci_delay);char *Fen_Jie(signed int Send_Temp);unsigned int Sci_Rx_check(unsigned int i_Rx,unsigned int *p_Rx);signed int DIV_CAL(long signed int dividend,signed int divisor);unsigned int U_DIV_CAL(long unsigned int udividend,unsigned int udivisor);//=====================================================================//主程序开始//===================================================================== void main(void){//控制寄存器初始设置InitSysCtrl(); //初始化系统DINT; //关全局中断IER = 0x0000;IFR = 0x0000;InitPieCtrl(); //初始化PIE中断InitPieVectTable(); //初始化PIE中断矢量表InitGpio(); //初始化Gpio输入输出口InitEv(); //初始化Eva的T和T2InitAdc_Eva(); //初始化ADInitData();EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.T1UFINT=&t1uf_int;//T1下溢中断地址PieVectTable.CAPINT4=&cap_int;PieVectTable.CAPINT5=&cap_int;PieVectTable.CAPINT6=&cap_int;EDIS; // This is needed to disable write to EALLOW protected registersPieCtrl.PIEIER2.bit.INTx6 = 1; //T1下溢中断使能PieCtrl.PIEIER5.bit.INTx5 = 1;PieCtrl.PIEIER5.bit.INTx6 = 1;PieCtrl.PIEIER5.bit.INTx7 = 1;IER |= M_INT2; // Enable CPU Interrupt 2IER |= M_INT4; // Enable CPU Interrupt 4IER |= M_INT5; // Enable CPU Interrupt 5EvbRegs.EVBIMRC.bit.CAP4INT=1;EvbRegs.EVBIMRC.bit.CAP5INT=1;EvbRegs.EVBIMRC.bit.CAP6INT=1;EvbRegs.CAPCONB.all=0x36FF;NOP;NOP;NOP;NOP;EvbRegs.CAPCONB.all=0xB6FF;EINT; //使能全局中断INTMERTM; // Enable Global realtime interrupt DBG//等待中断(中断之外的时间内进行LCD的发送和接收)for(;;){SCI_CTL();}}//===================================================================== //串口控制//===================================================================== //*************//接收数据检测//************void Check_Rxdata(){switch(Sci_Rx[0]){case 'm': //转速给定和转速在线更新 case 'v':{FlagRegs.bit.Vflag=1;if(Sci_Rx[1]=='-'){FlagRegs.bit.Sign1=0; //转速为负值spd_given1 = Sci_Rx_check(4,Sci_Rx);}else{FlagRegs.bit.Sign1=1; //转速为正值spd_given1 = Sci_Rx_check(3,Sci_Rx);}if(Sci_Rx[0]=='m'){FlagRegs.bit.Sign2=FlagRegs.bit.Sign1;FlagRegs.bit.Sign=FlagRegs.bit.Sign1;}break;}case 's': //启动{Sci_Tx[0]='a';Sci_Tx[1]='+';Sci_Tx[2]='0';Sci_Tx[3]='0';Sci_Tx[4]='0';Sci_Tx[5]='0';Sci_Tx[6]='0';Sci_Tx[7]='z';spd_given=spd_given1;Protect_Data();Motor_Start();FlagRegs.bit.Send=1;T_length=8;T_pointer=0;break;}case 't': //停止 {Motor_Stop();break;}default: break;}}//*******************// 串口接收/发送判断//******************SCI_CTL(){if((SciaTx_Ready() == 1) && (FlagRegs.bit.Send == 1))//发送数据准备好并且软件使能发送{if(FlagRegs.bit.Test==0) //SCI测通状态{SciaRegs.SCITXBUF = Sci_Rx[T_pointer];T_pointer++; //发送缓冲器数组指针+1if(T_pointer==R_length){FlagRegs.bit.Test=1;FlagRegs.bit.Send=0;T_pointer=0;}}else //SCI非测通状态{SciaRegs.SCITXBUF = Sci_Tx[T_pointer];T_pointer++; //发送缓冲器数组指针+1if(T_pointer==T_length){FlagRegs.bit.Send = 0;T_pointer=0;}if(T_pointer>=10){T_pointer=0;FlagRegs.bit.Send= 0;}}R_pointer=0;}#if !SCIA_INTif(SciaRx_Ready() == 1) //接收数据准备好{FlagRegs.bit.SendEnd=0;FlagRegs.bit.Send= 0;Sci_Rx[R_pointer] = SciaRegs.SCIRXBUF.all;R_pointer++;if(Sci_Rx[R_pointer-1]=='z'){R_length=R_pointer-1;FlagRegs.bit.Send= 1;FlagRegs.bit.SendEnd=1;if(FlagRegs.bit.Test==1){Check_Rxdata();R_pointer = 0;}}if(R_pointer== 10){R_pointer = 0;}}#endif}//****************//接收数据格式调整//****************unsigned int Sci_Rx_check(unsigned int i_Rx,unsigned int *p_Rx){unsigned long data_Rx;unsigned int *p_tmp_Rx=p_Rx+i_Rx;data_Rx=1000*(*p_tmp_Rx)+100*(*(p_tmp_Rx+1))+10*(*(p_tmp_Rx+2))+(*(p_tmp_Rx+ 3))-53328;return(data_Rx);}//****************//发送数据格式调整//****************char *Fen_Jie(signed int Send_Temp) {unsigned int Temp;char s1,s2,s3,s4;char String_Tmp[6]={0,0,0,0,0,'\0'}; if(Send_Temp< 0){String_Tmp[0]='-';Send_Temp=-Send_Temp;}else{String_Tmp[0]='+';}s1=((long)Send_Temp*2097)>>21;if(s1>=10) {s1=9;}Temp=Send_Temp-s1*1000;s2=((long)Temp*5253)>>19;if(s2>=10) {s2=9;}Temp=Temp-s2*100;s3=((long)Temp*3277)>>15;if(s3>=10) {s3=9;}s4=Temp-s3*10;if(s4>=10) {s4=9;}String_Tmp[1]=s1+48; //千位String_Tmp[2]=s2+48; //百位String_Tmp[3]=s3+48; //十位String_Tmp[4]=s4+48; //个位return(String_Tmp);}//**************// 数据发送//**************void Sci_Send(signed int sci_delay){//串口数据发送char *p_send=0;a2++;if((a2>=sci_delay)&&(FlagRegs.bit.Send==0)&&(FlagRegs.bit.SendEnd==1)) {p_send=Fen_Jie(spd_fd_q0);Sci_Tx[0]='a';Sci_Tx[1]=*p_send;Sci_Tx[2]='0';Sci_Tx[3]=*(p_send+1);Sci_Tx[4]=*(p_send+2);Sci_Tx[5]=*(p_send+3);Sci_Tx[6]=*(p_send+4);Sci_Tx[7]='z';FlagRegs.bit.Send=1;a2=0;}}//===================================================================== //电机状态控制//===================================================================== //*******************// 数据处理//******************Protect_Data(){if(spd_kp<=0)spd_kp=1; //转速环P参数else if(spd_kp>30000) spd_kp=30000;if(spd_ki<=0)spd_ki=1; //转速环P参数else if(spd_ki>30000) spd_ki=30000;if(id_kp<=0)id_kp=1; //转速环P参数else if(id_kp>30000) id_kp=30000;if(id_ki<=0)id_ki=1; //转速环P参数else if(id_ki>30000) id_ki=30000;EvaRegs.T1PR =7500; //矢量控制开关频率5K固定t1per=7500;EvaRegs.T1CON.all = 0X080C; //连续增减计数InitAdc_Eva();} //************//电机停止//************ Motor_Stop(){EvaRegs.CMPR1=0;EvaRegs.CMPR2=0;EvaRegs.CMPR3=0;EvaRegs.ACTR.all=0X0FFF;InitData();FlagRegs.bit.Openint=0;EvaRegs.T1CON.bit.TENABLE=0;EvbRegs.T3CON.bit.TENABLE=0;}//************//电机启动//************Motor_Start(){EvaRegs.ACTR.all=0X0999;FlagRegs.bit.Openint=1;t1per=7500;EvaRegs.T1PR =7500; //周期寄存器 5khzEvaRegs.T1CON.all = 0X080C; //连续增减计数EvbRegs.T3PR =0xffff; // 周期寄存器EvbRegs.T3CON.all = 0X170C; // 连续增减计数EvbRegs.EVBIMRA.all=0X0000; // T3下溢使能EvbRegs.EVBIFRA.all=0X0FFFF; // 清中断标志位GpioMuxRegs.GPBMUX.bit.CAP4Q1_GPIOB8=0; //将cap456设置为io口 GpioMuxRegs.GPBMUX.bit.CAP5Q2_GPIOB9=0;GpioMuxRegs.GPBMUX.bit.CAP6QI2_GPIOB10=0;cap2 = GpioDataRegs.GPBDAT.all & 0x0700; //记录cap4-6初始状态cap2 = cap2>>8;cap2 = cap2&0x0007;if(FlagRegs.bit.Sign==1) cap2=7-cap2;else cap2=cap2;GpioMuxRegs.GPBMUX.bit.CAP4Q1_GPIOB8=1; //将cap456设置为CAP口 GpioMuxRegs.GPBMUX.bit.CAP5Q2_GPIOB9=1;GpioMuxRegs.GPBMUX.bit.CAP6QI2_GPIOB10=1;EvaRegs.T1CON.bit.TENABLE=1;FlagRegs.bit.Vflag=1;}//===================================================================== //直流无刷电动机驱动双闭环主程序//===================================================================== //*****************//驱动主程序//*****************void bldc(){intruptcount++;speed();switch((int)cap2){case 4:{Ad(); //检测电流if(ia_fd<0) ia_fd=0; //保护speed_PI(); //转速PI调节Ia_PI(); //电流PI调节EvaRegs.ACTR.all = 0x0F3E; //ia+,ib-EvaRegs.CMPR1=COMP2;break;}case 5:{Ad(); //检测电流if(ia_fd<0) ia_fd=0; //保护speed_PI(); //转速PI调节Ia_PI(); //电流PI调节EvaRegs.ACTR.all = 0x03FE; //ia+,ic- EvaRegs.CMPR1=COMP2;break;}case 1:{Ad();if(ib_fd<0) ib_fd=0;ia_fd=ib_fd;speed_PI();Ia_PI();EvaRegs.ACTR.all = 0x03EF; //ib+,ic- EvaRegs.CMPR2=COMP2;break;}case 3:{Ad();if(ib_fd<0) ib_fd=0;speed_PI();Ia_PI();EvaRegs.ACTR.all = 0x0FE3; //ib+,ia- EvaRegs.CMPR2=COMP2;break;}case 2:{Ad();ia_fd=-ia_fd;if(ia_fd<0) ia_fd=0;speed_PI();Ia_PI();EvaRegs.ACTR.all = 0x0EF3; //ic+,ia- EvaRegs.CMPR3=COMP2;break;}case 6:{Ad();ib_fd=-ib_fd;if(ib_fd<0) ib_fd=0;speed_PI();Ia_PI();EvaRegs.ACTR.all = 0x0E3F; //ic+,ib-EvaRegs.CMPR3=COMP2;break;}default: break;}}//********************************//电流反馈//********************************void Ad(){char delay_zy=0;ia_fd=0,ib_fd=0; //AB相电流检测值清零 for(Iab_Data=0;Iab_Data<=5;Iab_Data++){ia[Iab_Data]=AdcRegs.RESULT0>>4;ib[Iab_Data]=AdcRegs.RESULT1>>4;if(Iab_Data==0){for(delay_zy=0;delay_zy<=10;delay_zy++) {;}}else if(Iab_Data==1){if(ia[0]>ia[1]){Temp_filter= ia[1];ia[1] = ia[0];ia[0] = Temp_filter;}if(ib[0]>ib[1]){Temp_filter= ib[1];ib[1] = ib[0];ib[0] = Temp_filter;}}else{if(ia[Iab_Data]>ia[1]){Temp_filter= ia[1];ia[1] = ia[Iab_Data];ia[Iab_Data] = Temp_filter;}else if(ia[Iab_Data]<ia[0]){Temp_filter= ia[0];ia[0] = ia[Iab_Data];ia[Iab_Data] = Temp_filter;}if(ib[Iab_Data]<ib[0]){Temp_filter= ib[0];ib[0] = ib[Iab_Data];ib[Iab_Data] = Temp_filter;}else if(ib[Iab_Data]>ib[1]){Temp_filter= ib[1];ib[1] = ib[Iab_Data];ib[Iab_Data] = Temp_filter;}}}ia_fd=(ia[2]+ia[3]+ia[4]+ia[5])>>2; ib_fd=(ib[2]+ib[3]+ib[4]+ib[5])>>2; ia_fd=ia_fd-2133;ib_fd=ib_fd-2150;}//********************************//转速反馈计算//********************************void speed(void){if((cap2 != cap1)&&(t2first==1)){if(cap_c!= 0){long2_tmp = 1953125/cap_c;spd_fd_q1 = long2_tmp;intruptcount=0;switch(cap2){case 5:{if(cap1==4) spd_fd_q1=-spd_fd_q1; break;}case 4:{if(cap1==6) spd_fd_q1=-spd_fd_q1; break;case 6:{if(cap1==2) spd_fd_q1=-spd_fd_q1; break;}case 2:{if(cap1==3) spd_fd_q1=-spd_fd_q1; break;}case 3:{if(cap1==1) spd_fd_q1=-spd_fd_q1; break;}case 1:{if(cap1==5) spd_fd_q1=-spd_fd_q1; break;}default:break;}BLDC_SPD[Spd_Data]=spd_fd_q1;if(Spd_Data==1)if(BLDC_SPD[0]>BLDC_SPD[1]){Temp_filter = BLDC_SPD[1];BLDC_SPD[1] = BLDC_SPD[0];BLDC_SPD[0] = Temp_filter;}}else{if(BLDC_SPD[Spd_Data]>BLDC_SPD[1]){Temp_filter= BLDC_SPD[1];BLDC_SPD[1] = BLDC_SPD[Spd_Data];BLDC_SPD[Spd_Data] = Temp_filter;}else if(BLDC_SPD[Spd_Data]<BLDC_SPD[0]) {Temp_filter= BLDC_SPD[0];BLDC_SPD[0] = BLDC_SPD[Spd_Data];BLDC_SPD[Spd_Data] = Temp_filter;}}Spd_Data++;if(Spd_Data>=10){Spd_Data=0;}cc++;if(cc>=3){cc=0;spd_fd_q0=(BLDC_SPD[2]+BLDC_SPD[3]+BLDC_SPD[4]+BLDC_SPD[5]+BLDC_SPD[6]+BLDC_ SPD[7]+BLDC_SPD[8]+BLDC_SPD[9])>>3;}cap1=cap2;}else{spd_fd_q0 = 0;}}else{if(intruptcount>=1500){intruptcount=0;spd_fd_q0=0;}else{spd_fd_q0=spd_fd_q0;}}if(t2first==0) t2first=1;}//********************************//转速调节器//********************************void speed_PI(void){unsigned int abs_spd=0;signed int spd_ki_bldc=1;speed_counter++;if(speed_counter>=10){speed_counter=0;if(FlagRegs.bit.Vflag==1) //转速给定更新{if(FlagRegs.bit.Sign1!=FlagRegs.bit.Sign2)//新转向和原有转向不同 {FlagRegs.bit.Zero =1; //换转向标志位置位spd_given2=spd_given; //缓存目标频率spd_given=0; //当前目标频率给定0}FlagRegs.bit.Vflag =0; //转速给定更新标志位清零FlagRegs.bit.Sign2=FlagRegs.bit.Sign1; //更新转向标志}if((spd_fd_q0==0)&&(FlagRegs.bit.Zero==1)) //当前给定频率,目标频率需要反向(电机需要从正转到反转){spd_given=spd_given2; //给定新的目标频率FlagRegs.bit.Zero=0; //换转向标志位清零FlagRegs.bit.Sign=FlagRegs.bit.Sign1; //给定新的转向}speed_e1 = speed_e2; //将本次误差用作下次使用speed_e2 = spd_given - abs(spd_fd_q0);abs_spd=abs(spd_given)>>2;if((abs(speed_e2))<abs_spd){spd_ki_bldc=spd_ki;}else{if(spd_given<100) spd_ki_bldc=12;//10*8else if(spd_given<150) spd_ki_bldc=10;else if(spd_given<200) spd_ki_bldc=8;else if(spd_given<250) spd_ki_bldc=6;else if(spd_given<300) spd_ki_bldc=5;else spd_ki_bldc=4;}long1_tmp= (long)spd_kp * (speed_e2 - speed_e1); long2_tmp= (long)spd_ki_bldc * speed_e2;u16_tmp1=(long1_tmp+long2_tmp)>>10;Idc_given2=Idc_given2+u16_tmp1;if(Idc_given2 > Idc_max) //限幅Idc_given2 = Idc_max;else if(Idc_given2 < Idc_min)Idc_given2 = Idc_min;}}//********************************//电流调节器//********************************void Ia_PI(void){Ia_e1 = Ia_e2; //将本次误差用作下次使用Ia_e2 = Idc_given2 - ia_fd;long1_tmp=(long)id_kp * (Ia_e2 - Ia_e1);long2_tmp=(long)id_ki * Ia_e2;u16_tmp1=(long1_tmp+long2_tmp)>>12;COMP2=COMP2+u16_tmp1;if(COMP2 < 0)COMP2 = 0;else if(COMP2 > (t1per-200))COMP2 = (t1per-200);}//===================================================================== //T1下溢中断子程序//===================================================================== interrupt void t1uf_int(void){IFR=0x0000; //中断标志位清零PieCtrl.PIEACK.all=0xffff;if(FlagRegs.bit.Openint==1) //控制程序准备开始运行{bldc();GpioDataRegs.GPACLEAR.bit.GPIOA11=1;Sci_Send(400);}EvaRegs.EVAIFRA.bit.T1UFINT=1; //T1下溢中断标志位清零EINT;}//=====================================================================// CAP4/5/6中断子程序//===================================================================== interrupt void cap_int(void){IFR=0x0000;PieCtrl.PIEACK.all=0xffff;GpioMuxRegs.GPBMUX.bit.CAP4Q1_GPIOB8=0; //将cap456设置为io口GpioMuxRegs.GPBMUX.bit.CAP5Q2_GPIOB9=0;GpioMuxRegs.GPBMUX.bit.CAP6QI2_GPIOB10=0;cap2 = GpioDataRegs.GPBDAT.all & 0x0700; //记录cap4-6初始状态cap2 = cap2>>8;cap2 = cap2&0x0007;if(FlagRegs.bit.Sign==1) cap2=7-cap2;else cap2=cap2;if(EvbRegs.EVBIFRC.bit.CAP4INT==1){cap_a=EvbRegs.CAP4FIFO;EvbRegs.EVBIFRC.bit.CAP4INT=1;}else if(EvbRegs.EVBIFRC.bit.CAP5INT==1){cap_a=EvbRegs.CAP5FIFO;EvbRegs.EVBIFRC.bit.CAP5INT=1;}else if(EvbRegs.EVBIFRC.bit.CAP6INT==1)cap_a=EvbRegs.CAP6FIFO;EvbRegs.EVBIFRC.bit.CAP6INT=1;}cap_c=cap_a-cap_b;if(cap_c<0) cap_c=cap_c+0xffff;cap_b=cap_a;GpioMuxRegs.GPBMUX.bit.CAP4Q1_GPIOB8=1; //将cap456设置为CAP口 GpioMuxRegs.GPBMUX.bit.CAP5Q2_GPIOB9=1;GpioMuxRegs.GPBMUX.bit.CAP6QI2_GPIOB10=1;EINT;}InitData(){char i;T_pointer=0; //发送数据数组指针R_pointer=0; //接收数据数组指针a2=0;for(i=0;i<8;i++){Sci_Rx[i]=0;Sci_Tx[i]=0;cap1=0; //前次换向标志位cap2=0; //本次换向标志位intruptcount=0; //定时器1下溢中断次数Idc_given2=0; //算得本次电流给定值speed_e1=0; //前次转速误差speed_e2=0; //本次转速误差Ia_e1=0; //前次电流误差Ia_e2=0; //本次电流误差t2over=0;t2first=0;COMP2=0; //装比较寄存器值speed_counter=0; //速度环计数器cap_a=0;cap_b=0;cap_c=0;for(i=0;i<10;i++){BLDC_SPD[i]=0;}}/////////////////////////////////////////////////////////////////////// // BLDC.c 程序结束////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 文件名: DSP28_Ev.c// 意义: DSP28 EV初始化/////////////////////////////////////////////////////////////////////// #include "DSP28_Device.h"void InitEv(void){//定时器T1初始化EvaRegs.T1PR =7500; //周期寄存器 5khzEvaRegs.T1CON.all = 0X080C; //连续增减计数EvaRegs.CMPR1=0; //比较寄存器初始化EvaRegs.CMPR2=0;EvaRegs.CMPR3=0;EvaRegs.ACTR.all=0X0FFF; //6PWM强制高CONA.all=0X8A00; //比较寄存器T1下溢重载CONA.bit.ACTRLD=2; //方式控制寄存器立即重载EvaRegs.DBTCONA.all=0X0FF4; //死区3.2usEvaRegs.T1CNT=0;EvaRegs.EVAIMRA.all=0X0200; //T1下溢使能EvaRegs.EVAIFRA.all=0X0FFFF; //清中断标志位//定时器T4初始化EvbRegs.T4PR = 60000; // 周期寄存器EvbRegs.T4CON.all = 0X0F0C; // 连续增减计数EvbRegs.EVBIMRB.all=0X0000; // T4中断不使能EvbRegs.EVBIFRB.all=0X0FFFF; // 清中断标志位}/////////////////////////////////////////////////////////////////////// // DSP28_Ev.c结束/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 文件名: DSP28_Sci.c// 意义: DSP28 SCI 初始化//////////////////////////////////////////////////////////////////////// #include "DSP28_Device.h"unsigned int * UART_MODE = (unsigned int *) 0x4010;void InitSci(void){// Initialize SCI-A:*UART_MODE = 0x44;EALLOW;GpioMuxRegs.GPFMUX.all = 0x0030;EDIS;SciaRegs.SCICCR.all = 0x07; //8位,无校验SciaRegs.SCICTL1.all = 0x03; //软件复位发送接收使能SciaRegs.SCIHBAUD = 0x01; //波特率9600B/S SciaRegs.SCILBAUD = 0x0E7;SciaRegs.SCICTL1.all = 0x23; //清除软件复位发送接收使能}//发送准备好int SciaTx_Ready(void){unsigned int i;if(SciaRegs.SCICTL2.bit.TXRDY == 1){i = 1;}else{i = 0;}return(i);}//接收准备好int SciaRx_Ready(void){unsigned int i;if(SciaRegs.SCIRXST.bit.RXRDY == 1){i = 1;}else{i = 0;}return(i);}///////////////////////////////////////////////////////////////////////////DSP28_Sci.c结束///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// 文件名: DSP28_SysCtrl.c// 意义: DSP28 系统控制寄存器初始化//////////////////////////////////////////////////////////////////////////// #include "DSP28_Device.h"void InitSysCtrl(void){Uint16 i;EALLOW;DevEmuRegs.M0RAMDFT = 0x0300;DevEmuRegs.M1RAMDFT = 0x0300;DevEmuRegs.L0RAMDFT = 0x0300;DevEmuRegs.L1RAMDFT = 0x0300;DevEmuRegs.H0RAMDFT = 0x0300;// Disable watchdog moduleSysCtrlRegs.WDCR= 0x0068;// Initalize PLLSysCtrlRegs.PLLCR = 0xA; //CLKIN=150M// Wait for PLL to lockfor(i= 0; i< 5000; i++){}// HISPCP/LOSPCP prescale register settings, normally it will be set to default valuesSysCtrlRegs.HISPCP.all = 0x0001; //高速时钟75MSysCtrlRegs.LOSPCP.all = 0x0002; //低速时钟37.5M// Peripheral clock enables set for the selected peripherals.SysCtrlRegs.PCLKCR.bit.EVAENCLK=1; //使能EVASysCtrlRegs.PCLKCR.bit.EVBENCLK=1; //使能EVBSysCtrlRegs.PCLKCR.bit.SCIENCLKA=1;//使能SCISysCtrlRegs.PCLKCR.bit.ADCENCLK=1; //使能ADC}///////////////////////////////////////////////////////////////////////////DSP28_SysCtrl.c结束//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 文件: DSP28_PieCtrl.c// 意义: DSP28 PIE 控制寄存器初始化///////////////////////////////////////////////////////////////////////// #include "DSP28_Device.h"void InitPieCtrl(void){// Disable PIE:PieCtrl.PIECRTL.bit.ENPIE = 0;// Clear all PIEIER registers:PieCtrl.PIEIER1.all = 0;PieCtrl.PIEIER2.all = 0;PieCtrl.PIEIER3.all = 0;PieCtrl.PIEIER4.all = 0;PieCtrl.PIEIER5.all = 0;PieCtrl.PIEIER6.all = 0;PieCtrl.PIEIER7.all = 0;PieCtrl.PIEIER8.all = 0;PieCtrl.PIEIER9.all = 0;PieCtrl.PIEIER10.all= 0;PieCtrl.PIEIER11.all= 0;PieCtrl.PIEIER12.all= 0;// Clear all PIEIFR registers:PieCtrl.PIEIFR1.all = 0;PieCtrl.PIEIFR2.all = 0;PieCtrl.PIEIFR3.all = 0;PieCtrl.PIEIFR4.all = 0;PieCtrl.PIEIFR5.all = 0;PieCtrl.PIEIFR6.all = 0;PieCtrl.PIEIFR7.all = 0;PieCtrl.PIEIFR8.all = 0;PieCtrl.PIEIFR9.all = 0;PieCtrl.PIEIFR10.all= 0;PieCtrl.PIEIFR11.all= 0;PieCtrl.PIEIFR12.all= 0;// Enable PIE:PieCtrl.PIECRTL.bit.ENPIE = 1;PieCtrl.PIEACK.all = 0xFFFF;}///////////////////////////////////////////////////////////////////////////DSP28_PieCtrl.c结束//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 文件名: DSP28_PieVect.c// 意义: DSP28 PIE 向量表初始化//////////////////////////////////////////////////////////////////////////// #include "DSP28_Device.h"const struct PIE_VECT_TABLE PieVectTableInit = {PIE_RESERVED, // Reserved spacePIE_RESERVED,PIE_RESERVED,PIE_RESERVED,PIE_RESERVED,PIE_RESERVED,PIE_RESERVED,PIE_RESERVED,PIE_RESERVED,PIE_RESERVED,PIE_RESERVED,PIE_RESERVED,PIE_RESERVED,// Non-Peripheral InterruptsINT13_ISR, // XINT13 or CPU-Timer 1 INT14_ISR, // CPU-Timer2DATALOG_ISR, // Datalogging interrupt RTOSINT_ISR, // RTOS interruptEMUINT_ISR, // Emulation interrupt NMI_ISR, // Non-maskable interrupt ILLEGAL_ISR, // Illegal operation TRAP USER0_ISR, // User Defined trap 0 USER1_ISR, // User Defined trap 1 USER2_ISR, // User Defined trap 2USER3_ISR, // User Defined trap 3 USER4_ISR, // User Defined trap 4 USER5_ISR, // User Defined trap 5 USER6_ISR, // User Defined trap 6 USER7_ISR, // User Defined trap 7 USER8_ISR, // User Defined trap 8 USER9_ISR, // User Defined trap 9 USER10_ISR, // User Defined trap 10 USER11_ISR, // User Defined trap 11 // Group 1 PIE VectorsPDPINTA_ISR, // EV-APDPINTB_ISR, // EV-Brsvd_ISR,XINT1_ISR,XINT2_ISR,ADCINT_ISR, // ADCTINT0_ISR, // Timer 0WAKEINT_ISR, // WD// Group 2 PIE VectorsCMP1INT_ISR, // EV-ACMP2INT_ISR, // EV-ACMP3INT_ISR, // EV-AT1PINT_ISR, // EV-AT1CINT_ISR, // EV-AT1UFINT_ISR, // EV-Arsvd_ISR,// Group 3 PIE Vectors T2PINT_ISR, // EV-A T2CINT_ISR, // EV-A T2UFINT_ISR, // EV-A T2OFINT_ISR, // EV-A CAPINT1_ISR, // EV-A CAPINT2_ISR, // EV-A CAPINT3_ISR, // EV-A rsvd_ISR,// Group 4 PIE Vectors CMP4INT_ISR, // EV-B CMP5INT_ISR, // EV-B CMP6INT_ISR, // EV-B T3PINT_ISR, // EV-B T3CINT_ISR, // EV-B T3UFINT_ISR, // EV-B T3OFINT_ISR, // EV-B rsvd_ISR,// Group 5 PIE Vectors T4PINT_ISR, // EV-B T4CINT_ISR, // EV-B T4UFINT_ISR, // EV-B T4OFINT_ISR, // EV-BCAPINT5_ISR, // EV-B CAPINT6_ISR, // EV-B rsvd_ISR,// Group 6 PIE Vectors SPIRXINTA_ISR, // SPI-A SPITXINTA_ISR, // SPI-A rsvd_ISR,rsvd_ISR,MRINTA_ISR, // McBSP-A MXINTA_ISR, // McBSP-A rsvd_ISR,rsvd_ISR,// Group 7 PIE Vectors rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,// Group 8 PIE Vectors rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,// Group 9 PIE Vectors SCIRXINTA_ISR, // SCI-A SCITXINTA_ISR, // SCI-A SCIRXINTB_ISR, // SCI-B SCITXINTB_ISR, // SCI-B ECAN0INTA_ISR, // eCAN ECAN1INTA_ISR, // eCANrsvd_ISR,rsvd_ISR,// Group 10 PIE Vectors rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,// Group 11 PIE Vectorsrsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,// Group 12 PIE Vectorsrsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,rsvd_ISR,};void InitPieVectTable(void){int16 i;Uint32 *Source = (void *) &PieVectTableInit;Uint32 *Dest = (void *) &PieVectTable;EALLOW;for(i=0; i < 128; i++)*Dest++ = *Source++;EDIS;// Enable the PIE Vector TablePieCtrl.PIECRTL.bit.ENPIE = 1;}///////////////////////////////////////////////////////////////////////// //DSP28_PieVect.c结束////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 文件名: DSP28_Gpio.c// 意义: 初始化I/O///////////////////////////////////////////////////////////////////////// #include "DSP28_Device.h"void InitGpio(void){EALLOW;// Set GPIO A port pins, enable 6PWMGpioMuxRegs.GPAMUX.all=0x033F; // EVA PWM 1-6GpioMuxRegs.GPADIR.all=0xFF3F;。

基于DSP的直流电机控制系统C程序(包括1602显示,捕获CAP、PWM波发生程序)

基于DSP的直流电机控制系统C程序(包括1602显示,捕获CAP、PWM波发生程序)

DSP2407控制直流电机程序附录系统主程序:/*Main.c*//*PWM电机控制程序,正反转,默认设置的工作频率1kHz*/#include "register.h"void SystemInit();void Timer1Init();void KickDog();void change();void cap4Init();unsigned int numled=20,numkey=0;unsigned int a=0,b=0;unsigned int count=0,time_count=0,f_count=0;unsigned char tab1[3]={'r','/','s'};unsigned char tab2[15]={' ','S','e','t',' ','B','y',' ','L,'i','n','F','a','n','g'};#define RS_H PADATDIR=PADA TDIR | 0x0008#define RS_L PADATDIR=PADA TDIR & 0xFFF7#define RW_H PADATDIR=PADATDIR | 0x0010#define RW_L PADATDIR=PADATDIR & 0xFFEF#define E_H PADATDIR=PADA TDIR | 0x0020#define E_L PADATDIR=PADA TDIR & 0xFFDF#define PASC PADATDIR=PADA TDIR | 0x3800#define PCSC PCDA TDIR=PCDATDIR | 0xFF00#define PCSR PCDA TDIR=PCDATDIR & 0x00FF#define uchar unsigned char#define uint unsigned intvoid LCD1602init();void writecommand(uchar command);void LCDdisplay();void readstat();void delay(unsigned int i);main(){SystemInit(); //系统初始化MCRB=MCRB & 0xFF00; //IOPC口为一般I/O口MCRA=MCRA & 0xC0C7; //IOPB0-5、IOPA3-5设为IO口模式MCRC=MCRC & 0xE0FF; //IOPF0-4设为IO口模式PBDATDIR=0xFFC2; //所有LED=0PFDATDIR=0xF8E7; //置IOPE1-3为输入口Timer1Init(); //定时器1初始化cap4Init();LCD1602init();T3CON=T3CON|0X0040; // 启动定时器3asm(" CLRC INTM ");while(1){change();LCDdisplay();}}void SystemInit(){asm(" SETC INTM "); /* 关闭总中断*/asm(" CLRC SXM "); /* 禁止符号位扩展*/asm(" CLRC CNF ");asm(" CLRC OVM "); /* 累加器结果正常溢出*/SCSR1=0x83FE; /* 系统时钟CLKOUT=20*2=40M *//* 打开ADC,EV A,EVB,CAN和SCI的时钟,系统时钟CLKOUT=40M */ WDCR=0x006F; /* 禁止看门狗,看门狗时钟64分频*/KickDog(); /* 初始化看门狗*/IFR=0xFFFF; /* 清除中断标志*/IMR=0x0000; /* 禁止所有中断*/}void Timer1Init(){EVAIMRA=0x0080; // 定时器1周期中断使能EVAIFRA=0xFFFF; // 清除中断标志GPTCONA=0x0000;T1PR=25000; // 定时器1初值,定时0.4us*2500=1msCMPR1=25000;T1CNT=0;T1CON=0x144E; //增模式, TPS系数40M/16=2.5M,T1使能IMR|=0x0002; //打开中断2}void cap4Init(){T3PR=0xFFFF; // 通用定时器3的周期寄存器为0XFFFFT3CON=0x1400; // 通用定时器3为连续增计数模式T3CNT=0x00; // 计数器清0WSGR=0x0000; // 禁止所有等待状态CAPCONB=0x0A440; // 设置捕获单元4为检测上升沿,且选择TIMER3为时钟asm(" clrc INTM"); // 开总中断IMR|=0x0008; // 允许中断优先级4的中断CAP4FIFO=0;EVBIMRC=EVBIMRC|0X0001; // 允许CAPTURE4中断EVBIFRC=EVBIFRC|0X0FFFF;}void LCD1602init() //LCD1602初始化函数{writecommand(0x38);writecommand(0x38);writecommand(0x38);delay(150);writecommand(0x01);delay(150);writecommand(0x02);delay(150);writecommand(0x06);delay(150);writecommand(0x0c);delay(150);writecommand(0x38);}void writecommand(uchar command) //LCD1602写命令函数{readstat();PCSC;PASC;RS_L;RW_L;PCDATDIR=PCDATDIR & 0x0FF00|command;//在此条指令之后只要使能信号有个由高到低的跳变即可写液晶delay(5);E_L; //可以不要asm(" NOP"); //可以不要asm(" NOP"); //可以不要asm(" NOP"); //可以不要E_H;delay(5); //可以不要E_L;}void readstat(){unsigned int stat;PCSR;PASC;while(1){RS_L;E_H;RW_H;stat=PCDATDIR & 0x0080;if(stat==0)break;}}void writedata(uchar data) //LCD1602写数据函数{readstat();PCSC;PASC;RS_H;RW_L;PCDA TDIR=PCDA TDIR & 0x0FF00|data;//在此条指令之后只要使能信号有个由高到低的跳变即可写液晶//如果在这之前就有//由高到低的变化就会送出去乱码,即不是自己想要的值delay(5);E_L; //可以不要asm(" NOP");//可以不要asm(" NOP");//可以不要asm(" NOP");//可以不要E_H;delay(5); //可以不要E_L;}void change(){MCRA=MCRA | 0x00C0; //PA6为PWM口ACTRA=0x0006; //PWM1高有效DBTCONA=0x0530; //使能死区定时器1,分频40M/16=2.5M,死区时5*0.4us=2us COMCONA=0xA600; //比较控制寄存器if((PFDATDIR & 0x0001)!=0x0001) //若有按键仍为低,IOPF0=0{delay(800);if((PFDATDIR & 0x0001)!=0x0001){b=0;numkey=1;a++;if(a==4) a=1;while((PFDATDIR & 0x0001)!=0x0001);}}if((PFDATDIR & 0x0002)!=0x0002) //若有按键仍为低,IOPF1=0{a=0;b=0;numkey=2;}if((PFDATDIR & 0x0004)!=0x0004) //若有按键仍为低,IOPF2=0 {delay(800);if((PFDATDIR & 0x0004)!=0x0004){a=0;numkey=3;b++;if(b==4) b=1;while((PFDA TDIR & 0x0004)!=0x0004);}}if(numkey==1){PFDATDIR=PFDATDIR & 0xF8E7;PFDATDIR=PFDATDIR | 0x1010;PBDATDIR=PBDA TDIR & 0xFFC7; //将其他的led灭掉PBDATDIR=PBDA TDIR | 0x0404; //IOPB2=1;LED1亮if(a==1) CMPR1=21000;if(a==2) CMPR1=17000;if(a==3) CMPR1=23500;}if(numkey==2){PFDATDIR=PFDA TDIR & 0xF8E7;CMPR1=25000;PFDATDIR=PFDATDIR | 0x1818;PBDATDIR=PBDA TDIR & 0xFFCB;PBDATDIR=PBDA TDIR | 0x0808; //IOPB3=1;LED2亮}if(numkey==3){PFDATDIR=PFDATDIR & 0xF8E7;PFDATDIR=PFDATDIR | 0x0808;PBDATDIR=PBDA TDIR & 0xFFD3;PBDATDIR=PBDA TDIR | 0x1010; //IOPB4=1;LED3亮if(b==1) CMPR1=21000;if(b==2) CMPR1=17000;if(b==3) CMPR1=23500;}}void c_int2() /*定时器1中断服务程序*/{if(PIVR!=0x27){ asm(" CLRC INTM ");return;}time_count++;if(time_count>=100){time_count=0;f_count=count;count=0;}T1CNT=0;numled--;if(numled==0){numled=20;if((PBDATDIR & 0x0001)==0x0001)PBDA TDIR=PBDATDIR & 0xFFFE; //IOPB0=0;LED灭elsePBDA TDIR=PBDATDIR |0x0101; //IOPB0=1;LED亮}EVAIFRA=0x80;asm(" CLRC INTM ");return;}void cap4int(){int flag;flag=EVBIFRC&0X01; // 判断是否是CAP4中断if(flag!=0x01){asm(" clrc INTM"); // 返回前开中断return; // 如果不是CAP4中断,则直接返回}count++;EVBIFRC=EVBIFRC|0x01; // 写"1"清除CAP4中断标志asm(" clrc INTM"); // 返回前开中断return; // 中断返回}void LCDdisplay(void){uint data;uchar data_qian,data_bai,data_shi,data_ge,address=0,add=0;writecommand(0x84);if(numkey == 3){data = '-';}else{data = '+';}writedata((uchar)data);data=f_count/4;data_qian=data/1000;data_bai=data%1000/100;data_shi=data%100/10;data_ge =data%10; writecommand(0x85);writedata(data_qian+0x30); writecommand(0x86);writedata(data_bai+0x30); writecommand(0x87);writedata(data_shi+0x30); writecommand(0x88);writedata(data_ge+0x30); address=0x89;for(add=0;add<3;add++,address++) {writecommand(address);data=tab1[add];writedata(data);}address=0xC0;for(add=0;add<15;add++,address++){writecommand(address);data=tab2[add];writedata(data);}}void delay(unsigned int i){ unsigned int j;for(;i>0;i--)for(j=1000;j>0;j--);}void interrupt PHANTOM(){asm(" clrc INTM"); // 返回前开中断return;}void KickDog() /*踢除看门狗*/{WDKEY=0x5555;WDKEY=0xAAAA;}中断向量表:;define.asm.include "lf2407a.h".include "F2407REGS.H".global _c_int0,_c_int2,_cap4int.global _IMR,_IFR.global _SCSR1,_SCSR2,_XINT1CR,_XINT2CR.global _WDCNTR,_WDKEY,_WDCR.global_MCRA,_MCRB,_MCRC,_PADA TDIR,_PBDATDIR,_PCDA TDIR,_PEDATDIR,_PFDA TDIR.global_ADCTRL1,_ADCTRL2,_MAXCONV,_CHSELSEQ1,_CHSELSEQ2,_CHSELSEQ3,_CHSELSEQ 4.global _AUTO_SEQ_SR,_RESULT0,_RESULT1,_RESULT2,_RESULT8,_RESULT9.global_CANMDER,_CANTCR,_CANRCR,_CANMCR,_CANBCR2,_CANBCR1,_CANESR,_CANGSR .global _CANCEC,_CANIFR,_CANIMR,_CANLAM0H,_CANLAM0L.global_CANID0L,_CANID0H,_CANCTRL0,_CANBX0A,_CANBX0B,_CANBX0C,_CANBX0D.global_CANID1L,_CANID1H,_CANCTRL1,_CANBX1A,_CANBX1B,_CANBX1C,_CANBX1D.global_CANID2L,_CANID2H,_CANCTRL2,_CANBX2A,_CANBX2B,_CANBX2C,_CANBX2D.global_CANID3L,_CANID3H,_CANCTRL3,_CANBX3A,_CANBX3B,_CANBX3C,_CANBX3D.global_CANID4L,_CANID4H,_CANCTRL4,_CANBX4A,_CANBX4B,_CANBX4C,_CANBX4D.global_CANID5L,_CANID5H,_CANCTRL5,_CANBX5A,_CANBX5B,_CANBX5C,_CANBX5D.global_SCICCR,_SCICTL1,_SCIHBAUD,_SCILBAUD,_SCICTL2,_SCIRXST,_SCIRXEMU,_SCIRXBU F,_SCITXBUF,_SCIPRI;.global _GPTCONA,_T1CNT,_T1PR,_T1CON,_T2CNT,_T2PR,_T2CON.global _EV AIMRA,_EV AIMRB,_EV AIFRA,_EV AIFRB,_PIVR.global_GPTCONB,_T3CNT,_T3CMPR,_T3PR,_T3CON,_COMCONA,_ACTRA,_DBTCONA,_CMPR1, _EVBIMRA,_EVBIFRA.global _WSGR,_CAPCONB,_EVBIMRC,_EVBIFRC;建立中断向量表.sect ".vectors"RSVECT B _c_int0INT1 B PHANTOMINT2 B _c_int2INT3 B PHANTOMINT4 B _cap4intINT5 B PHANTOMINT6 B PHANTOM.textPHANTOM:KICK_DOGRET.end。

DSP异步电机模糊控制编程实现

DSP异步电机模糊控制编程实现

第10卷 第1期2006年1月电 机 与 控 制 学 报EL EC TR IC MACH I N ES AND CON TROLVol 110No 11Jan .2006基于D SP 的异步电机模糊控制系统编程实现刘福才1, 韩会山1,2, 陈 丽2(1.燕山大学电气工程学院,河北秦皇岛066004;2.邢台职业技术学院电子系,河北邢台054000)摘 要:针对模糊控制器的DSP 编程实现问题,依据模糊输入、输出空间的对称性,采用对空间分区建立索引表的方法,建立了一种基于T MS320LF2407A 的新型模糊控制器的编程实现框图,并应用在交流感应电动机V /F 闭环变频控制系统的速度环中。

在理论分析和系统仿真的基础上,通过实验验证该算法的可行性,并且系统具有良好的动态性能,转速超调量小。

关键词:异步电机;DSP;V /F 变频;模糊控制中图分类号:TP273;T M921.5文献标识码:A文章编号:1007-449X (2006)01-0018-05A DSP based i n ducti on motor control syste m withfuzzy controller program sche meL I U Fu 2cai 1, HAN Hui 2shan1,2, CHEN L i2(1.Depart m ent of Aut omati on,Yanshan University,Q inhuangdao 066004,China;2.Depart m ent of Electricity,Xingtai I nstitute of Pr ofessi onal Technol ogy,Xingtai 054000,China )Abstract:I n order t o realize the DSP comp ile of fuzzy contr ol,an index bl ock of fuzzy s pace was com 2p iled,utilizing the input/out put fuzzy s pace sy mmetry .Based on the T MS320LF2407A,a novel fuzzy al 2gorith m p r ogra m method f or V /F inducti on mot or contr ol syste m has been p r oposed .Si m ulati on results and experi m ent results de monstrate that the p r oposed fuzzy p r ogra m sche me is valid,and the dyna m ic perf or mance is quite well,and the overshoot is s mall .Key words:inducti on mot or;DSP;V /F converter;fuzzy contr ol收稿日期:2004-09-21;修订日期:2005-06-22基金项目:燕山大学博士基金资助项目(B111)作者简介:刘福才(1966-),男,博士、教授,研究方向为模糊辨识与预测控制、电力拖动及其计算机控制;韩会山(1975-),男,硕士研究生,研究方向为电力拖动控制系统及交流伺服调速系统智能控制;陈 丽(1977-),女,讲师、硕士,从事机器人控制、智能控制研究。

基于DSP的无刷直流电机控制方法

基于DSP的无刷直流电机控制方法

算法精度
改进算法,提高控制精度,减小 电机运行过程中的误差,提升电 机性能。
鲁棒性增强
增强控制算法的鲁棒性,减小外 部干扰对电机性能的影响,提高 系统的稳定性。
硬件设计优化
电路板布局优化
合理布置电路板上的元器 件,减小信号传输延时和 干扰,提高信号质量。
电源管理优化
优化电源电路设计,提高 电源稳定性和效率,降低 电源噪声对控制系统的影 响。
基于DSP的无刷直流电机控 制方法
汇报人: 2024-01-01
目录
• 引言 • 无刷直流电机原理 • DSP技术基础 • 基于DSP的无刷直流电机控制
方法 • 优化与改进 • 结论与展望
01
引言
研究背景与意义
研究背景
随着工业自动化和智能化的快速发展,无刷直流电机(BLDCM)因其高效、节能、高可靠性等优点 ,在许多领域得到了广泛应用。为了实现无刷直流电机的精确控制,需要研究先进的控制策略和方法 。
直流电机的控制中。
研究趋势
随着人工智能和机器学习技术的不断发展,基于深度学习、强化学习等机器学习算法的 无刷直流电机控制方法成为新的研究趋势。这些方法能够实现对电机的自适应、自主学 习控制,进一步提高电机的性能和智能化水平。同时,随着电力电子技术和传感器技术
的不断发展,无刷直流电机的控制精度和响应速度也将得到进一步提高。
定性。
无刷直流电机应用领域
01
02
03
工业自动化
无刷直流电机广泛应用于 各种自动化生产线、机器 人、数控机床等领域。
电动车
无刷直流电机在电动车领 域具有广泛的应用,如电 动自行车、电动摩托车、 电动汽车等。
家用电器
无刷直流电机也应用于家 用电器中,如空调、冰箱 、洗衣机等。

利用DSP控制直流无刷电机

利用DSP控制直流无刷电机

利用DSP控制直流无刷电机直流无刷电机(Brushless DC Motor,简称BLDC)由于其高效、高转速、大扭矩和低噪音等特性而被广泛应用于各种领域。

要控制BLDC进行转速调节、位置控制等,需要使用数字信号处理器(Digital Signal Processor,简称DSP)来实现。

本文将详细介绍如何利用DSP控制直流无刷电机。

一、直流无刷电机介绍直流无刷电机由转子和定子组成,电机可通过电子调速控制技术实现闭环控制,即通过检测电流、电压、角度等参数来实现控制。

相较于传统的可调电阻电调速和功率电子器件调速,无刷电机控制方式更为精确,可控性更高,并且在减小电气噪声的同时大大提高了效率。

二、直流无刷电机的控制方式直流无刷电机的控制方式可以分为三种:感应式、霍尔传感器控制、反电动势检测控制。

其中,感应式控制方式较为简单,但其准确性和鲁棒性较差;霍尔传感器控制方式使用霍尔元件检测转子位置,可以获得更高的准确性和鲁棒性;反电动势检测控制方式通过检测转子的反电动势来确定位置,具有简化硬件和准确性高等优点。

三、DSP控制直流无刷电机利用DSP控制直流无刷电机需要进行以下几个步骤:1. 设置DSP的GPIO口并输入代码:用GPIO口连接电机,可根据需要设置GPIO管脚的中断、状态和其他属性,并输入代码到DSP中。

2. 制作电机转速控制器:通过编写参考电路和硬件控制程序来制作电机转速控制器,代码需要根据控制方式进行适当的修改。

3. 编写电机控制程序:根据转速调节、位置控制等的需求,编写相关的电机控制程序。

基本步骤包括:初始化电机控制器、设定控制参数、检测电机状态、执行电机控制指令等。

4. 测试和优化:根据测试结果优化电机控制程序,以达到最佳效果。

在测试过程中可以使用示波器、逻辑分析仪等工具进行分析。

四、DSP控制直流无刷电机的优点1. 高精度DSP能够提供高精度的控制,可在微秒级的时间内执行多种运算,实现高速、高精度的控制。

电机控制的DSP程序设计及CAN基础知识

电机控制的DSP程序设计及CAN基础知识

电机控制系统程序设计
通信发送程序设计 在发送部分软件设计中,如果根 据状态寄存器的发送状态标志来 判断是否可以发送数据,那么当 CAN总线出现断路,然后又正常, 这时即便进行软件初始化,数据也无法正常发送,原因是该状态标志位无法通过软件进行初始化来进行复位,因此在软件设计时可以不考虑该状态标志位。
CAN总线基本概念
CAN总线线与
高速CAN( CAN High Speed )遵循标准ISO-IS 11898,用于位速率为125kbp
到1Mbps之间的高速总线。
低速CAN( CAN Low Speed )遵循标准ISO-IS 11519-2,用于位速率在125kbps
以下的低速总线。
CAN总线接口标准
DSP芯片简介
2.DSP的性能 DSP性能公式:CPU时间 = CPI × IC / 时钟频率 三个参数反映了与体系结构相关的三种技术。 (1).时钟频率反映了DSP实现技术、生产工艺和计算机组织。 (2).CPI是指令时钟数,反映了DSP实现技术、计算机指令集的结构和计 算机组织。 (3).IC是程序执行过程中所处理的指令数,反映了DSP指令集的结构和编 译术。 从目前情况来看,提高某一个参数指标,不会明显地影响其它两个指标。 这对于综合运用各种技术改进计算机系统的性能是非常有益的。
电机控制的DSP程序设计及CAN基础知识 姓 名:叶振锋 时 间:2009年3月26日 公 司:上海电驱动有限公司
旅游旅行攻略
CLICK TO ADD TITLE
01
概述
电机控制系统程序设计
03
电机控制系统结构图
子程序模块设计说明
05
电机控制系统动态结构图
软件设计与调试注意事项

基于DSP控制的感应电机变频调速系统上位机程序使用说明

基于DSP控制的感应电机变频调速系统上位机程序使用说明

基于DSP控制的感应电机变频调速系统上位机程序使用说明目录基于DSP控制的感应电机变频调速系统上位机程序使用说明1.概述 (1)2.安装指南 (3)3.功能使用说明3.1 系统状态控制命令 (3)3.2 系统设置命令 (5)3.3 控制方式参数设置 (6)3.4 波形显示 (9)3.5 显示辅助设置 (10)3.6 数据采集参数设置 (12)3.7 状态显示 (14)4.使用实例4.1 开环SPWM异步调制启动转速与启动电流观测 (14)4.2 磁场定向(FOC)双闭环控制实验 (15)4.3 试验结束注意 (17)4.4 显示后期处理 (17)基于DSP控制的高性能无刷直流电动机实验系统上位机程序使用说明1.安装指南 (19)2.软件功能 (19)3.功能使用说明3.1 系统状态控制命令 (20)3.2系统命令 (21)3.3实验数据数值及波形显示 (23)3.4数据采集参数设置 (26)3.5控制方式参数设置 (27)4.调速系统 (27)5.伺服系统 (28)6.状态显示 (28)7.其他支持功能 (29)8.使用实例 (29)外扩DSP使用说明 (32)基于DSP 控制的感应电机变频调速系统上位机程序使用说明1.概述MCL-13上位机控制程序,是“基于DSP 控制的感应电机变频调速系统(MCL-13)”的上位机控制程序。

本软件与MCL-13挂箱配套使用。

MCL-13挂箱上备有串口RS232连接插座。

用户使用本软件前,应通过此连接插座与上位PC 机串口妥善连接。

脱离MCL-13挂箱,本软件将无效,装入运行时会引起死机。

程序主界面(User Interface )如图1.所示。

MSCL-13上位机控制程序可以完成对MCL-13系统的上位机控制,包括面板命令控制、各类控制策略内部参数给定、各类波形捕捉和后期数据图象处理。

1.1 面板控制命令给定:串口设置。

●数据后期处理命令给定。

在下列4种控制策略中,任意选择一种进行实验:开环SPWM 控制,开环空间矢量控制,闭环磁场定向控制,闭环直接转矩控制。

DSP三相交流电动机SVPWM开环调速控制程序(硬件法)

DSP三相交流电动机SVPWM开环调速控制程序(硬件法)

《4-3三相交流电动机SVPWM开环调速控制程序(硬件法)》.include "240x.h".global _c_int0ST0 .set 0ST1 .set 1.bss TEMP,1.bss SET_F,1.bss F_OMEGA,1.bss OMEGA,1.bss SET_V,1.bss MAX_V,1.bss T_SAMPLE,1.bss THETA_H,1.bss THETA_L,1.bss THETA_R,1.bss THETA_M,1.bss THETA_I,1.bss SS,1.bss SC,1.bss SIN_INDX,1.bss SIN_ENTRY,1.bss SIN_END,1.bss SIN_THETA,1.bss COS_THETA,1.bss UA,1.bss UB,1.bss THETA_S,1.bss SECTOR,1.bss THETA_90,1.bss THETA_180,1.bss THETA_270,1.bss THETA_360,1.bss DEC_MS,24.bss T1_PERIODS,1.bss CMP_1,1.bss CMP_2,1.bss SVPA T,1.bss ACCH,1.bss ACCL,1.bss AR0_SA VE,1.bss P_HI,1.bss P_LO,1ST0_SA VE .usect ".context",1ST1_SA VE .usect ".context",1.sect ".vectors" RESET B _c_int0INT1 B PHANTOMINT2 B _C_INT2 5 INT3 B PHANTOMINT4 B PHANTOMINT5 B PHANTOMINT6 B PHANTOM RESERVED B PHANTOM SW_INT8 B PHANTOM SW_INT9 B PHANTOM SW_INT10 B PHANTOM SW_INT11 B PHANTOM SW_INT12 B PHANTOM SW_INT13 B PHANTOM SW_INT14 B PHANTOM SW_INT15 B PHANTOM SW_INT16 B PHANTOM TRAP B PHANTOM NMI B PHANTOM EMU_TRAP B PHANTOM SW_INT20 B PHANTOM SW_INT21 B PHANTOM SW_INT22 B PHANTOM SW_INT23 B PHANTOM SW_INT24 B PHANTOM SW_INT25 B PHANTOM SW_INT26 B PHANTOM SW_INT27 B PHANTOM SW_INT28 B PHANTOM SW_INT29 B PHANTOM SW_INT30 B PHANTOM SW_INT31 B PHANTOM.sect ".pvecs" PVECTORS B PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B T1UF_ISR B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOM B PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOMB PHANTOM.text_c_int0SETC INTMCLRC CNFLDP #224SPLK #0000001000000100B,SCSR1SPLK #68H,WDCRLDP #225LACC MCRAOR #0FC0HSACL MCRALDP #0SPLK #0FFH,IFRSPLK #00000010B,IMRLDP #232SPLK #0FFFH,EV AIFRASPLK #0FH,EV AIFRBSPLK #0FH,EV AIFRCSPLK #0200H,EV AIMRASPLK #0,EV AIMRBSPLK #0,EV AIMRCSPLK #500,T1PRSPLK #500,CMPR1SPLK #500,CMPR2SPLK #500,CMPR3SPLK #0000011001100110B,ACTRASPLK #01F4H,DBTCONASPLK #1001001000000000B,COMCONASPLK #1000100000000010B,T1CONLDP #6SPLK #0347H,T_SAMPLESPLK #16000,T1_PERIODSSPLK #11585,MAX_VSPLK #0,SET_FSPLK #10053,F_OMEGASPLK #0,THETA_LSPLK #0,THETA_HLAR AR0,#THETA_90LAR AR1,#(28-1)LACC #ANGLES_LARP AR0INIT_TBLTBLR *+,AR1ADD #1BANZ INIT_TBL,AR0SPLK #29335,THETA_ISPLK #31291,THETA_SSPLK #SIN_ENTRY_,SIN_ENTRYSPLK #(SIN_ENTRY_+90),SIN_ENDLDP #232SPLK #0000100001000010B,T1CONCLRC INTMMAIN_LOOPLDP #6LT SET_FMPYU F_OMEGAPACSACH OMEGALT SET_FMPYU MAX_VPACSACH SET_VB MAIN_LOOPPHANTOMCLRC INTMRET_C_INT2SST #ST0,ST0_SA VESST #ST1,ST1_SA VELDP #6SACH ACCHSACL ACCLSPH P_HISPL P_LOMPY #1SPL T_SA VESAR AR0,AR0_SA VECLRC SXMLDP #224LACC PIVRSUB #029HBCND T1UF_ISR,EQ RESTLDP #6LAR AR0, AR0_SA VELT P_LOMPY #1LPH P_HILT T_SA VELACC ACCH,16ADDS ACCLLDP #0LST #ST1,ST1_SA VELST #ST0,ST0_SA VECLRC INTMRETT1UF_ISRLDP #232SPLK #0FFFH,EV AIFRALDP #6LT OMEGAMPY T_SAMPLEPACSFRADD THETA_H,16ADDS THETA_LSACH THETA_HSACL THETA_LBCND CHK_UPLIM,GEQADD THETA_360,16SACH THETA_HB RND_THETA CHK_UPLIMSUB THETA_360,16BCND REST_THETA,LEQSACH THETA_HB RND_THETA REST_THETAADD THETA_360,16RND_THETAADD #1,15SACH THETA_RLACC #1SACL SSSACL SCLACC THETA_RSACL THETA_MSUB THETA_90 ;BCND E_Q,LEQSPLK #-1,SCLACC THETA_180SUB THETA_RSACL THETA_MBCND E_Q,GEQSPLK #-1,SSLACC THETA_RSUB THETA_180SACL THETA_MLACC THETA_270SUB THETA_RBCND E_Q,GEQSPLK #1,SCLACC THETA_360SUB THETA_RSACL THETA_ME_QLT THETA_MMPYU THETA_IPACSACH SIN_INDXLACC SIN_INDX,11SACH SIN_INDXLACC SIN_ENTRYADD SIN_INDXTBLR SIN_THETALACC SIN_ENDSUB SIN_INDX ;TBLR COS_THETA ;LT SSMPY SIN_THETAPACSACL SIN_THETALT SCMPY COS_THETAPACSACL COS_THETALT SET_VMPY COS_THETAPACSACH UAMPY SIN_THETAPACSACH UBLT THETA_RMPY THETA_SPACSACH SECTORLACC SECTOR,5SACH SECTORLACC #DEC_MSADD SECTOR,2SACL TEMPLAR AR0,TEMPLT UAMPY *+PACLT UBMPY *+APACBCND CMP1BIG0,GEQLACC #0CMP1BIG0SACH TEMPLT TEMPMPY T1_PERIODSPACADD #1,15SACH CMP_1,1LT UAMPY *+PACLT UBMPY *+APACBCND CMP2BIG0,GEQLACC #0CMP2BIG0SACH TEMPLT TEMPMPY T1_PERIODSPACADD #1,15SACH CMP_2,1LACC #CCKWISE_ADD SECTORTBLR SVPATLAR AR0,#ACTRALACC *AND #0FFFHOR SVPATSACL *LAR AR0,#CMPR1LACC CMP_1SACL *+ADD CMP_2SACL *SUB #500BCND IN_LMT,LEQSPLK #500,*IN_LMTB REST.dataANGLES_.word 01922H.word 03244H.word 04B66H.word 06488HDEC_MS .word 20066.word –11585.word 0.word 23170.word 20066.word 11585.word -20066.word 11585.word 0.word 23170.word -20066.word -11585.word -20066.word 11585.word 0.word -23170.word -20066.word -11585.word 20066.word -11585.word 0.word -23170.word 20066.word 11585CCKWISE_.word 0001000000000000B.word 0011000000000000B.word 0010000000000000B.word 0110000000000000B.word 0100000000000000B.word 0101000000000000BSIN_ENTRY_.word 0.word 286,572,857,1143,1428.word 1713,1997,2280,2563,2845.word 3126,3406,3686,3964,4240.word 4516,4790,5063,5334,5604.word 5872,6138,6402,6664,6924.word 7182,7438,7692,7943,8192.word 8438,8682,8923,9162,9397.word 9630,9860,10087,10311,10531.word 10749,10963,11174,11381,11585.word 11786,11982,12176,12365,12551.word 12733,12911,13085,13255,13421.word 13583,13741,13894,14044,14189.word 14330,14466,14598,14726,14849.word 14968,15082,15191,15296,15396.word 15491,15582,15668,15749,15826.word 15897,15964,16026,16083,16135.word 16182,16225,16262,16294,16322.word 16344,16362,16374,16382,16384.end。

dsp课程设计报告电机控制

dsp课程设计报告电机控制

目录一.实验设备 (3)二.课程设计要求 (3)三.课程设计思路 (3)四.实验接线 (5)五.相关代码的详细说明 (6)六.设计总结 (9)一.实验设备1.PC机一台,操作系统为WindowsXP (或Windows98、Windows2000),安装了ccs3.1;2.TI 2000系列的TMS320F2812 eZdsp开发板一块;3.扩展实验箱一台;4.示波器一台;5.直流电机及其驱动箱一套。

二.课程设计要求课程设计中使用的直流电机(THBLD-1型力矩电机控制)驱动有两种方式,可以使用其自带的驱动箱,也可以使用扩展实验箱中的驱动电路,因此可任选一种方式完成课程设计,具体要求:方式一(使用电机自带的驱动箱):①利用DSP的事件管理器产生一路PWM接入驱动箱,控制电机;②利用按键检测控制电机,一个按键控制电机正转和反转(按键一次改变电机转向),另一个按键控制电机转速(三级调速,按键一次改变一次速度);③利用QEP采样电路检测电机转速;④数码管显示电机当前转速。

方式二(使用实验箱上的驱动电路)①理解直流电机双极性驱动电路的原理,利用事件管理器产生正确的PWM控制波形,实现电机开环控制;②利用按键检测控制电机,一个按键控制电机正转和反转(按键一次改变电机转向),另一个按键控制电机转速(三级调速,按键一次改变一次速度);③利用QEP采样电路检测电机转速;④数码管显示电机当前转速。

三.课程设计思路在本课程设计中,我们采用了直流电机(THBLD-1型力矩电机控制)驱动的第一种方式——使用电机自带的驱动箱驱动的方式。

实验思路如下:1.利用DSP的事件管理器产生一路PWM接入驱动箱,控制电机。

TMS320F2812处理器包含EVA和EVB2个事件管理器,每个事件管理器包含通用定时器(GP)、比较器、PWM单元、捕获单元以及正交编码脉冲电路(QEP)。

PWM 单元主要应用于产生脉宽调制信号控制数字电机。

在本课程设计中,我们使用了事件管理器EVA的通用定时器1来产生一路PWM信号——PWM1,来控制电机。

DSP的PWM电机控制程序代码分析

DSP的PWM电机控制程序代码分析

中南大学DSF原理及应用课程代码分析报告报告题目:DSP的PWM电机控制程序代码分析学院: ____________专业班级:____________________姓名: ________________________学号:0909082203指导老师:刘建成目录1. 基本原理2. 数据存储空间(汇编源程序)、头文件和变量声明(C 源程序)分析3. 算法分析与流程图4. 总结1. 基本原理1.每个240X器件都包含两个事件管理模块EVA和EVB,每个时间管理器模块包括通用定时器、比较单元、捕获单元,以及正交编码脉冲电路。

2.直流电机控制:直流电动机是最早出现的电动机,也是最早能实现调速的电动机。

近年来,直流电动机的结构和控制方法都发生了很大的变化。

随着计算机进入控制领域,以及新型的电力电子功率元器件的不断出现,使采用全控型的开关功率元件进行脉宽调制(PWM)控制方式已成为绝对主流。

PWM调压调速原理:其中,U为电枢端电压;I为电枢电流;R为电枢电路总电阻;为每级磁通量;K为电动机结构参数。

所以直流电机的转速控制方法可分为两类:对励磁通进行控制的励磁控制法和对电枢电压进行控制的电枢控制法。

其中励磁控制法在低速时受磁极饱和的限制,在高速时受换向火花和换向器结构强度的限制,并且励磁线圈电感较大,动态响应较差,所以这种控制方法用得很少。

现在,大多数应用场合都使用电枢控制法。

绝大多数电流电机采用开关驱动方法。

开关驱动方式是使半导体功率器件工作在开关状态,通过脉宽调制PWM来控制电动机电枢电压,实现调速。

具体电路如下图。

UP超16C1ALr:DDU1DMOTE直流电动机转速n的表达式为:U IR nK2. 数据存储空间(汇编源程序)、头文件和变量声明(C 源程序)分析在此程序中定义了如下变量(C 源程序)/^global.c*7extern uksiifled int $丹1佩训2問冊卩吋冋卿; extern unsigned int WDCB^IDKEV : extern URsijntd int [MR r IFI,PIIRi r VS0t;extern unsized int MCRA.HCRI.MCHC.PflDAIBl^PBDATDIH.rCMnil.KMnitPFDnOIH; extern unsigned int 眦TRLMDCTRL?川WONU 邮EL 刑邮FL 叫邮WQ3附血Qh; extern unsized int AlirOSEIJSR RESULT ^RESULTI.RfSLLTS, RESULTS RESULT?; extern unsigreti int 耶HO®HTGR£RN 删期帼乩冊顺R2MMGR1 疋RHE 恥⑷隔端 extern unsized int 帥NCFM 肪旧朋胆札倔肚酣脚血吐州肚;PKtern unsigned int CAHIDmjCnHtDSL^DNCTRLOfCANEMOfl.CAffiXBB^ANBXOCjCANBXOO; PKterfl unsigned int GAKIEIH.CRHIDlL.CAIETHLI.CANeXIR^RW^B^ftNBKIC^ANBMD ;extern unsigned int CAHID2H I CAHID2L,CAHCTRL2I CAH6X2A J CAHei!2S T CAHDX2C I CANBX2D; PKtern unsigned int 聽帕03儿蚀川蚀問1£即直理用欄%1:噸监盼血11瞄眄蚀丽鹉片extern unsigned int 即NID4H#RHM 札.CRHCTRL*』朋BKUbCR 蔺胡盼皿冊汕C,C 側册呱; extern unsigned int 渤ID5H#ANI 瓯,MNCTRL 几朋哪井問删唧,他删丸,朋册曲; extern unsigred int 離ICCR 靑tICTU,SUHE 細釘SC 】UIW0dl :I (;TL2』mRXST.SCIRXENI.SCJRXBUF.SCHXIUF,SC1FR I;蹴PM unsigned ilt SHCDHAJICNTJIPHJICON.T^CNT.IZPRJ^CDH.EUAlMRflJUAlMRBJUAIFHftJUAIFRB ; »tern unHqn 凶 int 即TMNEJMNT J 斜PRJ3PRJ 剜HQIONA /济陆MT 饲陆柑IPIH,口时删上朋IFRA;在此程序中定义如下数据空间(汇编程序):ine.asnc_inrn R _fi_tnti* c_int?I MR, IFR ~SCSftll B SCSR2, jKJHnCR, KIH12CR WDIDHTR p UDKE¥,_WDCR憎 M,」離朋.…MCHC a _PmTDIR._PB&ftWlR,_PCDftTDlR i _PEDflTDIR w jPFmi?IR fl D CTRL! ,_ftDCTHL2t JlflXCOHU #_CH S ELSEQ 1 t _CHSE LSEQ 2P _CHSEL S E Q 3._C HSEL S EQ>i AIIV n ^SFq^SR P _R ES1II Ilp.RF SUL 11 fr _RFSlJLT?」F SIULTR^RFSUI T9CHIVDER, CAMER^ CAIWcEll p [:HHICR , CAWER2?_C DNH :CR1 ,_C AHE SR f _CANESR CfiNCLC, UfiHlFH. UAHIHH . JJmMLRMNH a JUAHL AMliL由于程序设置使用 CAN 总线传输电机转速数据,故在程序中开辟了 CANIDxL 和CANIDxH 存储CAN 总线数据标识符ID 的单元),CANCTRLx 存储CAN 总线控制寄存器位单元), CANBXnA/B/C/D (存储总线传输数据单元)。

dsp电机代码

dsp电机代码

#include "DSP281x_Device.h"#include "DSP281x_Examples.h"#define LCD_DELAY_nUS(A) Delay(((((long double) A * 1000.0L) / (long double)6.666667) - 18.0L) / 14.0L)void Delay(unsigned long loopCnt);//'''''''''''''''''''''''''液晶显示值/'''''''''''''''''''''''''''''''''''''extern unsigned char number[10];extern unsigned char a,b,c,d,e, biao_zhi;unsigned char f;int NowSpd=0;long Place_now_display=0;//'''''''''''''''''''''''''''end'''''''''''''''''''''''''''''''////::::::::::::::::::::::::电机初始化变量定义:::::::::::::::::::::::::::::::::char motor_OK=1, shan_qu=0;//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;/*::::::::::::::::::::::::::速度变量值定义:::::::::::::::::::::::::::::::::::::::::::*/int temp=0, temp1=0, temp2=0;long SatErr_speed=0,OutPreSat_speed=0; //速度变量值定义long speed_now=0, Up_speed=0, speed_error=0, Ui_speed=0;long speed_set=0;//:::::::::::::::::::::::::::位置环变量定义:::::::::::::::::::::::::::long PlaceSet=0, PlaceError=0,Place_now=0, Now_P=0,//圈数OutPreSat_Place=0; //位置变量值定义unsigned char PlaceSetBit=0; //位置设定标志位//--------------------------------------------------------------------//:::::::::::::::::::::::::空间矢量变量定义:::::::::::::::::::::::::::::::::::::::::int extent_temp=0, extent_temp1=0, extent_temp2=0;//位置变量值定义unsigned int extent[14]={0x3999, 0x2999, 0x6999, 0x4999, 0x5999, 0x1999, 0x3999, 0x2999, 0x6999, 0x4999, 0x5999, 0x1999, 0x3999, 0x2999 }; //区域数组定义int extent_i=0, extent_D=0, extent_Q=0, extent_D_1=0; //扇区变量,extent_i, extent_D, extent_Q(extent_Q比extent_D超前90度//-----------------------------------extern const int sin_theta[1000];//外部SIN表extern const int cos_theta[1000];//外部cos表//cos_theta[theta]为Q15格式, ID, IQ为Q7格式1-128, Id,Iq为LONG型int t1=0, t2=0, CMPR_temp=1250, theta=0, pwm_temp=0;// turn=0;long Id=0, Iq=0, ID=0, IQ=0, Ualfa=0, Ubeta=0, x=0, y=0, z=0, temp_volue=0;//===========================电流环变量定义=========================int AD2_temp=0,Ki_Q_temp=0, Ki_D_temp=0, pwm_x=0,theta_add_60=0;long Iu=0,Iv=0, I_d=0, I_q=0, I_ref_D=0, I_ref_Q=0, I_er_Q=0,I_er_D=0, I_order_Q=0,OutPreSat_IQ=0, SatErr_IQ=0, Ui_IQ=0, Up_IQ=0,OutPreSat_ID=0, SatErr_ID=0, Ui_ID=0, Up_ID=0;//------------------------------------------------------------------// long adc_x0=0, adc_x1=0, adc_restul1=0, adc_restul0=0,adc_i=0;//===========================测试变量==============================// unsigned int TimeClash=0, timer2_x=0,timer2_x1=0, timer1_test[1000]={0},// timer2_test[1000]={0}, timer3_test[500]={0}, //timer4_test[500]={0}, // test_i=0, ICTs=0;unsigned int TimeClash=0;extern unsigned int IsrTest;//-------------------------------------------------------------------//==========================串口程式变量定义==========================int ReceiveTemp = 0, SciCommand_i=0, SciCommand_j=0, SetBit=0;int SpeedSetTemp = 0, PlaceEnable=1, SpeedSetAD=0;long PlaceSetTemp=0, SciCommand[14]={0};//--------------------------------------------------------------------////////////////外部中断初始化/////////////////////// void init_Xint1(void){EALLOW;PieCtrlRegs.PIEIER1.bit.INTx4=1; //中断允许PieCtrlRegs.PIEIFR1.bit.INTx4=0; //清除中断标志PieCtrlRegs.PIEACK.bit.ACK1=1;XIntruptRegs.XINT1CR.bit.POLARITY=1; // 上升沿触发XIntruptRegs.XINT1CR.bit.ENABLE=1;EDIS;EINT;}////////////////ADC初始化/////////////////////void init_ADC(void){//AdcRegs.ADCTRL1.bit.RESET = 1;//AdcRegs.ADCTRL1.bit.RESET = 0;AdcRegs.ADCTRL3.bit.ADCPWDN = 1;LCD_DELAY_nUS(2000);AdcRegs.ADCTRL3.bit.ADCBGRFDN = 3;LCD_DELAY_nUS(2000);AdcRegs.ADCTRL1.bit.CONT_RUN = 1; //连续运行;AdcRegs.ADCTRL1.bit.CPS = 0;AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1;AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;AdcRegs.ADCTRL3.bit.ADCCLKPS = 3; //25MHZAdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 2;AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 1;AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 2;}///////////////初始化事件管理器EVA//////////////////// void Init_Evx(void){//=======定时器3定时中断初始化====================== EALLOW;EvbRegs.T3PR=9375; //一毫秒EvbRegs.T3CON.all=0x1340; //8分频PieCtrlRegs.PIEIER4.bit.INTx4=1;//定时器3周期中断允许PieCtrlRegs.PIEIFR4.bit.INTx4=0;//清除中断标志位PieCtrlRegs.PIEACK.bit.ACK4=1;EvbRegs.EVBIMRA.bit.T3PINT=1;EvbRegs.EVBIFRA.bit.T3PINT=1;EDIS;//-------------------------------------------//========定时器1下溢中断&(svpwm)初始化====================EALLOW;EvaRegs.T1CON.all = 0x0842; //定时器1,连续增减,一分频,使能,比较使能,立即重载EvaRegs.T1PR = 1250; //30MHZ PWMEvaRegs.CMPR1 = 0; //测试用EvaRegs.CMPR2 = 0; //测试用CONA.all |= 0X9200; //使能比较操作, 使能SVPWM模式, T0下溢重载, PWM比较输出使能EvaRegs.ACTRA.all = 0X0999; //SV正转, PWM 1,3,5低有效& pWM 2,4,6高有效;// EvaRegs.EXTCONA.bit.INDCOE = 1; //独立输出比较使能// EvaRegs.GPTCONA.all |= 0x0052;EvaRegs.T1CNT = 0;EvaRegs.EVAIMRA.bit.T1UFINT = 1; //下溢中断允许EvaRegs.EVAIFRA.bit.T1UFINT = 1; //清除下溢中断标志位PieCtrlRegs.PIEIER2.bit.INTx6 = 1;//下溢中断向量允许PieCtrlRegs.PIEIFR2.bit.INTx6 = 0;//清除下溢中断标志PieCtrlRegs.PIEACK.bit.ACK2 = 1;/////////////////QEP初始化////////////////EvaRegs.T2CON.all = 0x1870;EvaRegs.T2CNT = 0x0000;EvaRegs.T2PR = 0xffff;//------------------------------------------/*////////////// EVB捕获功能初始化/////////EvbRegs.CAPCONB.bit.CAP45EN = 1; //使能捕捉单元4和5 EvbRegs.CAPCONB.bit.CAP45TSEL = 3; //44和5选择定时器3 EvbRegs.CAPCONB.bit.CAP4EDGE = 3; // 单元4上升和下降沿触发EvbRegs.CAPCONB.bit.CAP5EDGE = 3; // 单元5上升和下降沿触发EvbRegs.EVBIFRC.bit.CAP4INT = 1; //复位捕捉4标志位EvbRegs.EVBIFRC.bit.CAP5INT = 1; //复位捕捉5标志位EvbRegs.EVBIMRC.bit.CAP4INT = 1; //允许捕捉中断4 EvbRegs.EVBIMRC.bit.CAP5INT = 1; //允许捕捉中断5PieCtrlRegs.PIEIER5.bit.INTx5 = 1; //允许捕捉中断4向量PieCtrlRegs.PIEIER5.bit.INTx6 = 1; //允许捕捉中断5向量PieCtrlRegs.PIEIFR5.bit.INTx5 = 0; //清除捕捉中断4标志位PieCtrlRegs.PIEIFR5.bit.INTx6 = 0; //清除捕捉中断5标志位PieCtrlRegs.PIEACK.bit.ACK5 = 1; *///------------------------------------------EDIS;}///////////////////SCI初始化////////////////////////////////// void InitSci(void){EALLOW;//SendSciaRegs.SCICTL1.bit.SWRESET = 1;SciaRegs.SCICCR.bit.SCICHAR = 7; //取八位数据SciaRegs.SCICTL1.bit.TXENA = 1; //open send//ReceiveSciaRegs.SCICTL1.bit.RXENA = 1; //open receiveSciaRegs.SCICTL2.bit.RXBKINTENA = 1; //允许接收中断SciaRegs.SCIHBAUD = 0x01;SciaRegs.SCILBAUD = 0xE7; //9600PieCtrlRegs.PIEIER9.bit.INTx1 = 1; //允许接收中断PieCtrlRegs.PIEIFR9.bit.INTx1 = 0;PieCtrlRegs.PIEACK.bit.ACK9 = 1;///////////////功率保护中断初始化////////////////EvaRegs.EVAIMRA.bit.PDPINTA = 1; //PDPINTA中断允许EvaRegs.EVAIFRA.bit.PDPINTA = 1; //PDPINTA中断标志清零PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //PDPINTA中断允许PieCtrlRegs.PIEIFR1.bit.INTx1 = 0;PieCtrlRegs.PIEACK.bit.ACK1 = 1; //EDIS;}//-----------------------------------------------------------///////////////////电机初始化函数(位置确定)//////////////////////////// void motor_init(void){switch(GpioDataRegs.GPADAT.all & 0xE000){case 0xA000: shan_qu=0; break;case 0x2000: shan_qu=1; break;case 0x6000: shan_qu=2; break;case 0x4000: shan_qu=3; break;case 0xC000: shan_qu=4; break;case 0x8000: shan_qu=5; break;default: motor_OK = 0; break;}extent_D = 833 * shan_qu + 416 ;}//////////////////中虾 ?////////////////////////// interrupt void MY_XINT1_ISR(void);//T1捕获中断interrupt void MY_T3PINT_ISR(void);interrupt void MY_T1UFINT_ISR(void);interrupt void MY_SCI_ISR(void);interrupt void MY_PDPINDA_ISR(void);//---------------------------------------------------------void SciSendChar(unsigned char SciSendTemp);void SciSendString(unsigned char *x);void main(void)/***********************************************************************/ InitSysCtrl(); //初始化系统控制寄存器,PLL,看门狗...InitGpio(); //初始化GPIO工作模式InitPeripheralClocks(); //初始化外设时钟InitPieCtrl(); //初始化PIE寄存器InitPieVectTable(); //初始化PIE中断向量表motor_init(); //电机初始化if(motor_OK==1) //如果电机工作正常才允许使用{init_Xint1(); //初始化外部中断1init_ADC(); //初始化ADCInit_Evx(); //初始化事件管理A}Init_LCD(); //液晶初始化两次Init_LCD();InitSci();EALLOW;PieVectTable.XINT1 = &MY_XINT1_ISR; //外部中断XINT1向量地址PieVectTable.T3PINT = &MY_T3PINT_ISR; //TIMER3比较中断PieVectTable.T1UFINT = &MY_T1UFINT_ISR; //time 1 下溢中断PieVectTable.RXAINT = &MY_SCI_ISR; //SciInterruptPieVectTable.PDPINTA = &MY_PDPINDA_ISR; //PDPINDAEDIS;IER = 0x0000;IER = 0x010b; //xint1 tiufint t3pint rxaint(int1 int2 int4 int9)IFR = 0x0000;EINT; //开放全局中断/********************************************************************/while (1){if(motor_OK==1){display_a_string(0,0, "NowSpd=");display_a_string(12,0, "r/m");if(speed_now>=0){NowSpd = speed_now;display_a_char(7,0,'+');}else{NowSpd =-speed_now;display_a_char(7,0,'-');}a=NowSpd/1000;b=NowSpd%1000/100;c=NowSpd%100/10;d=NowSpd%10;display_a_char(8,0,number[a]); display_a_char(9,0,number[b]); display_a_char(10,0,number[c]); display_a_char(11,0,number[d]);display_a_string(0,1,"Now_P="); display_a_string(13,1,"r");if(Now_P>=0){Place_now_display=Now_P;display_a_char(6,1,'+');}else{Place_now_display=-Now_P;display_a_char(6,1,'-');}f=Place_now_display/100000;e=Place_now_display%100000/10000;a=Place_now_display%10000/1000;b=Place_now_display%1000/100;c=Place_now_display%100/10;d=Place_now_display%10;display_a_char(7,1,number[f]);display_a_char(8,1,number[e]);display_a_char(9,1,number[a]);display_a_char(10,1,number[b]);display_a_char(11,1,number[c]);display_a_char(12,1,number[d]);if(SetBit==0)//清除位置信号数组{for(SciCommand_j=0;SciCommand_j<14;SciCommand_j++){ SciCommand[SciCommand_j]=0; }}//////////////////返回位置完成信息///////////////////////////////////if((PlaceError<=2)&&(PlaceError>=-2)) //当脉冲数相差+-1时,速度为0{if(PlaceSetBit == 1){PlaceSetBit = 0;SciSendString("Place Ok!");}}}else{display_a_string(0,0,"Motor error! ");display_a_string(0,1,"Please check it!");}}}/////////////////外部中断1程序//////////////////////interrupt void MY_XINT1_ISR(void){if(TimeClash == 0){if(EvaRegs.GPTCONA.bit.T2STAT==1) //圈数{ Now_P++; } //正转else{ Now_P--; } //反转extent_temp2=EvaRegs.T2CNT;extent_D=0;}PieCtrlRegs.PIEACK.bit.ACK1=1;EINT;}//////////////////定时器3中断程序///////////////////// interrupt void MY_T3PINT_ISR(void){EvbRegs.T3CNT=0; //从载计数器值EVBtemp1 = EvaRegs.T2CNT;if((temp1-temp2)>=50000){temp=65536-temp1+temp2;Place_now-=temp;temp = -temp;}//电机(反转)过峰值else if((temp2-temp1)>=50000){temp=65536-temp2+temp1;Place_now+=temp; //电机(正转)过峰值}else if(temp1 >= temp2){ temp=temp1-temp2; Place_now+=temp; }//电机(正转)else{temp=temp2-temp1;Place_now-=temp; //电机(反转)temp = -temp;}temp2 = temp1;speed_now = 6*temp;//==================位置环PI控制======================if(PlaceEnable ==1){PlaceError = PlaceSet - Place_now;OutPreSat_Place = PlaceError;if((PlaceError<=10000)&&(PlaceError>=-10000)){OutPreSat_Place = PlaceError/3;}{ if (OutPreSat_Place> 2000)speed_set = 2000;else if (OutPreSat_Place< -2000)speed_set = -2000;elsespeed_set = OutPreSat_Place;}}//----------------- 位置环PI控制结束------------------//******************************************************************* if(SpeedSetAD==1){AD2_temp=AdcRegs.ADCRESULT2>>4;speed_set = AD2_temp-2048;}//********************************************************************//================速度环PI控制====================== speed_error = speed_set - speed_now;Up_speed = 10*speed_error; //25Ui_speed = Ui_speed + 32*Up_speed/100 + 1*SatErr_speed;OutPreSat_speed = Up_speed + Ui_speed ;{if (OutPreSat_speed > 1600)I_order_Q = 1600;else if (OutPreSat_speed < -1600)I_order_Q = -1600;elseI_order_Q = OutPreSat_speed;}SatErr_speed = I_order_Q - OutPreSat_speed;//----------------- 速度环PI控制结束------------------/*{//测试用if((GpioDataRegs.GPADAT.bit.GPIOA12 == 0)&&(timer2_x1==0)) { timer2_x1=1; }if(timer2_x1==1){timer1_test[timer2_x] = speed_set;timer2_test[timer2_x] = speed_now;timer3_test[timer2_x] = Place_now;// timer4_test[timer2_x] = speed_set;timer2_x++;if(timer2_x>=500){ timer2_x=500; }}}//测试用*/PieCtrlRegs.PIEACK.bit.ACK4=1;EvbRegs.EVBIMRA.bit.T3PINT=1;EvbRegs.EVBIFRA.bit.T3PINT=1;EINT;}//////////////////定时器1下溢中断//////////////////////interrupt void MY_T1UFINT_ISR(void){pwm_x++;//>>>>>>>>>>>>>>>>>>>>直轴位置确定>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>{ //位置范?extent_temp1=EvaRegs.T2CNT;if((extent_temp1-extent_temp2)>=50000) //电机反转{ extent_temp= 65536 - extent_temp1 + extent_temp2; extent_D-= extent_temp; }else if((extent_temp2-extent_temp1)>=50000) //电机正传{ extent_temp= 65536 - extent_temp2 + extent_temp1; extent_D+= extent_temp; }else if(extent_temp1 >= extent_temp2) //电机正传{ extent_temp= extent_temp1 - extent_temp2; extent_D+= extent_temp; }else //电机反转{ extent_temp= extent_temp2 - extent_temp1; extent_D-= extent_temp; }extent_temp2= extent_temp1;} //位置确定if(extent_D < 0){ extent_D = 10000 + extent_D; }//保证extent_D不超过10000if(extent_D >= 10000){ extent_D = extent_D - 10000; }//####################### 计算电机角度THETA###########################extent_D_1 = extent_D + 105; //加105是为了补偿电机脉冲平均误差,电机脉冲为105if(extent_D_1 >= 10000){ extent_D_1 = extent_D_1 - 10000; }//交轴值由10000减去现值theta = extent_D_1/10; //现在电机D轴的位置if(pwm_x==3) //加入电流环{pwm_x=0;theta_add_60 = theta + 83; //加83为了对应电机的相位+60度(电流环专用)if(theta_add_60 >= 1000){ theta_add_60 = theta_add_60 - 1000; }if(theta_add_60 < 0){ theta_add_60 = theta_add_60 + 1000; }//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>//======================读取电流值,CLARKE和Park变换作电流反馈之用========================================Iu = AdcRegs.ADCRESULT0>>4;Iu = Iu - 1831; //读取U相的电流值1845 |Iv = AdcRegs.ADCRESULT1>>4;Iv = Iv - 1833; //读取V相电流值1853 | 电流CLARKE变换I_d = Iu;I_q = ((2*Iv + Iu)*18919)>>15; //其中式为(2*Ib+Id)*1.732/3 |I_ref_D = ( I_d*cos_theta[theta_add_60] + I_q*sin_theta[theta_add_60])>>15; //|电流Park变换I_ref_Q = (-I_d*sin_theta[theta_add_60] + I_q*cos_theta[theta_add_60])>>15; //|//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++//==========================电流环的Q轴PI控制=======================================//I_er_Q = I_order_Q - I_ref_Q;Up_IQ = 9*I_er_Q/10; //35*I_er_Q/10Ui_IQ = Ui_IQ + 1*Up_IQ/10 + 1*SatErr_IQ/10;OutPreSat_IQ = Up_IQ + Ui_IQ ;if (OutPreSat_IQ > 1023)IQ = 1023;else if (OutPreSat_IQ < -1023)IQ = -1023;elseIQ = OutPreSat_IQ;SatErr_IQ = IQ - OutPreSat_IQ;//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++//==========================电流环的D轴PI控制=======================================//I_er_D = 0 - I_ref_D;Up_ID = 9*I_er_D/10;Ui_ID = Ui_ID + 1*Up_ID/10 + 1*SatErr_ID/10;OutPreSat_ID = Up_ID + Ui_ID ;if (OutPreSat_ID > 500)ID = 500;else if (OutPreSat_ID < -500)ID = -500;elseID = OutPreSat_ID;SatErr_ID = ID - OutPreSat_ID;//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++}//电流环计算结束if((speed_set==0)&&(speed_error==0)&&(PlaceSetBit == 0)) //防止电机静止时的噪声{ IQ=0; ID=0; }//********SVPWM控制---相当于直流电机的PWM控制(最大值1023 最小值-1023; 正值正转,负值反转*****if(IQ>=0)//当MOTOR正转时{/* Id=ID*cos(sita)-IQ*sin(sita);Iq=ID*sin(sita)+IQ*cos(sita);Ualfa=Id; Ubeta=Iq;x=Ubeta;y=(1.732051*Ualfa+Ubeta)/2;z=(-1.732051*Ualfa+Ubeta)/2;*///cos_theta[theta]为Q15格式, ID, IQ为Q7格式1-128, Id,Iq为LONG型Id=ID*cos_theta[theta] - IQ*sin_theta[theta]; /*逆PARK变换*/Iq=ID*sin_theta[theta] + IQ*cos_theta[theta];Ualfa=Id>>10;Ubeta=Iq>>10; //Ualfa & Ubeta type is longtemp_volue=(56756 * Ualfa)>>15;//==1.732051*Ualfax=Ubeta;y=(temp_volue + Ubeta)>>1; //除远?移一位z=(-temp_volue + Ubeta)>>1;extent_Q = extent_D_1 + 1250; //交轴值由10000减去现值{//+++if(extent_Q >= 10000){extent_Q = extent_Q - 10000; //如果实际交轴的值超过了要减去10000}if(extent_Q < 0){extent_Q = extent_Q + 10000;}} //---extent_i = extent_Q / 833; //实际交轴的角度if(extent_i > 11){ extent_i = 11; }EvaRegs.ACTRA.all=extent[extent_i]; //把扇区位置写入PWM控制寄存器switch(extent_i){case 0:{t1=(-z*CMPR_temp)>>15; t2=(x*CMPR_temp)>>15; break; }case 1:{ t1=(y*CMPR_temp)>>15; t2=(z*CMPR_temp)>>15; break; }case 2:{ t1=(x*CMPR_temp)>>15; t2=(-y*CMPR_temp)>>15; break; }case 3:{t1=(z*CMPR_temp)>>15; t2=(-x*CMPR_temp)>>15; break; }case 4:{t1=(-y*CMPR_temp)>>15; t2=(-z*CMPR_temp)>>15; break; }case 5:{ t1=(-x*CMPR_temp)>>15; t2=(y*CMPR_temp)>>15; break; }//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++case 6:{t1=(-z*CMPR_temp)>>15; t2=(x*CMPR_temp)>>15; break; }case 7:{ t1=(y*CMPR_temp)>>15; t2=(z*CMPR_temp)>>15; break; } case 8:{ t1=(x*CMPR_temp)>>15; t2=(-y*CMPR_temp)>>15; break; } case 9:{t1=(z*CMPR_temp)>>15; t2=(-x*CMPR_temp)>>15; break; } case 10:{t1=(-y*CMPR_temp)>>15; t2=(-z*CMPR_temp)>>15; break; } case 11:{ t1=(-x*CMPR_temp)>>15; t2=(y*CMPR_temp)>>15; break; } default:break;}if(t1<0){ t1=0;}if(t2<0){ t2=0;}EvaRegs.CMPR1=t1;EvaRegs.CMPR2=t1+t2;}//+++++++++++++++++反向旋转+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(IQ<0)//当MOTOR反转时{//cos_theta[theta]为Q15格式, ID, IQ为Q7格式-1023-1023, Id,Iq为LONG型Id=ID*cos_theta[theta] - IQ*sin_theta[theta]; //逆PARK变换Iq=ID*sin_theta[theta] + IQ*cos_theta[theta];Ualfa=Id>>10;Ubeta=Iq>>10; //Ualfa & Ubeta type is longtemp_volue=(56756 * Ualfa)>>15;//==1.732051*Ualfax=Ubeta;y=(temp_volue + Ubeta)>>1; //除以二,移一位z=(-temp_volue + Ubeta)>>1;extent_Q= extent_D_1 - 1250; //交轴值=直轴-1250 减90度if(extent_Q<0){extent_Q=extent_Q+10000;}extent_i=extent_Q/833; //实际交轴的角度EvaRegs.ACTRA.all=extent[extent_i+1]|0x8000; //反向旋转SVDIR=1; 扇区数组值比正转超前一个扇区switch(extent_i){case 0:{t1=(x*CMPR_temp)>>15; t2=(-z*CMPR_temp)>>15; break; }case 1:{ t1=(z*CMPR_temp)>>15; t2=(y*CMPR_temp)>>15; break; }case 2:{ t1=(-y*CMPR_temp)>>15; t2=(x*CMPR_temp)>>15; break; }case 3:{t1=(-x*CMPR_temp)>>15; t2=(z*CMPR_temp)>>15; break; }case 4:{t1=(-z*CMPR_temp)>>15; t2=(-y*CMPR_temp)>>15; break; }case 5:{ t1=(y*CMPR_temp)>>15; t2=(-x*CMPR_temp)>>15; break; }//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++case 6:{t1=(x*CMPR_temp)>>15; t2=(-z*CMPR_temp)>>15; break; } case 7:{ t1=(z*CMPR_temp)>>15; t2=(y*CMPR_temp)>>15; break; } case 8:{ t1=(-y*CMPR_temp)>>15; t2=(x*CMPR_temp)>>15; break; } case 9:{t1=(-x*CMPR_temp)>>15; t2=(z*CMPR_temp)>>15; break; } case 10:{t1=(-z*CMPR_temp)>>15; t2=(-y*CMPR_temp)>>15; break; } case 11:{ t1=(y*CMPR_temp)>>15; t2=(-x*CMPR_temp)>>15; break; } default:break;}if(t1<0){ t1=0;}if(t2<0){ t2=0;}EvaRegs.CMPR1=t1;EvaRegs.CMPR2=t1+t2;}// TimeClash = 0; //防止外部中断与之冲突EvaRegs.EVAIMRA.bit.T1UFINT = 1; //下溢中断允许EvaRegs.EVAIFRA.bit.T1UFINT = 1; //清除下溢中断标志位PieCtrlRegs.PIEACK.bit.ACK2 = 1;EINT;}//---------------------------------------------------------///////////////////////接收中断/////////////////////////// interrupt void MY_SCI_ISR(void){ReceiveTemp = SciaRegs.SCIRXBUF.bit.RXDT;if(ReceiveTemp=='S')//S{ SetBit=1; }if(( SetBit==1)&&(ReceiveTemp!='S')){SciCommand[SciCommand_i] = ReceiveTemp;SciCommand_i++;}if(ReceiveTemp=='Y') //Y{if((SciCommand[0]=='P')&&(PlaceSetBit == 0)) //P{PlaceSetTemp = (SciCommand[2]-48)*1000000000 + (SciCommand[3]-48)*100000000+ (SciCommand[4]-48)*10000000 + (SciCommand[5]-48)*1000000+ (SciCommand[6]-48)*100000 +(SciCommand[7]-48)*10000+ (SciCommand[8]-48)*1000 + (SciCommand[9]-48)*100+ (SciCommand[10]-48)*10 + (SciCommand[11]-48);if( SciCommand[1] == '+')//+{ PlaceSet = PlaceSetTemp; }if( SciCommand[1] == '-')//-{ PlaceSet = -PlaceSetTemp; }SetBit = 0;SciCommand_i=0;PlaceSetBit = 1;}if(SciCommand[0]=='V')//V速度设置{PlaceEnable = 0; //禁止位置环if(SciCommand[1]=='B')//BUS B{SpeedSetTemp = (SciCommand[3]-48)*1000 + (SciCommand[4]-48)*100+(SciCommand[5]-48)*10 + (SciCommand[6]-48);if( SciCommand[2] == '+')//+{ speed_set= SpeedSetTemp; }if( SciCommand[2] == '-')//-{ speed_set= -SpeedSetTemp; }SpeedSetAD = 0; //禁止速度设置FOR AD}if(SciCommand[1]=='A')//ADC A{SpeedSetAD = 1; //允许AD转换FOR AD}SetBit = 0;SciCommand_i=0;}}PieCtrlRegs.PIEACK.bit.ACK9 = 1;}//--------------------------------------------------------//////////////////////功率保护中断///////////////////////// interrupt void MY_PDPINDA_ISR(void){motor_OK = 0;EvaRegs.EVAIFRA.bit.PDPINTA = 1;PieCtrlRegs.PIEACK.bit.ACK1 = 1; //}//*****************函数程式***************************//=========SciSendChar===========void SciSendChar(unsigned char SciSendTemp){while(!SciaRegs.SCICTL2.bit.TXRDY){;}SciaRegs.SCITXBUF = SciSendTemp;}//_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-//===================SciSendString====================void SciSendString(unsigned char *x) {while(*x){SciSendChar(*x);x++;}}//----------------------------------------------------。

东方电机控制器DSP说明书

东方电机控制器DSP说明书

东方电机控制器DSP说明书
1、按住“增加键”不放,“运行灯”闪烁,同时门体向开门方向运行(此时,门体必须向开门方向运行,如果向关门方向运行,请调换电机线),达到上限位以后松开“增加键”(此时可通过“增加键”和“减小键”进行微调),按住“设置键”不放,确认当前的位置为上限位,“运行灯”闪烁后熄灭,“状态灯”直亮,松开“设置键”,进入下限位学习状态。

2、按住“减小键”不放,“状态灯”闪烁,同时门体向关门方向运行,到达下限位后松开“减小键”(此时可通过“增加键”和“减小键”进行微调),按“设置键”不放,确认当前位置为下限位,“状态灯”闪烁后熄灭,松开“设置键”,下限位学习结束。

设计和实现基于DSP的电机速度控制系统

设计和实现基于DSP的电机速度控制系统

设计和实现基于DSP的电机速度控制系统电机速度控制系统是工业自动化中常见的控制系统之一,它广泛应用于各种设备和机械,如电机驱动器、机械传动系统、搅拌设备等。

本文将围绕任务名称,为您介绍设计和实现基于数字信号处理器(DSP)的电机速度控制系统的相关内容。

一、引言电机速度控制系统是通过对电机的驱动信号进行控制,实现对电机速度的精确控制。

传统的电机速度控制系统采用模拟控制方法,但其性能受到模拟元件的精确度、稳定性和可靠性的限制。

而采用DSP作为控制核心的电机速度控制系统,能够充分发挥数字信号处理和计算能力,提高控制精度和响应速度,并具有更好的稳定性和可靠性。

二、系统设计1. 系统框图基于DSP的电机速度控制系统通常包括传感器模块、DSP核心模块、电机驱动模块和通信接口模块。

传感器模块用于实时采集电机速度信号,DSP核心模块实现控制算法和运算处理,电机驱动模块将DSP生成的驱动信号转换为电机控制信号,通信接口模块用于与上位机或其他外部设备进行通信。

2. 算法设计速度控制算法是电机速度控制系统的核心部分,常用的算法包括比例积分微分(PID)控制算法、模糊控制算法、自适应控制算法等。

在设计算法时,需要考虑电机的特性参数,如转动惯量、摩擦因数等,根据实际需求选择合适的算法并进行参数调整,以实现对电机速度的精确控制。

3. 硬件选型选择合适的DSP芯片和外围模块是电机速度控制系统设计的重要环节。

在选型时,需要考虑DSP的计算能力、接口类型和开发环境,同时也要结合电机的需求和控制算法的特点,选择合适的外围模块,如运算放大器、模数转换器、PWM 模块等。

三、系统实现1. 硬件连接将传感器模块与DSP核心模块进行连接,通过采用合适的传感器(如光电编码器、磁编码器等)实时采集电机速度信号,并将信号传输给DSP核心模块进行处理。

同时,将DSP核心模块与电机驱动模块进行连接,将经过算法处理后的驱动信号转换为电机控制信号,驱动电机实现速度控制。

DSP电机控制PMSM

DSP电机控制PMSM

#include "DSP28_Device.h"EVA eva = EVA_DEFAULTS;EVB evb = EVB_DEFAULTS;RAMPGEN rampgen = RAMPGEN_DEFAULTS;VHZPROF vhzprof = VHZPROF_DEFAULTS;SVGENDQ svgendq = SVGENDQ_DEFAULTS;ROTATEVECTOR rotatevector = ROTATEVECTOR_DEFAULTS;static unsigned int RBBuf;static unsigned int RABuf;interrupt void ISRTimer1(void);interrupt void ISRTimer2(void);interrupt void T1UFINT_ISR(void);long f_given=0;long f_now=0;float happy=0;//显示相关unsigned int f_given_disp=0; //接到的的值unsigned int ku=10; //输入电压与电机额定电压的比unsigned int DispBuf[2]; //显示缓存,存在EEPROM,(ku,f_given) unsigned int RunFlag=0; //运行标志unsigned int TurnFlag=0; //正反转//_iq ha = 65545;//_iq hb = 65521;//_iq hc ;void ShowDisp(void); //显示函数,用于将数据显示到显示板_iq test1[20];_iq test2[20];void main(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; // This is needed to write to EALLOW protected registersPieVectTable.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; // This is needed to disable write to EALLOW protected registers/*使能位于PIE中组2的第6个中断定时器1下溢中断*/PieCtrl.PIEIER2.bit.INTx6=1;/*开中断*/IER |= M_INT2; //EVAIER |= M_INT9; //SCI //允许串口中断IER |= M_INT14; //cputimer2IER |= M_INT13; //cputimer1EINT; // Enable Global interrupt INTMERTM; // Enable Global realtime interrupt DBGMeva.Close(&eva);evb.Open(&evb);rampgen.StepAngleMax = _IQ(0.0128); //最大频率128hz 中断频率10kwhile(1){// hc= _IQmpy(ha,hb);只进行保留整数位,对于小数位不进行四舍五入。

基于Matlab的永磁同步电机DSP控制系统开发

基于Matlab的永磁同步电机DSP控制系统开发

基于Matlab的永磁同步电机DSP控制系统开发摘要本文以基于DSP平台的永磁同步电机(PMSM)矢量控制系统为工程实例,给出了控制系统从建模仿真到DSP程序代码自动生成的设计流程。

关键词Matlab;DSP;代码自动生成;永磁同步电机;矢量控制0 引言Matlab具有强大的分析、计算和可视化功能,被广泛用于控制系统的数学建模仿真、方案验证。

开发人员设计一个控制系统,一般先用Matlab对系统的控制算法进行数学建模仿真,方案通过验证后才进行DSP系统的硬件设计及代码开发,并通过对比实际系统和仿真模型的输出,完善系统的设计。

1 基于Matlab的DSP控制系统开发流程基于Matlab的DSP控制系统开发流程如下,开发人员根据概念设计在Matlab平台下利用Simulink、SimPowerSystems及C2000lib工具箱中的模型搭建系统仿真模型,仿真验证后通过Matlab的Real Time Workshop生成面向TI编译器的工程文件(.prj),并进一步完成代码的编译,链接生成DSP可执行机器码(.out)并下载到目标DSP板,完成系统的开发。

2 永磁同步电机矢量控制算法设计矢量控制算法完成三相坐标系到两相同步旋转坐标系的变换及其逆变换,实现永磁同步电动机的解耦控制。

3 控制系统的实现3.1 基于Matlab/Simulink的系统级仿真模型建模及仿真本文根据系统控制算法,基于Matlab搭建了基于磁场定向的PMSM空间矢量控制系统仿真模型,该仿真模型包括仿真模块和嵌入式系统模块两部分。

3.1.1 仿真模块设计1)相电流模数转换子模块将永磁同步电机模型输出的相电流值转换成DSP ADC寄存器的数据格式,模拟DSP ADC外设的数据采集工作模式。

换算公式见式1.1。

ADC_sim=isa,b×50+2048(式1.1)2)编码器子模块模拟DSP EV A事件管理器正交编码脉冲QEP电路的解码和计数工作模式。

DSP的PWM电机控制程序代码分析

DSP的PWM电机控制程序代码分析

中南大学DSP原理及应用课程代码分析报告报告题目:DSP的PWM电机控制程序代码分析学院:信息科学与工程学院专业班级:电气0804姓名:邓添轶学号:0909082203指导老师:刘建成目录1. 基本原理2. 数据存储空间(汇编源程序)、头文件和变量声明(C源程序)分析3. 算法分析与流程图4. 总结1. 基本原理1. 每个240X 器件都包含两个事件管理模块EV A 和EVB ,每个时间管理器模块包括通用定时器、比较单元、捕获单元,以及正交编码脉冲电路。

2. 直流电机控制:直流电动机是最早出现的电动机,也是最早能实现调速的电动机。

近年来,直流电动机的结构和控制方法都发生了很大的变化。

随着计算机进入控制领域,以及新型的电力电子功率元器件的不断出现,使采用全控型的开关功率元件进行脉宽调制(PWM )控制方式已成为绝对主流。

PWM 调压调速原理:直流电动机转速n 的表达式为:φK IRU n -=其中,U 为电枢端电压;I 为电枢电流;R 为电枢电路总电阻;φ为每级磁通量;K 为电动机结构参数。

所以直流电机的转速控制方法可分为两类:对励磁通进行控制的励磁控制法和对电枢电压进行控制的电枢控制法。

其中励磁控制法在低速时受磁极饱和的限制,在高速时受换向火花和换向器结构强度的限制,并且励磁线圈电感较大,动态响应较差,所以这种控制方法用得很少。

现在,大多数应用场合都使用电枢控制法。

绝大多数电流电机采用开关驱动方法。

开关驱动方式是使半导体功率器件工作在开关状态,通过脉宽调制PWM 来控制电动机电枢电压,实现调速。

具体电路如下图。

2. 数据存储空间(汇编源程序)、头文件和变量声明(C源程序)分析在此程序中定义了如下变量(C源程序)在此程序中定义如下数据空间(汇编程序):由于程序设置使用CAN总线传输电机转速数据,故在程序中开辟了CANIDxL和CANIDxH(存储CAN总线数据标识符ID的单元),CANCTRLx(存储CAN总线控制寄存器位单元) ,CANBXnA/B/C/D(存储总线传输数据单元)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

电机控制DSP编程
软件的层次化:
高级语言框架:仿真和实现可用同样的代码
(若程序不很复杂以及熟悉汇编,用宏汇编建立框架也可):
通用算法模块:模块封装,接口清晰
专用算法模块:PWM,电机模型
硬件环境封装:中断,端口,控制寄存器,存储器地址。

端口操作封装便于移植和检查。

不要直接对外设寄存器进行读写,最好建立接口程序,使算法部分与硬件独立。

中断结构:
主循环和中断的方式就是多线程的程序。

中断有定时中断、故障中断和通讯中断等。

可以多个定时中断实现多采样率的控制。

将复位看成是一种不可屏蔽中断,每次复位后指令都从同一地点开始执行,但是运行环境会有所不同,完全掉电除外。

后台计算,前台计算:有的模块可能只需具备几个部分,但是可以这样看。

后台程序可以用高级语言编写,前台程序用汇编语言编写。

注意:不要使前台程序时间超出,要以可能最长的执行时间计算,而且还要给后台程序留有一定的时间。

代码组织:
将每个程序模块都分为几个部分:常量定义,变量定义,初始化,执行部分(前台部分和后台部分)。

有条理的代码组织使得程序维护:填加模块、删除模块、修改模块变得有按部就班有法可依。

程序描述方法
流程图:另外一种语言的程序实现
结构图:框图为执行的操作,连线为传递的变量参数。

程序实现容易。

状态机:连线为状态转换的方向并标注转换条件,框图为可能的几种状态。

结构图举例:滞洄比较器,开方器,多路开关
Ctrl
存储器的规划:
数据存储器:两种片内RAM ,SARAM ,DARAM ,可以同时读写。

外部存储器一般要
加等待周期。

临时变量:scratch registers ,特点,在一个线程开始其值不固定,退出时也不固定。

全局变量:虽然不建议使用,但在电机控制程序中,可以在程序模块保持独立的情况下采用少量全局变量:输出电流,电压,给定转速等。

局部专用变量:可以保留中间计算结果或预先计算的结果,还可以用于调试。

永久全局变量:初始化一次,以后只读,方便编程。

常数和表头。

临时变量和专用变量的权衡:空间和时间存在矛盾,资源占用和调试方便的矛盾。

采用临时变量可以少占用数据存储器,用专用变量可以保留中间计算结果或预先计算的结果,可以节省时间。

数据存储器容量的计算:临时变量,全局变量和专用变量,还可能有堆栈变量。

如果数据存储器紧张,可以考虑数据区特殊的利用方法。

存储器的安置:常用的变量如临时变量,固定全局变量放在最快DARAM 中。

可重入性和可重用性:
可重入性的方法:只修改堆栈变量和专用临时变量;对全局变量和静态变量只读;不用自修改代码的程序。

子程序不必设计成带堆栈的可重入形式,可以为不同的程序端(主程序,中断)编制多个相同的子程序,针对性的子程序。

这也不占用很多空间。

而且省下了重入保护现场的时间和程序空间。

在C语言中为程序模块建立一个struct,其成员为传递的参数(输入及输出)。

可以使调用更加简洁。

用指针引用,可以重入。

TI不推荐使用“hard-coded” data memory locations,要求可重定位,实际上,我们通过辅助编辑软件可以协助重定位,防止遗漏和重复。

我们利用固定位置的变量和SCOPE进行在线调试。

宏的采用可以帮助我们解决重定位的问题。

F2xx系列的特殊考虑:如果采用直接寻址,有DP切换的问题,可以在常用DP设置专门的临时变量。

另外还有DP自适应和DP切换的方法。

程序的可重定位并可固化(ROM-able)特性:主要取决于直接寻址的DP的处理。

可以让程序模块中的变量用一个DP的变量,并且在调用前设置正确的DP.
没有用C的原因:
熟悉了汇编
汇编的常用指令也没有几条
程序结构不复杂
总是要和硬件打交道
编程效率高
位操作和定点运算为主
汇编有宏和子程序的使用也可以避免错误
编程标准
建立编程标准的好处:便于合作者代码集成;编写的模块具有通用性;便于调试;可以只对客户提供二进制文件;可以部分编译。

目前的标准:目前虽然没有统一的标准,但是我们要了解编程方面好的常规,在没有按照常规的方法要将接口描写清楚,站在前人的基础上。

命名的标准:
编程前先想好变量定义和程序实现所需的各个模块的名称和接口定义。

模块的命名:“<module>_<vendor>_ [A-Z0-9]”。

类似地,前后缀的约定和规范应该提前明确规定。

模块内部变量的名字的定义并不重要,关键是接口用到的那些外部变量和符号。

为便于名称意义的判断,在组合词中间不要加“_”,例如currentScale中间,最好用大写开头。

命名规则举例:
变量全部小写(前缀后缀除外);
常量全部大写(或加后缀“_k”);
定标值皆加后缀“_sh”
一个32位变量低字“_l”
IO空间地址的定义后面都加“_p”
编译器的利用
宏和子程序的选择和相互使用:宏可以简化子程序参数传递的形式,各子程序的相同部分可以用宏来实现。

常量的计算:DP值(ldp #uab<<7)
宏的使用:简单而实用的宏:sdp,SBIT0,SBIT1等
文件的包含要注意用条件编译防止多次包含的发生。

程序的优化
1)程序优化和可维护性的权衡。

举例说:一个程序将执行时间优化10%很难,而CPU的
时钟速度增加的很快。

程序的优化可以使程序变得难读,接口变得复杂,模块化会被打乱。

2)时间和空间的矛盾:
3)程序的优化的原则:程序太精简使可维护性变差,优化可以但是要单向进行即调试版本
和发行版本;建议模块优化。

4)执行时间优化方法:sdp的使用提高可重用性;顺序执行保证流水线连续;如何利用
复合指令优化程序(LTP,LTS和LTA,APAC和SPAC,MPYS和MPYA)。

5)运行环境:在中断中一般要保护现场,保证中断退出时对现场还原,但是在中断进入时
的需要的环境要进行设置。

有一个办法可以节省时间,按照常用的环境建立一个默认的环境,在主程序和每个中断开始设置这一环境,每个程序模块需要的环境与此不同时进行设置,模块退出时还原,这样在每个功能模块中就可以认为在这个默认的环境中,由于大多数模块使用默认环境,不需重新设置。

例如:PM,OVM,SXM在缺省状态下都是
1。

6)溢出防止:在用sach dma,shift实现右移(先左移shift位),SXM不起作用,而且左移
过程中OVM也不起作用。

因此要注意溢出发生。

7)饱和抑制:
setc ovm
lacc reference,16
sub feedback,16
sach error
具有饱和限制的左移: norm * ;
8)所有变量的初始状态为0,除非特别加以赋值,初始化变得简单,没有初始化程序会缺乏
可重复性。

9)四舌五入:F240定点运行的截尾误差对于正负数都是产生一个负向的偏移,而不是绝
对值的减小。

主要用于除法和结尾。

相关文档
最新文档