This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28335: f28335

Part Number: TMS320F28335
Other Parts Discussed in Thread: CONTROLSUITE

Hello,

I need to calculate speed from an encoder using eQEP [simulink]. I have already read eQEP_sprug05a but I cant say that I understand what exactly have to do. I have a 2000 [nominal rpm] motor and  an incremental tacho that gives me 1024 pulses per revolution. I tried to configure eQEP but all the registers are zeros [CCSv6, real time ].

How can I calculate speed; Is it possilbe only with QEPa pulse or I need QEPindex also;

In datasheet there is a different method for low speed and high speed. Is 2000 rmp high speed so I need to use both methods;

In ControlSuite there is 'Example_posspeed.xls' . Can I use this example to calculate register's values;

Can I use a PWM module instead of encoder pulses;

#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
#include "DSP2833x_GlobalPrototypes.h"
#include "rtwtypes.h"
#include "DSP_Motor_Drive_PI_eQEP.h"

void config_QEP_eQEP1(uint32_T pcmaximumvalue, uint32_T pcInitialvalue, uint32_T
                      unittimerperiod, uint32_T comparevalue, uint16_T
                      watchdogtimer, uint16_T qdecctl, uint16_T qepctl, uint16_T
                      qposctl, uint16_T qcapctl, uint16_T qeint)
{
  EALLOW;                              /* Enable EALLOW*/

  /* Enable internal pull-up for the selected pins */
  GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0;  /* Enable pull-up on GPIO20 (EQEP1A)*/
  GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0;  /* Enable pull-up on GPIO21 (EQEP1B)*/
  GpioCtrlRegs.GPAPUD.bit.GPIO22 = 0;  /* Enable pull-up on GPIO22 (EQEP1S)*/
  GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0;  /* Enable pull-up on GPIO23 (EQEP1I)*/

  /* Configure eQEP-1 pins using GPIO regs*/
  GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 1; /* Configure GPIO20 as EQEP1A*/
  GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 1; /* Configure GPIO21 as EQEP1B  */
  GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 1; /* Configure GPIO22 as EQEP1S*/
  GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 1; /* Configure GPIO23 as EQEP1I*/
  EDIS;
  EQep1Regs.QPOSINIT = pcInitialvalue; /*eQEP Initialization Position Count*/
  EQep1Regs.QPOSMAX = pcmaximumvalue;  /*eQEP Maximum Position Count*/
  EQep1Regs.QUPRD = unittimerperiod;   /*eQEP Unit Period Register*/
  EQep1Regs.QWDPRD = watchdogtimer;    /*eQEP watchdog timer Register*/
  EQep1Regs.QDECCTL.all = qdecctl;     /*eQEP Decoder Control (QDECCTL) Register*/
  EQep1Regs.QEPCTL.all = qepctl;       /*eQEP Control (QEPCTL) Register*/
  EQep1Regs.QPOSCTL.all = qposctl;     /*eQEP Position-compare Control (QPOSCTL) Register*/
  EQep1Regs.QCAPCTL.all = qcapctl;     /*eQEP Capture Control (QCAPCTL) Register*/
  EQep1Regs.QEPCTL.bit.FREE_SOFT = 2;  /*unaffected by emulation suspend*/
  EQep1Regs.QPOSCMP = comparevalue;    /*eQEP Position-compare*/
  EQep1Regs.QEINT.all = qeint;         /*eQEPx interrupt enable register*/
}

  • Hi Kostas,

    Thank you for your post. Your thread has been assigned to a C2000 expert and should be answered soon.

    Best regards,
    Chen
  • To configure the EQEP register, you need to enable the clock of EQEP module first as below, and you can use EQEP module without INDEX if you don't need to use the signal to calibrate the ZERO position of rotor.
    SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1
  • HI,

    In ControlSuite there is an example for eQEP 'Example_2833xEqep_pos_speed'-> 'Example_posspeed.c'.

    1. I have 'incremental tacho 1.0' which gives me 1024 pulses per revolution. Is the same as 1024 lines per revolution?

    2. Can I use this example without IQmath? I have f28335 which is floating point.

    3. How can I correspond the value of registers with the real values? For example, In 'ADC_spru812a.pdf' it states that the voltage is being transformed in a range between 0 and 4096. Is there a way to see this value in register? How about QCPRDLAT register?

    4. I have these errors. I can not figure out if this problem is from data types or I need to use IQmath?

    5. Model base rate is 0.2. Is this a problem?

    int main(void)
    {
      volatile boolean_T runModel = 1;
      float modelBaseRate = 0.2;
      float systemClock = 150;
      c2000_flash_init();
      init_board();
    

    void isr_int5pie1_task_fcn(void)
    {
      /* Call the system: <Root>/Speed_Regulation */
    
    	   /* S-Function (c28xisr_c2000): '<Root>/C28x Hardware Interrupt' */
    
        /* Output and update for function-call system: '<Root>/Speed_Regulation' */
    
        /* S-Function (c280xqep): '<S2>/eQEP' */
    
    
        	 // High Speed Calculation using QEP Position counter
        	    // Check unit Time out-event for speed calculation:
        	    // Unit Timer is configured for 100Hz in INIT function
    
        	  real32_T newp,oldp,Tmp1,Speed_fr,SpeedRpm_fr,Speed_pr,SpeedRpm_pr;
        	  int DirectionQep;
    
    
        	    if(EQep1Regs.QFLG.bit.UTO==1)      // If unit timeout (one 100Hz period)
        	    {
        	        //
        	        // Differentiator
        	        // The following lines calculate position =
        	        // (x2-x1)/4000 (position in 1 revolution)
        	        //
        	    	rtDW.eQEP_o2 = EQep1Regs.QPOSLAT;/* eQEP Position Counter Latch (QPOSLAT) Register*/
        	        newp =(real32_T)((real_T) rtDW.eQEP_o2*rtP.mech_scaler);
        	        oldp=rtP.oldpos;
        	        DirectionQep = EQep1Regs.QEPSTS.bit.QDF;
    
        	        if (DirectionQep==0)      	// POSCNT is counting down
        	        {
        	            if (newp>oldp)
        	            {
        	                Tmp1 = - (1 - newp + oldp);    // x2-x1 should be negative
        	            }
        	            else
        	            {
        	                Tmp1 = newp -oldp;
        	            }
        	        }
        	        else if (DirectionQep==1)    // POSCNT is counting up
        	        {
        	            if (newp<oldp)
        	            {
        	                Tmp1 = 1 + newp - oldp;
        	            }
        	            else
        	            {
        	                Tmp1 = newp - oldp;     // x2-x1 should be positive
        	            }
        	        }
    
        	        if (Tmp1>1)
        	        {
        	            Speed_fr = 1;
        	        }
        	        else if (Tmp1<-1)
        	        {
        	            Speed_fr = -1;
        	        }
        	        else
        	        {
        	            Speed_fr = Tmp1;
        	        }
    
        	        //
        	        // Update the electrical angle
        	        //
        	        rtP.oldpos = newp;
    
    
        	        SpeedRpm_fr = rtP.BaseRpm * Speed_fr * 1.3655;
    
        	        EQep1Regs.QCLR.bit.UTO=1;					// Clear interrupt flag
        	    }
    
        	    //
        	    // Low-speed computation using QEP capture counter
        	    //
    
        	    if(EQep1Regs.QEPSTS.bit.UPEVNT==1)     // Unit position event
        	    {
        	        if(EQep1Regs.QEPSTS.bit.COEF==0)   // No Capture overflow
        	        {
        	        rtDW.eQEP_o1 = EQep1Regs.QCPRDLAT;     /* eQEP Capture Period Latch (QCPRDLAT) Register*/       // temp1 = t2-t1
        	        }
        	        else   // Capture overflow, saturate the result
        	        {
        	        rtDW.eQEP_o1=0xFFFF;
        	        }
    
        	        //
        	        // Speed_pr = SpeedScaler/rtDW.eQEP_o1
        	        //
        	        Speed_pr =rtP.SpeedScaler / rtDW.eQEP_o1;
        	        Tmp1=Speed_pr;
    
        	        if (Tmp1>1)
        	        {
        	            Speed_pr = 1.0;
        	        }
        	        else
        	        {
        	            Speed_pr = Tmp1;
        	        }
    
        	        //
        	        // Convert Speed_pr to RPM
        	        //
        	        if (DirectionQep==0)     // Reverse direction = negative
        	        {
        	            SpeedRpm_pr = -(rtP.BaseRpm * Speed_pr);
        	        }
        	        else                        // Forward direction = positive
        	        {
        	            SpeedRpm_pr = rtP.BaseRpm * Speed_pr * 1.3655;
        	        }
    
        	        EQep1Regs.QEPSTS.all=0x88;	// Clear Unit position event flag
        	                                    // Clear overflow error flag
        	    }
    
        /* Switch: '<S2>/Switch' incorporates:
         *  Constant: '<S2>/Constant'
         */
        if (SpeedRpm_fr > rtP.Constant_Value)
        {
          rtDW.Switch = (real_T)SpeedRpm_fr;
        }
        else
        {
          rtDW.Switch = (real_T)SpeedRpm_pr;
        }
    
        /* End of Switch: '<S2>/Switch' */
    
        /* End of Outputs for S-Function (c28xisr_c2000): '<Root>/C28x Hardware Interrupt' */
    
        /* Update for RateTransition: '<Root>/Rate Transition' */
        rtDW.RateTransition_Buffer[rtDW.RateTransition_ActiveBufIdx == 0] =
          rtDW.Switch;
        rtDW.RateTransition_ActiveBufIdx = (rtDW.RateTransition_ActiveBufIdx == 0);
    
    P rtP = {
      90.0F,                               /* Mask Parameter: DiscretePIDController1_I
                                            * Referenced by: '<S3>/Integral Gain'
                                            */
      60.0F,                               /* Mask Parameter: DiscretePIDController1_LowerSat
                                            * Referenced by:
                                            *   '<S3>/Saturate'
                                            *   '<S4>/DeadZone'
                                            */
      10.0F,                               /* Mask Parameter: DiscretePIDController1_P
                                            * Referenced by: '<S3>/Proportional Gain'
                                            */
      59400.0F,                            /* Mask Parameter: DiscretePIDController1_UpperSat
                                            * Referenced by:
                                            *   '<S3>/Saturate'
                                            *   '<S4>/DeadZone'
                                            */
      136.5,                               /* Expression: 136.5
                                            * Referenced by: '<S2>/Constant'
                                            */
      0.0,                                 /* Expression: 0
                                            * Referenced by: '<S2>/Switch'
                                            */
      0.2F,                                /* Computed Parameter: Integrator_gainval
                                            * Referenced by: '<S3>/Integrator'
                                            */
      0.0F,                                /* Computed Parameter: Integrator_IC
                                            * Referenced by: '<S3>/Integrator'
                                            */
      0.0F,                                /* Computed Parameter: ZeroGain_Gain
                                            * Referenced by: '<S4>/ZeroGain'
                                            */
      0.0F,                                /* Computed Parameter: Constant_Value_g
                                            * Referenced by: '<S3>/Constant'
                                            */
      0.0F,                                 /* Computed Parameter: RateTransition_X0
                                            * Referenced by: '<Root>/Rate Transition'
                                            */
      0.0,									/*oldpos*/
      0.000244,			    /*mechanical scaler*/
      94,									/*speed scaler*/
      2400								/*nominal rpm*/
    };
    
    struct P_ {
      real32_T DiscretePIDController1_I;   /* Mask Parameter: DiscretePIDController1_I
                                            * Referenced by: '<S3>/Integral Gain'
                                            */
      real32_T DiscretePIDController1_LowerSat;/* Mask Parameter: DiscretePIDController1_LowerSat
                                                * Referenced by:
                                                *   '<S3>/Saturate'
                                                *   '<S4>/DeadZone'
                                                */
      real32_T DiscretePIDController1_P;   /* Mask Parameter: DiscretePIDController1_P
                                            * Referenced by: '<S3>/Proportional Gain'
                                            */
      real32_T DiscretePIDController1_UpperSat;/* Mask Parameter: DiscretePIDController1_UpperSat
                                                * Referenced by:
                                                *   '<S3>/Saturate'
                                                *   '<S4>/DeadZone'
                                                */
      real32_T Constant_Value;               /* Expression: 136.5
                                            * Referenced by: '<S2>/Constant'
                                            */
      real_T Switch_Threshold;             /* Expression: 0
                                            * Referenced by: '<S2>/Switch'
                                            */
      real32_T Integrator_gainval;         /* Computed Parameter: Integrator_gainval
                                            * Referenced by: '<S3>/Integrator'
                                            */
      real32_T Integrator_IC;              /* Computed Parameter: Integrator_IC
                                            * Referenced by: '<S3>/Integrator'
                                            */
      real32_T ZeroGain_Gain;              /* Computed Parameter: ZeroGain_Gain
                                            * Referenced by: '<S4>/ZeroGain'
                                            */
      real32_T Constant_Value_g;           /* Computed Parameter: Constant_Value_g
                                            * Referenced by: '<S3>/Constant'
                                            */
      real32_T RateTransition_X0;          /* Computed Parameter: RateTransition_X0
                                            * Referenced by: '<Root>/Rate Transition'
                                            */
      real32_T oldpos;					/*initial oldpos*/
      real32_T mech_scaler;		/*mechanical scaler value8*/
      real32_T SpeedScaler;		/*speed scaler*/
      real32_T BaseRpm;				/*nominal rmp*/
    };



    Thank you in advance.