Пример #1
0
//! \brief     Sets up the throttle module parameters initially
//! \param[in] handle  The throttle handle
extern void THROTTLE_setParams(THROTTLE_Handle handle,  \
                                const bool invert,
                                const _iq max_adc,      \
                                const _iq min_adc,      \
                                const _iq max_out,      \
                                const _iq min_out)
{
  THROTTLE_Obj *obj = (THROTTLE_Obj *)handle;

  obj->flagSw1 = false;
  obj->flagSw2 = false;
  obj->max_adc = max_adc;
  obj->min_adc = min_adc;

  obj->max_out = max_out;
  obj->min_out = min_out;

  obj->slope = _IQdiv((obj->max_out - obj->min_out),(obj->max_adc - obj->min_adc));
  obj->offset = obj->max_out - _IQmpy(obj->slope,obj->max_adc);

  obj->state = THROTTLE_Run;
  obj->value = _IQ(0.0);

  return;
}
Пример #2
0
void rate_generator()
{
	static _iq time = 0;
	_iq f;

	if (system.state == running_state)
	{
		if (time < system.Tacc)
		{
			f = _IQmpy(_IQdiv(system.Fref, system.Tacc), time);
			system.Fout = f;
			time += pwm.pwm_period;

			uf_characteristics();

			pwm.angle_step = _IQmpy(system.Fout, pwm.pwm_period);
		}
		else
		{
			system.Fout = system.uf.F[1];
			system.Uref = system.uf.U[1];
		}
	}
	else if (system.state == ready_state)
	{
		time = 0;
		system.Fout = system.uf.F[0];
		system.Uref = system.uf.U[0];
	}
}
Пример #3
0
void smopos_calc(SMOPOS *v)
{	
    _iq E0;
    
    E0 = _IQ(0.5);
    
// Sliding mode current observer
    v->EstIalpha = _IQmpy(v->Fsmopos,v->EstIalpha) + _IQmpy(v->Gsmopos,(v->Valpha-v->Ealpha-v->Zalpha));
    v->EstIbeta = _IQmpy(v->Fsmopos,v->EstIbeta) + _IQmpy(v->Gsmopos,(v->Vbeta-v->Ebeta-v->Zbeta));

// Current errors
    v->IalphaError = v->EstIalpha - v->Ialpha;
    v->IbetaError = v->EstIbeta - v->Ibeta;

// Sliding control calculator
    if (_IQabs(v->IalphaError) < E0)
       v->Zalpha = _IQmpy(v->Kslide,_IQdiv(v->IalphaError,E0));  
    else if (v->IalphaError >= E0) 
       v->Zalpha = v->Kslide;
    else if (v->IalphaError <= -E0) 
       v->Zalpha = -v->Kslide;

    if (_IQabs(v->IbetaError) < E0)
       v->Zbeta = _IQmpy(v->Kslide,_IQdiv(v->IbetaError,E0));  
    else if (v->IbetaError >= E0) 
       v->Zbeta = v->Kslide;
    else if (v->IbetaError <= -E0) 
       v->Zbeta = -v->Kslide;

// Sliding control filter -> back EMF calculator
    v->Ealpha = v->Ealpha + _IQmpy(v->Kslf,(v->Zalpha-v->Ealpha));
    v->Ebeta = v->Ebeta + _IQmpy(v->Kslf,(v->Zbeta-v->Ebeta));

// Rotor angle calculator -> Theta = atan(-Ealpha,Ebeta)
    v->Theta = _IQatan2PU(-v->Ealpha,v->Ebeta); 
}
Пример #4
0
extern void THROTTLE_runState(THROTTLE_Handle handle)
{
  THROTTLE_Obj *obj = (THROTTLE_Obj *)handle;


  if(obj->flagSw1)
  {
    obj->result = _IQ(0.0);
    obj->state = THROTTLE_CalMaxMin;
    obj->max_adc = obj->min_out;
    obj->min_adc = obj->max_out;
  }
  else
  {
    switch (obj->state)
    {
    case THROTTLE_CalMaxMin:

      if (obj->value > obj->max_adc)
        obj->max_adc = obj->value;
      else if (obj->value < obj->min_adc)
        obj->min_adc = obj->value;
      else if (obj->flagSw2)
        obj->state = THROTTLE_CalCalc;

    break;

    case THROTTLE_CalCalc:
    {
      obj->slope = _IQdiv((obj->max_out - obj->min_out),(obj->max_adc - obj->min_adc));
      obj->offset = obj->max_out - _IQmpy(obj->slope,obj->max_adc);
      
      obj->state = THROTTLE_Run;
    }
    break;

    case THROTTLE_Run:
    {
      _iq result = _IQmpy(obj->value,obj->slope) + obj->offset;
      obj->result = _IQsat(result,obj->max_out,obj->min_out);
    }
    break;
    }
  }


  return;
}
Пример #5
0
__interrupt void ecapISR(void)
{
    // Clear capture (CAP) interrupt flags
    CAP_clearInt(halHandle->capHandle, CAP_Int_Type_All);

    // Compute the PWM high period (rising edge to falling edge)
    uint32_t PwmDuty = (uint32_t) CAP_getCap2(halHandle->capHandle) - (uint32_t) CAP_getCap1(halHandle->capHandle);

    // Assign the appropriate speed command, combine 0-5% and 95-100%
    // 0-100% speed is proportional to 1-2ms high period
    // 60MHz * 2ms = 120000

    // 0-1%
    if (PwmDuty <= 61000)
    {
        gSpeedRef_Ok = 0;
        gSpeedRef_duty = _IQ(0);
        gMotorVars.Flag_Run_Identify = 0;
    }
    // 1-99%
    if ((PwmDuty > 61000) && (PwmDuty < 119000))
    {
        gSpeedRef_Ok = 0;
        gSpeedRef_duty = _IQdiv(PwmDuty - 60000, 60000);
        gMotorVars.Flag_Run_Identify = 1;
    }
    // 99-100%
    else if (PwmDuty >= 119000)
    {
        gSpeedRef_Ok = 0;
        gSpeedRef_duty = _IQ(1.0);
        gMotorVars.Flag_Run_Identify = 1;
    }
    // Catch all
    else
    {
        gSpeedRef_duty = _IQ(0);
        gMotorVars.Flag_Run_Identify = 0;
    }

    // Clears an interrupt defined by group number
    PIE_clearInt(halHandle->pieHandle, PIE_GroupNumber_4);
}  // end of ecapISR() function
extern void VS_FREQ_setProfile(VS_FREQ_Handle handle,
							float_t LowFreq, float_t HighFreq,
                            float_t VoltMin, float_t VoltMax)

