⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vhz_wx.c

📁 f2407:电机控制
💻 C
字号:
#include "f2407_c.h"
#include "cursample.h"
#include "freq_theta.h"
#include "polar_rect_c.h"
#include "qep.h"
#include "scopead.h" 
#include "sincos.h"
#include "softsvpwm_c.h"
#include "volt_freq_c.h"
#include "var_vhz_wx.c"
#include "init_vhz_wx.c"
#include "int_vhz_wx.c"   
                                 
unsigned	int	ave_adresult=0,adresult[4]={0,0,0,0},sz1=0;   
unsigned	int	handflag=0;
unsigned	int	handstart=0,handstop=0;
unsigned	int	autoflag=0;
unsigned	int	autostart=0,autostop=0,autostart1=0;   
unsigned	int	iovalue[3]={0,0,0},lastiovalue=0,sz=0;

unsigned	int	speed_ref=0;    //保存接收到的转速显示器速度给定  
unsigned	int	speed_rec_flag=0,time_rec_flag=0;

void 	variable_init(void);
void 	kickdog(void);  
void 	clearipm(void); 
void	mailbox0rec(void);
void	mailbox1rec(void); 
void	mailbox2rec(void);  
void 	mailbox3send(void);  

void	read_io(void); 
void	stop(void);


main()
{	sysinit();
	wdinit();
	variable_init();
	qepinit(); 
	caninit();
	mailbox2_init();
	mailbox3_init();
	mailbox0_init();
	mailbox1_init();
	pdpinit();
	pwminit(); 
	adinit();  
	ioinit();
    kickdog(); 	
   
	asm(" CLRC INTM");
	for(;;)
	{	
      /////////////////////////////////2005-11-8///////////
	 if(flagspeedchang==1)
	 {
	  flagspeedchang=0;
	  if(freq_ref_out.freq_ref_max-freq_ref_out.freq_ref!=0) //如果发生了频率更新,则执行以下的操作
      {
		 if(freq_ref_out.freq_ref_max>freq_ref_out.freq_ref) //如果更新后的频率大于原来的参考频率,则执行下面的操作
		 {
           freq_ref_out.freq_ref=freq_ref_out.freq_ref+freq_ref_slope_out.freq_ref_slope;
		   if(freq_ref_out.freq_ref>freq_ref_out.freq_ref_max)
			  freq_ref_out.freq_ref=freq_ref_out.freq_ref_max;
		   if(freq_ref_out.freq_ref<frequence_min)	
			  freq_ref_out.freq_ref=frequence_min; 	
		 }
		 if(freq_ref_out.freq_ref_max<freq_ref_out.freq_ref) //如果更新后的频率小于原来的参考频率,则执行下面的操作
		 {
           freq_ref_out.freq_ref=freq_ref_out.freq_ref-freq_ref_slope_out.freq_ref_slope;
		   if(freq_ref_out.freq_ref<freq_ref_out.freq_ref_max)
			  freq_ref_out.freq_ref=freq_ref_out.freq_ref_max; 	
           if(freq_ref_out.freq_ref<frequence_min)  //如果更新后的频率小于最小频率,则取最小值
		      freq_ref_out.freq_ref=frequence_min;     	
		 }
		           
	   } 
     }
     ////////////////////////////////////////		
	 //	if(ipmfault==1)	clearipm();       //如果有错误信号,则清除 
	 	mailbox0rec();                            
	 	mailbox1rec();                              
	 	mailbox2rec();
	 	mailbox3send();
		if(soft_timer.key_timer>=30)       //3ms读一次按键,读3次,相同则有效
		{                                                       
		    soft_timer.key_timer=0;
			read_io();
		}  
		if(handflag==1)	
		{
			if((handstart==1)&&(handstop==0))
			{ 
				
			    flagflag=1;
				ave_adresult=(adresult[0]+adresult[1]+adresult[2]+adresult[3])>>2;      //取AD采样的平均值,并右移6位
	        //此处AD的最大值对应300Hz,对应Q16格式的0xffff;  
				freq_ref_out.freq_ref_max=ave_adresult*64;     //(ave_adresult*0xffff)/1024;   //注意此处为Q16格式,基值为300Hz
				
			    if(freq_ref_out.freq_ref_max<frequence_min)	
					freq_ref_out.freq_ref_max=frequence_min;
				if((*ACTRB&0x0fff)!=0x999 )
				    *ACTRB=(*ACTRB&0xF000)|0x999;	//PWM8,10,12 active high,PWM7,9,11 active low
             }
             else
             {
             	
             	stop();
			 }	
		}
		if(autoflag==1)
		{ 
	    	if((autostart==1)&&(autostop==0)&&(autostart1==1))
			{
				flagflag=1;
                fspeed=(float)speed_ref;
//			 	freq_ref_out.freq_ref_max=(int)(fspeed*728/100);     // 7.28 P=2 speed_ref为接收的转速显示器给定转速(speed_ref*p/60)*2^16/300
//			 	freq_ref_out.freq_ref_max=(int)(fspeed*1092/100);     // 10.92 P=3 speed_ref为接收的转速显示器给定转速(speed_ref*p/60)*2^16/300
			 	freq_ref_out.freq_ref_max=(int)(fspeed*364/100);      // 3.64 虎溪 P=1 speed_ref为接收的转速显示器给定转速(speed_ref*p/60)*2^16/300
			    if(freq_ref_out.freq_ref_max<frequence_min)	
					freq_ref_out.freq_ref_max=frequence_min;				
				if((*ACTRB&0x0fff)!=0x999 )
					*ACTRB=(*ACTRB&0xF000)|0x999;			//PWM8,10,12 active high,PWM7,9,11 active low
             }   
             else
             {
            	stop();
			 }  
		}
		if((handflag==0)&&(autoflag==0))
        {
            stop();
		    if(ipmfault==1)	clearipm();       //如果有错误信号,则清除 
		}	

		kickdog();
	}
}

