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: eQEP module - high speed measurement update rate too slow

Part Number: TMS320F28335

Hello,

I'm a student and for a project I have to use the eQEP module for a TMS320F28335 to measure the speed and position of a linear machine (PMSM). The incremental encoder ouputs the signals with frequencies between 10Hz and 100kHz depending on the speed.
I get the measured speed and position for high and low speeds without a problem. But the speed update rate for high frequencies is too slow.
The update rate is the value of the QUPRD-register divided by the clock. For correct measurements I need at least the period QUPRD=1.500.000 and the clock frequency is 150MHz. That means the DPS calculates every 10ms a new speed value. That is quiet slow. Especially after an index event, when the QPOSCNT-register is resettet to get a reference point for the position (position counter reset on index event [PCRM]=00). If I choose QUPRD much smaller like QUPRD=30000, the measured speed isn't usable at all.
For example (diagram):
The machine drives with 0.4m/s (QEPA and QEPB=20kHz) and it passes an index event/refernce point, the measured speed is 0m/s for 20ms (QUPRD=3.000.000), even when it's a lot faster. The frequencies for the PWM signals are 16kHz, so during the 20ms with no measured speed, the DSP outputs 320 (different) calculated PWM values based on the speed to the inverter. But the values are just wrong.

Is there any solution to fix this problem? I appreciate every suggestion and thanks for your help.

Best regards
Arne

Used simplified code fragment:

EQep1Regs.QUPRD = 3000000;                                            
    if( EQep1Regs.QFLG.bit.UTO == 1 ){                                      
        v_fast_1 =  (EQep1Regs.QPOSCNT-EQep1Regs.QPOSLAT)*750/3000000;  
        EQep1Regs.QCLR.bit.UTO = 1;                                       
    }

Measured signals with an external DAC and a scope:

  • Hi Arne,

    EQEP module can generally measure signals of quite high frequencies if Unit Timeout Measurement approach is used so ideally there should not be any issue in your case where signals are around 20kHZ.  Can you provide more details about your configuration of eQEP, are you using unit time out interrupt i.e. speed calculation occurs after every unit timeout (20 ms in your case) .

    Thanks & Regards

    Himanshu

  • Thank you Himanshu for your help so far.

    I tried various things but it's always the same result with the wrong speed measurement for one time period.
    Here is the simplest code example with the result from the diagram.

    /*init interrupts*/
    // Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;
    
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used.  This is useful for debug purposes.
       InitPieVectTable();
    
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
       EALLOW;  
       PieVectTable.EQEP1_INT = EQEP1_isr;
       EDIS;    
    
    // Enable CPU INTs
       IER |= M_INT5;      // for EQEP
    
    
    // Enable INTn in the PIE:
       PieCtrlRegs.PIEIER5.bit.INTx1 = 1;       // enable EQEP1_INT
    
    
    // Enable global Interrupts and higher priority real-time debug events:
       EINT;   // Enable Global interrupt INTM
       ERTM;   // Enable Global realtime interrupt DBGM
    
    /*init function for the eQEP module, executed one time during boot*/
    
    void InitEQep(void) {
      /* Quadrature Count Mode */
      EQep1Regs.QDECCTL.bit.QSRC = QEP_QUADRATURE_ENCODER_COUNT_MODE;
      /* Count both signal edges (rising & falling)  */
      EQep1Regs.QDECCTL.bit.XCR  = QEP_EXT_CLOCK_RATE_X2;
      /* swap direction */
      EQep1Regs.QDECCTL.bit.SWAP = QEP_SWAP_DIRECTION;
      /* Reset QEP-Counter automatically when reaching reference point */
      EQep1Regs.QEPCTL.bit.PCRM = QEP_RESET_ON_REFERENCE_POINT;
      /* Enable QEP-Counter */
      EQep1Regs.QEPCTL.bit.QPEN = QEP_QUAD_COUNTER_ENABLE;
      /* Enable QEP-Timer */
      EQep1Regs.QEPCTL.bit.UTE  = QEP_QUAD_TIMER_ENABLE;
      /* Use Software Index Marker; Latching Position value at Index */
      EQep1Regs.QEPCTL.bit.IEL = 3;
      /* Set Encoder maximum increments into count register */
      EQep1Regs.QPOSMAX = 0xFFFFFFFF;
      /* initialize Count with zero */
      EQep1Regs.QPOSCNT = 0;
      EQep1Regs.QEINT.bit.IEL = 1; //enable Index event latch interrupt
      EQep1Regs.QEINT.bit.UTO = 1;  //Unit time out interrupt
      EQep1Regs.QEPCTL.bit.UTE = 1; // enable Unit Timer
      EQep1Regs.QEPCTL.bit.QCLM = 1; // enable capture latch mode
      EQep1Regs.QUPRD = 3000000; //periode of timer
    
    
    /*Interrupt function in main.c */
    void EQEP1_isr(void) {
       pos_past = pos;                                
       pos = EQep1Regs.QPOSLAT;
       v = (pos-pos_past)*750/EQep1Regs.QUPRD;
       EQep1Regs.QCLR.all=0xFFE;
       PieCtrlRegs.PIEACK.all |= PIEACK_GROUP5;
    }

    With an nearly empty main function the interrupt function "EQEP1_isr" is executed every 20ms because of the unit time interrupt without a problem. But when I put a loop with a counter in the main function, the counter won't be interrupted by the unit time interrupt. The counter just counts for many seconds and the speed isn't calculated once during the loop. So I think there must be an error with my interrupt initialization. If this is the case, the interrupt function "EQEP1_isr" shouldn't be executed once or am I wrong?

    Best regards
    Arne

  • Hi Arne,

    It is quite unclear to me what exact problem you are facing. But what I could think of if you are wondering why the first calculation is wrong in the first interrupt then you don't need to worry as this might be possible because by the time unit timeout is configured, there might be some already accumulated position counts but in calculation, "pos_past" is assumed 0 so this could result in some error. So i would suggest you to always ignore the first speed calculation, and monitor the values from second calculation onwards.

    And now coming to your second issue, when you say counter so is it implemented using another CPU_Timer interrupt then maybe that both of these interrupts belong to same PIE so it disable eqep interrupt as well. Please check that