{
  VS_FREQ_Obj *obj = (VS_FREQ_Obj *)handle;

  obj->LowFreq = _IQ(LowFreq/obj->iqFullScaleFreq_Hz);
  obj->HighFreq = _IQ(HighFreq/obj->iqFullScaleFreq_Hz);

  obj->VoltMin = _IQ(VoltMin/obj->iqFullScaleVoltage_V);
  obj->VoltMax = _IQ(VoltMax/obj->iqFullScaleVoltage_V);

  obj->VfSlope = _IQdiv((obj->VoltMax - obj->VoltMin), (obj->HighFreq - obj->LowFreq));

  obj->Vdq_gain.value[0] = _IQ(0.3);
  obj->Vdq_gain.value[1] = _IQsqrt(_IQ(obj->maxVsMag_pu*obj->maxVsMag_pu) - _IQmpy(obj->Vdq_gain.value[0], obj->Vdq_gain.value[0]));

  return;
} // end of VS_FREQ_setProfile() function
Пример #7
0
//----------------------------------------------------------------------------
// Main code:
//----------------------------------------------------------------------------
int main(void)
{
    unsigned int  i;

    _iq tempX, tempY, tempP, tempM, tempMmax;
//  char buffer[20];

    int *WatchdogWDCR = (void *) 0x7029;

    // Disable the watchdog:
    asm(" EALLOW ");
    *WatchdogWDCR = 0x0068;
    asm(" EDIS ");

    Step.Xsize = _IQ(STEP_X_SIZE);
    Step.Ysize = _IQ(STEP_Y_SIZE);
    Step.Yoffset = 0;
    Step.X = 0;
    Step.Y = Step.Yoffset;

    // Fill the buffers with some initial value
    for(i=0; i < DATA_LOG_SIZE; i++)
    {
        Dlog.Xwaveform[i] = _IQ(0.0);
        Dlog.Ywaveform[i] = _IQ(0.0);
        Dlog.Mag[i] = _IQ(0.0);
        Dlog.Phase[i] = _IQ(0.0);
        Dlog.Exp[i] = _IQ(0.0);
    }

    Step.GainX = _IQ(X_GAIN);
	Step.FreqX = _IQ(X_FREQ);
	Step.GainY = _IQ(Y_GAIN);
	Step.FreqY = _IQ(Y_FREQ);

    // Calculate maximum magnitude value:
    tempMmax = _IQmag(Step.GainX, Step.GainY);

    for(i=0; i < DATA_LOG_SIZE; i++)
    {
        // Calculate waveforms:
        Step.X = Step.X + _IQmpy(Step.Xsize, Step.FreqX);
        if( Step.X > _IQ(2*PI) )
            Step.X -= _IQ(2*PI);

        Step.Y = Step.Y + _IQmpy(Step.Ysize, Step.FreqY);
        if( Step.Y > _IQ(2*PI) )
            Step.Y -= _IQ(2*PI);

        Dlog.Xwaveform[i] = tempX = _IQmpy(_IQsin(Step.X), Step.GainX);
        Dlog.Ywaveform[i] = tempY = _IQmpy(_IQabs(_IQsin(Step.Y)), Step.GainY);

        // Calculate normalized magnitude:
        //
        // Mag = sqrt(X^2 + Y^2)/sqrt(GainX^2 + GainY^2);
        tempM = _IQmag(tempX, tempY);
        Dlog.Mag[i] = _IQdiv(tempM, tempMmax);

        // Calculate normalized phase:
        //
        // Phase = (long) (atan2PU(X,Y) * 360);
        tempP = _IQatan2PU(tempY,tempX);
        Dlog.Phase[i] = _IQmpyI32int(tempP, 360);

        // Use the exp function
        Dlog.Exp[i] = _IQexp(_IQmpy(_IQ(.075L),_IQ(i)));

		// Use the asin function
		Dlog.Asin[i] = _IQasin(Dlog.Xwaveform[i]);
    }
}
Пример #8
0
void ScalarControl(void)
{
	_iq Ds, Udc, angle;
	_iq sin, cos;

	Udc = _IQ(20.0); //system.Udc;
	Ds = _IQdiv(_IQmpy(system.Uref, _IQ(K_MOD_SPACEPWM)), Udc);
	if (Ds > _IQ(0.98))
		Ds = _IQ(0.98);

	system.Uout = _IQmpy( _IQmpy(Udc, Ds), _IQ(1/K_MOD_SPACEPWM));

	angle = pwm.angle;
	angle += pwm.angle_step;

	if (angle >= _IQ(1.0))
	{
		angle -= _IQ(1.0);
		pwm.period_out = 1;
	}
	pwm.angle = angle;

	sin = _IQsinPU(angle);
	cos = _IQcosPU(angle);

    svgen_dq.Ualpha = _IQmpy(Ds, cos);
    svgen_dq.Ubeta  = _IQmpy(Ds, sin);
    svgen_dq.calc(&svgen_dq);


#if 0
    _iq             Ds, Udc, Angle;
    _iq             sinT, cosT;

    Udc = ctom.measData.UdcFast;

    Ds = _IQdiv(_IQmpy(mtoc.mFControl.Uref, _IQ(K_MOD_SPACEPWM)), Udc);
    if(Ds > _IQ(0.98))  Ds = _IQ(0.98);

    ctom.cFControl.Uout = _IQmpy( _IQmpy(Udc, Ds), _IQ(1/K_MOD_SPACEPWM));

    Angle  = ctom.cFControl.Angle;
    Angle += mtoc.mFControl.StepAngle;

    if(Angle > _IQ( 1.0)){
        Angle -= _IQ(1.0);
        ctom.measData.periodOut = 1;
    }
    else if(Angle < _IQ(-1.0)){
        Angle += _IQ(1.0);
        ctom.measData.periodOut = 1;
    }
    ctom.cFControl.Angle = Angle;

    sinT = _IQsinPU(Angle);
    cosT = _IQcosPU(Angle);

    svgen_dq.Ualpha = _IQmpy(Ds, cosT);
    svgen_dq.Ubeta  = _IQmpy(Ds, sinT);
    svgen_dq.calc(&svgen_dq);

/*
    pwm1.MfuncC1 = (s16)_IQtoIQ15(svgen_dq.Tc); // MfuncC1 is in Q15
    pwm1.MfuncC2 = (s16)_IQtoIQ15(svgen_dq.Ta); // MfuncC2 is in Q15
    pwm1.MfuncC3 = (s16)_IQtoIQ15(svgen_dq.Tb); // MfuncC3 is in Q15
    pwm1.triol_update(&pwm1);

    v->Tc = (s16)_IQtoIQ15(svgen_dq.Tc);
    v->Ta = (s16)_IQtoIQ15(svgen_dq.Ta);
    v->Tb = (s16)_IQtoIQ15(svgen_dq.Tb);
*/
#endif
}
Пример #9
0
void uf_characteristics()
{
	system.Uref = _IQmpy(_IQdiv(system.uf.U[1] - system.uf.U[0], system.uf.F[1] - system.uf.F[0]), system.Fout);
}
Пример #10
0
void FREQCAL_Calc(FREQCAL *p)
{
     unsigned long tmp;
   	 _iq newp,oldp;

// Check unit Time out-event for speed calculation:
// Unit Timer is configured for 100Hz in INIT function
//**** Freq Calculation using QEP position counter ****//
// For a more detailed explanation of the calculation, read
// the description at the top of this file

	if(EQep1Regs.QFLG.bit.UTO==1)                  // Unit Timeout event
	{
		/** Differentiator	**/
	 	newp=EQep1Regs.QPOSLAT;                    // Latched POSCNT value
		oldp=p->oldpos;

    	if (newp>oldp)
      		tmp = newp - oldp;                     // x2-x1 in v=(x2-x1)/T equation
    	else
      		tmp = (0xFFFFFFFF-oldp)+newp;

		p->freq_fr = _IQdiv(tmp,p->freqScaler_fr); // p->freq_fr = (x2-x1)/(T*10KHz)
		tmp=p->freq_fr;

		if (tmp>=_IQ(1))          // is freq greater than max freq (10KHz for this example)?
	 		p->freq_fr = _IQ(1);
		else
	 		p->freq_fr = tmp;

		p->freqhz_fr = _IQmpy(p->BaseFreq,p->freq_fr); 	// Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
		                                                // p->freqhz_fr = (p->freq_fr)*10kHz = (x2-x1)/T

		// Update position counter
    	p->oldpos = newp;
		//=======================================

		EQep1Regs.QCLR.bit.UTO=1;					// Clear interrupt flag
	}

//**** Freq Calculation using QEP capture counter ****//
	if(EQep1Regs.QEPSTS.bit.UPEVNT==1)              // Unit Position Event
	{
		if(EQep1Regs.QEPSTS.bit.COEF==0)            // No Capture overflow
			tmp=(unsigned long)EQep1Regs.QCPRDLAT;
		else							            // Capture overflow, saturate the result
			tmp=0xFFFF;

		p->freq_pr = _IQdiv(p->freqScaler_pr,tmp);  // p->freq_pr = X/[(t2-t1)*10KHz]
		tmp=p->freq_pr;

		if (tmp>_IQ(1))
	 		p->freq_pr = _IQ(1);
		else
	 		p->freq_pr = tmp;

		p->freqhz_pr = _IQmpy(p->BaseFreq,p->freq_pr); 	// Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
	                                                    // p->freqhz_pr =( p->freq_pr)*10kHz = X/(t2-t1)
		EQep1Regs.QEPSTS.all=0x88;					    // Clear Unit position event flag
												     	// Clear overflow error flag
	}
}