void kickdog(void)  
{	
    *WDKEY=0x5555;    
	*WDKEY=0xAAAA;
} 

void variable_init(void)
{	

	freq_theta_out.ktheta=k_theta;
	freq_theta_out.theta=0;
	polar_rect_out.ualfa=0;
	polar_rect_out.ubeta=0;
	sincos_out.inv_step=sincos_inv_step;
	sincos_out.k_cosx=sincos_k_cos;
	sincos_out.sinx=0;
	sincos_out.cosx=0;             
//	svpwm_out.Vdcinvt=0x608;      // 刘和平 T_pwm*线电压峰值/直流母线电压=0x609;  T_pwm=2000;          
	svpwm_out.Vdcinvt=T_pwm;      // 2000*380*1.414/537 ;2000对应10KHZ
	svpwm_out.PWMPRD=T_pwm;
	svpwm_out.va=0;
	svpwm_out.vb=0;
	svpwm_out.vc=0;
	vhz_volt_out.slope=vHz_slope_init;
	vhz_volt_out.uout=0;
	freq_ref_out.freq_ref_max=frequence_min; 
	freq_ref_out.freq_ref=frequence_min;
    freq_ref_slope_out.freq_ref_slope=0x01; 
	soft_timer.timer=0;
	soft_timer.speed_timer=0; 
	soft_timer.key_timer=0;
}



////////////////////清IPM模块错误信号程序
void clearipm(void)
{
     int	i=0;
     *EVBIFRA=*EVBIFRA|0x0001;
  	 for(i=0;i<20000;i++);               //延时清错误信号
     if((*COMCONB&0x0100)==0x0100)         
      	{
      		ipmfault=0;      
       		*COMCONB=*COMCONB|0x0200;	//使能PWM输出
      	}
}	

void read_io(void)                  //注意手动自动选择开关是自锁开关, 启动停止按钮是按键
{                                                                         
	int	temp;
	
	adresult[sz1]=*RESULT8>>6; 
	sz1=sz1+1;
	if(sz1>=4)	sz1=0;
	
	temp=*PBDATDIR&0x003f; 
	iovalue[sz]=temp;
	sz=sz+1; 
	if(sz>=3)	sz=0;  
	if((iovalue[0]==iovalue[1])&&(iovalue[1]==iovalue[2]))	lastiovalue=iovalue[0];
	if(((lastiovalue&0x01)==0)&&((lastiovalue&0x08)!=0))     //手动
	{                                                     
		handflag=1; 
		if(((lastiovalue&0x02)==0)&&((lastiovalue&0x04)!=0))
		{
			handstart=1; 
			handstop=0; 
		}
		if(((lastiovalue&0x02)!=0)&&((lastiovalue&0x04)==0))
		{
			handstart=0;
			handstop=1; 
		}
	}
	if(((lastiovalue&0x01)!=0)&&((lastiovalue&0x08)==0))        //自动
	{
		autoflag=1;	 
		if(((lastiovalue&0x10)==0)&&((lastiovalue&0x20)!=0))
		{
			autostart=1; 
			autostop=0; 
		}
		if(((lastiovalue&0x10)!=0)&&((lastiovalue&0x20)==0))
		{
			autostart=0;
			autostop=1; 
		}      
	}
	if((((lastiovalue&0x01)==0)&&((lastiovalue&0x08)==0))|(((lastiovalue&0x01)!=0)&&((lastiovalue&0x08)!=0)))
	{
		handflag=0; 
		autoflag=0; 
	}  
} 


