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

📄 acim.c

📁 dspic30f6010a的学习事例程序
💻 C
📖 第 1 页 / 共 3 页
字号:
                        uGF.bit.Btn3Pressed  = 1;
                        LATGbits.LATG0 = 0;
                    }
                else
                    {
                    if( uGF.bit.Btn3Pressed )
                        {
                        // Button just released
                        uGF.bit.Btn3Pressed  = 0;
                                                
                        if(uGF.bit.OpenLoop)
                        	{
	                        uGF.bit.ChangeSpeed = !uGF.bit.ChangeSpeed;
                        	pinLED3 = uGF.bit.ChangeSpeed;	
	                        }
	                        
	                    else
	                    	{    
	                        #ifdef SNAPSHOT
	                        	uGF.bit.DoSnap = 1;
	                        	SnapCount = 0;
	                        	pinLED4 = 1;

	                        #else
	                        	uGF.bit.ChangeSpeed = !uGF.bit.ChangeSpeed;
	                        	pinLED3 = uGF.bit.ChangeSpeed;	
	                        #endif
                        	}
                        	
                        	
                        #ifdef DIAGNOSTICS
                        	LATGbits.LATG0 = 1;
                        #endif 
                        
                        
                        
                        
                        }
                    }
				
				if( uGF.bit.SnapDone )
                    { 
                                         
                     uGF.bit.SnapDone=0;
				
                     pinLED4 = 0;          
                    }

                }  // end of display and button polling code              
                
            }   // End of Run Motor loop

        
        } // End of Main loop
        
    // should never get here
    while(1){}
}

//---------------------------------------------------------------------
// Executes one PI itteration for each of the three loops Id,Iq,Speed
void DoControl( void )
{
short i;

    // Assume ADC channel 0 has raw A/D value in signed fractional form from
    // speed pot (AN7).
    ReadSignedADC0( &ReadADCParm );


    // Set reference speed
    if(uGF.bit.ChangeSpeed)
	{
        CtrlParm.qVelRef = ReadADCParm.qADValue/8;
    }
	else
	{    
    	CtrlParm.qVelRef = ReadADCParm.qADValue/16;
	}

    if( uGF.bit.OpenLoop )
        {
        // OPENLOOP:  force rotating angle,Vd,Vq

        if( uGF.bit.ChangeMode )
            {
            // just changed to openloop
            uGF.bit.ChangeMode = 0;
            // synchronize angles
            OpenLoopParm.qAngFlux = CurModelParm.qAngFlux;

            // VqRef & VdRef not used
            CtrlParm.qVqRef = 0;
            CtrlParm.qVdRef = 0;
            }

        OpenLoopParm.qVelMech = CtrlParm.qVelRef;

        // calc rotational angle of rotor flux in 1.15 format

        // just for reference & sign needed by CorrectPhase
        CurModelParm.qVelMech = EncoderParm.qVelMech;
        CurModel();

        ParkParm.qVq = 0;

        if( OpenLoopParm.qVelMech >= 0 )
            i = OpenLoopParm.qVelMech;  
        else
            i = -OpenLoopParm.qVelMech;

        uWork = i <<2;

        if( uWork > 0x5a82 )
            uWork = 0x5a82;

        if( uWork < 0x1000 )
            uWork = 0x1000;

        ParkParm.qVd = uWork;

        OpenLoop();
        ParkParm.qAngle = OpenLoopParm.qAngFlux; 
		}
    else
        // Closed Loop Vector Control
        {

        if( uGF.bit.ChangeMode )
            {
            // just changed from openloop
            uGF.bit.ChangeMode = 0;

            // synchronize angles and prep qdImag
            CurModelParm.qAngFlux = OpenLoopParm.qAngFlux; 
            CurModelParm.qdImag = ParkParm.qId;
            }
			
        // Current model calculates angle
        CurModelParm.qVelMech = EncoderParm.qVelMech;
                
        CurModel();
				
        ParkParm.qAngle = CurModelParm.qAngFlux; 

        // Calculate qVdRef from field weakening
        FdWeakening();
               
                
        // Check to see if new velocity information is available by comparing
        // the number of interrupts per velocity calculation against the
        // number of velocity count samples taken.  If new velocity info
        // is available, calculate the new velocity value and execute
        // the speed control loop.
        if(EncoderParm.iVelCntDwn == EncoderParm.iIrpPerCalc)
        	{
	        // Calculate velocity from acumulated encoder counts
        	CalcVel();
        	// Execute the velocity control loop
// Changes 15 dec 2006
//****************************
				if ((uGF.bit.Sensorless)&&(!uGF.bit.OpenLoop))
				{
					if(CtrlParm.qVelRef==0)
					{
						if (abs(EstimParm.qVelEstim)<(StartupParm.qVelMinContrOff))
						{
							PIParmQref.qInMeas=0;
							PIParmQref.qdSum=0;
						} else
						{
		        			PIParmQref.qInMeas = EstimParm.qVelEstim;
						}
					} else
					{
		        		PIParmQref.qInMeas = EstimParm.qVelEstim;
				
// Changes 02 feb 2007
//****************************
// Hysteresis by speed reference value
// minimum speed ref. is StartupParm.qVelMinContrOff
// change speed ref. from 0 to StartupParm.qVelMinContrOff by positiv edge of CtrlParm.qVelRef through StartupParm.qVelMinContrOff
// change speed ref. from StartupParm.qVelMinContrOff to 0 by negative edge of CtrlParm.qVelRef through StartupParm.qVelMinContrOff/2

						if(abs(CtrlParm.qVelRef)<StartupParm.qVelMinContrOff)
						{
							if(abs(CtrlParm.qVelRef)<(StartupParm.qVelMinContrOff>>1)) 
							{						
								CtrlParm.qVelRef=0;
							} else
							{
								if(abs(PIParmQref.qInRef)>=(StartupParm.qVelMinContrOff))
								{
									if (CtrlParm.qVelRef>0) 
									{	
										CtrlParm.qVelRef=StartupParm.qVelMinContrOff;
									} else
									{
										CtrlParm.qVelRef=-StartupParm.qVelMinContrOff;
									}	
								} else
								{
									CtrlParm.qVelRef=0;	
								}
							}
						} 
					}

				} else
				{
					PIParmQref.qInMeas = EncoderParm.qVelMech;
				}
//****************************

			#ifndef	TORQUE_MODE
        	PIParmQref.qInRef  = CtrlParm.qVelRef;
        	CalcPI(&PIParmQref);
        	CtrlParm.qVqRef    = PIParmQref.qOut;
			#endif
           	}
        
        #ifdef	SNAPSHOT
		if(EncoderParm.iVelCntDwn == EncoderParm.iIrpPerCalc)
			{
			// Log data in the snapshot buffers
	        	if( uGF.bit.DoSnap )
		        {
			     SnapBuf1[SnapCount] = SNAP1;
			     SnapBuf2[SnapCount] = SNAP2;  
			     SnapBuf3[SnapCount] = SNAP3;
			     
			     SnapCount++;
			     if(SnapCount == SNAP_DELAY)
			        {
				   	uGF.bit.ChangeSpeed = !uGF.bit.ChangeSpeed;
                    pinLED3 = uGF.bit.ChangeSpeed;  
				     
				    }   
		         if(SnapCount == SNAPSIZE)
		            {
		            uGF.bit.SnapDone=1;
		            uGF.bit.DoSnap = 0;
		            }
		         
		         }
       		}
       	#endif
       
       
        // If the application is running in torque mode, the velocity
        // control loop is bypassed.  The velocity reference value, read
        // from the potentiometer, is used directly as the torque 
        // reference, VqRef.
        #ifdef	TORQUE_MODE
        	CtrlParm.qVqRef = CtrlParm.qVelRef * 4;
        #endif
       	
        // PI control for Q
        PIParmQ.qInMeas = ParkParm.qIq;
        PIParmQ.qInRef  = CtrlParm.qVqRef;
        CalcPI(&PIParmQ);
        ParkParm.qVq    = PIParmQ.qOut;
       

        // PI control for D
        PIParmD.qInMeas = ParkParm.qId;
        PIParmD.qInRef  = CtrlParm.qVdRef;
        CalcPI(&PIParmD);
        ParkParm.qVd    = PIParmD.qOut;
        
        
        }
}

//---------------------------------------------------------------------
// The ADC ISR does speed calculation and executes the vector update loop.
// The ADC sample and conversion is triggered by the PWM period.
// The speed calculation assumes a fixed time interval between calculations.
//---------------------------------------------------------------------

void __attribute__((__interrupt__,auto_psv)) _ADCInterrupt(void)
{

        IFS0bits.ADIF = 0;
        
        // Increment count variable that controls execution
        // of display and button functions.
        iDispLoopCnt++;
        
        // acumulate encoder counts since last interrupt 
        CalcVelIrp();  

        if( uGF.bit.RunMotor )
                {
pinLED1=1;                
                
                // use TMR1 to measure interrupt time for diagnostics
                TMR1 = 0;           
                iLoopCnt = TMR1;
		 

// Appcon/Changes 25 Jan 2007
// current is measured, 
// Offset is dynamicly compensated when
//  	1. Sensored control is selected
//  	2. Velocity > CurrCompMinSpeed
//****************************    
            
// Hysteresis for activation desactivation of offset compensation:
		// MeasCurrParm.iOffsetCompAktiv is set to 1 when abs(EncoderParm.qVelMech)>MeasCurrParm.iOffsetCompVelLimit+MeasCurrParm.iOffsetCompHyst
   		// MeasCurrParm.iOffsetCompAktiv is set to 0 when abs(EncoderParm.qVelMech)<MeasCurrParm.iOffsetCompVelLimit

	
	        	// Calculate qIa,qIb
				if ((abs(EncoderParm.qVelMech)>MeasCurrParm.iOffsetCompVelLimit)&&(uGF.bit.Sensorless==0))
				{			
					if(abs(EncoderParm.qVelMech)>(MeasCurrParm.iOffsetCompVelLimit+MeasCurrParm.iOffsetCompHyst))
					{
 						MeasCurrParm.iOffsetCompAktiv=1;						
					}
				} else
				{
 					MeasCurrParm.iOffsetCompAktiv=0;
				}

				if( MeasCurrParm.iOffsetCompAktiv)
				{
	        	// Calculate qIa,qIb with offset correction
               		MeasCompCurr();
				} else
				{
	        	// Calculate qIa,qIb without offset correction
               		MeasCompCurr2();					
				}
			
//****************************                
                
                // Calculate qId,qIq from qSin,qCos,qIa,qIb
                ClarkePark();
// Appcon/Changes 15 dec 2006
// New module: Speed estimation
//****************************         
// elapsed time: 16 micro second  by 15MIPs

   
				Estim();

//****************************             
                               
                // Calculate control values
                DoControl();
							
// Changes 15 dec 2006
//****************************
				if ((uGF.bit.Sensorless)&&(!uGF.bit.OpenLoop))
				{
					SincosParm.qAngle=EstimParm.qRho;
				} else
				{
					SincosParm.qAngle=ParkParm.qAngle;
				}
//****************************

⌨️ 快捷键说明

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