void mailbox3send(void)
{
	if((soft_timer.timer-soft_timer.can_timer)>=mailbox3_refresh)	    //向上位机发送电机转速信息100ms发一次
															//if the interval larger than 5ms, then refresh the MBX3A
	{	
		
		soft_timer.can_timer=soft_timer.timer; 
		if(*TCR&0x2000==0)
			asm( "nop");      //如果上一次发送成功,才更新发送缓冲区的数据  
	    else
	    {
	     	*TCR=*TCR|0x2000;     //清除发送成功位
	     	*MCR=(*MCR&0xFFFC)|0x103;						//CPU request to change the data field of mailbox3
		    
    	    if(speed_rec_flag==1)	
		    	*MBX3A=(*MBX3A&0xff00)|0x0055;	
		    if(time_rec_flag==1)	
		    	*MBX3A=(*MBX3A&0x00ff)|0x5500;
		    if(freq_ref_out.freq_ref!=0)        //电机启动 
		    	*MBX3C=(*MBX3C&0xff00)|0x0055;
            
            fspeed=(float)(freq_ref_out.freq_ref);
//            fspeed=20*fspeed*300/65535;  //注意:20=60/P;P=3;其中P为电机极对数
            fspeed=60*fspeed*300/65535;  //注意:20=60/P;P=1;其中P为电机极对数
        	speed=(int)fspeed;
        //    speed=30*(((freq_ref_out.freq_ref>>8)*300)>>8);  //P=2
	    	*MBX3B=speed;
		//	*MBX3C=speed;                                                       
		//	*MBX3D=speed;
			*MCR=*MCR&0xFEFF;				 //CPU request normal operation          
		    *TCR=*TCR|0X20;
		} 
	}
} 


///////////////////////////////CAN接收程序///////////////////////////
void	mailbox0rec(void)        //邮箱0接收电机转速显示器发送的转速给定,地址为0xAA+000b
{
	if((*RCR&0x10)==0x10)				//mailbox0 checking     
	{	
	    speed_ref=*MBX0B; 
	    speed_rec_flag=1;				//速度接收成功标志置1
                                   
		*RCR=*RCR|0x10;
	} 
	
}

void	mailbox1rec(void)      // 邮箱1接收时间显示器的时间参数,地址为0xA5+000b
{
	if((*RCR&0x20)==0x20)
	{	
		if(*MBX1D==0x5555)	autostart1=1;
		if(*MBX1D!=0x5555)	
			{
				autostart1=0; 
				autostart=0;               
			}         
				
		time_rec_flag=1;         // 接收时间成功标志置1
		*RCR=*RCR|0x20;
	} 
}
                                                           
void mailbox2rec(void)      //邮箱2接收上位机的转速给定,地址为0xAA+010b
{
	if((*RCR&0x40)==0x40)        
	{	
		if(*MBX1D==0x5555)	autostart1=1;
		if(*MBX1D!=0x5555)	
			{
				autostart1=0; 
				autostart=0;               
			}         
				
		time_rec_flag=1;         // 接收时间成功标志置1
		*RCR=*RCR|0x40;
	} 
}    

///////////////////2005-10-21//////////
void stop(void)                //电机停止过程频率给定逐渐减小,当减小到最小值时在给0,然后在关断PWM   
{
    if(freq_ref_out.freq_ref_max>freq_ref_out.freq_ref)     //如果启动未完成就按停止,则从当前频率开始减小
    	freq_ref_out.freq_ref_max=freq_ref_out.freq_ref;
 	if(freq_ref_out.freq_ref<=frequence_min)
	{
		flagflag=0;
    	freq_ref_out.freq_ref=0;
		*ACTRB=0x1FFF;              //vector rotate positive, PWM7,8,9,10,11,12 force high 	
	} 
	else	
		freq_ref_out.freq_ref_max=freq_ref_out.freq_ref_max-freq_ref_slope_out.freq_ref_slope;
}	
	
	
	
	
	
			

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -