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.

phase angle calculation in a triphase system using eCAP

With the module eCAP I have the frequencies of the 3 signals.

Now, I would like to know how I can find the phase of each of the signals using the ECAP module.

  • Hi Natalia,

    Assuming you are using eCAP1-3, one option may be to let eCAP1 be the synchronization master while configuring eCAP2-3 to be slaves.  Also configure all three to sample rising or falling edges using absolute timestamping and continuous mode.

    Early in your program, you would force synchronization using ECCTL[SWSYNC] on eCAP1.  Afterward, all three of your eCAP timers will be synchronized and will slowly free run to 2^32, then restart at zero and so on.  You then set up your eCAP events as desired and then, in code, subtract one eCAP edge time from a differ eCAP edge time to get the phase offset.

    There are likely to be other options as well.  Hopefully this helps though!


    Thank you,
    Brett

  • I did not understand well.
    I've been testing so far with only two signals.

    this is my code.

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    
    void configECapture();
    void Frequency();
    
    
    
    double Frec;
    Uint32 T1;
    Uint32 T2;
    Uint32 T3;
    Uint32 P1;
    Uint32 P2;
    
    double Frec2=0;
    
    Uint32 T12;
    Uint32 T22;
    Uint32 T32;
    Uint32 T42;
    Uint32 P12;
    Uint32 P22;
    Uint32 P32;
    
    
    Uint32 E1;
    Uint32 E2;
    Uint32 E3;
    Uint32 E4;
    
    void main(void)
    {
    
    
    
    	   InitSysCtrl();      // Initialize System Control:
    	   	   	   	   	   	   // PLL, WatchDog, enable Peripheral Clocks
    	   	   	   	   	   	   // This example function is found in the DSP2833x_SysCtrl.c file.
    
    	   DINT;               //Clear all interrupts and initialize PIE vector table:
    	                       // Disable CPU interrupts
    
    	   InitPieCtrl();      // Initialize the PIE control registers to their default state
    
    	   IER = 0x0000;       // Disable CPU interrupts and clear all CPU interrupt flags
    	   IFR = 0x0000;
    
    	   InitPieVectTable(); // Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR).
    
    	   InitECap1Gpio();
    	   InitECap2Gpio();
    
    
    
    	 //Enable global Interrupts and higher priority real-time debug events:
    
       configECapture();  // CONFIGURACION ECAP1
    
    
    
       for(;;)
       {
    
    	   Frequency();
       }
    
    }
    
    void Frequency()
    {
    
    
        E1= T12-T1;
        E2= ECap1Regs.TSCTR;
        E3= ECap2Regs.TSCTR;
    
    
    	T1 = ECap1Regs.CAP1; // Fetch Time-Stamp captured at t1
    	T2 = ECap1Regs.CAP2; // Fetch Time-Stamp captured at t2
    	T3 = ECap1Regs.CAP3; // Fetch Time-Stamp captured at t3
    	//P1 = T2-T1; // Calculate 1st period
    	//P2 = T3-T2; // Calculate 2st period
    
    	T12 = ECap2Regs.CAP1; // Fetch Time-Stamp captured at t1
    	T22 = ECap2Regs.CAP2; // Fetch Time-Stamp captured at t2
    	T32 = ECap2Regs.CAP3; // Fetch Time-Stamp captured at t3
    	T42 = ECap2Regs.CAP4;
    	//P12 = T22-T12; // Calculate 1st period
        //P22 = T32-T22; // Calculate 2st period
    
    	if(T1<T2)
    	{
    	   Frec = 150e6/T1;
    
    	}
    	else if (T2<T1)
    	{
    	        Frec = 150e6/T2;
    
    	}
    
    
    	if(T12<T22)
    			{
    
    			   Frec2 = 150e6/T12;
    			}
    			else if (P22<P12)
    			{
    			   Frec2 = 150e6/T22;
    			}
    
    	}
    
    void configECapture()
    {
    	// ECAP module 1 config
    	ECap1Regs.ECCTL1.bit.CAP1POL = 0;
    	ECap1Regs.ECCTL1.bit.CAP2POL = 0;
    	ECap1Regs.ECCTL1.bit.CAP3POL = 0;
    	ECap1Regs.ECCTL1.bit.CAP4POL = 0;
    
    	ECap1Regs.ECCTL1.bit.CTRRST1 = 1;
    	ECap1Regs.ECCTL1.bit.CTRRST2 = 1;
    	ECap1Regs.ECCTL1.bit.CTRRST3 = 1;
    	ECap1Regs.ECCTL1.bit.CTRRST4 = 1;
    
    	ECap1Regs.ECCTL1.bit.CAPLDEN = 0x1;        //Enable CAP1-4 register loads at capture event time.
    	ECap1Regs.ECCTL1.bit.PRESCALE = 0x0;       //Divide by 1 (i.e,. no prescale, by-pass the prescaler
    	ECap1Regs.ECCTL2.bit.CAP_APWM = 0x0;       //ECAP module operates in capture mode.
    	ECap1Regs.ECCTL2.bit.SWSYNC = 1;       //ECAP module operates in capture mode.
    
    	ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0x0;    //Operate in continuous mode
    	ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0x1;      //Disable sync out signal
    	ECap1Regs.ECCTL2.bit.SYNCI_EN = 0x0;       //Disable sync-in option
    	ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0x1;      //Allow TSCTR to run
    
    	            // Make sure the counter is stopped
    	// ECAP module 2 config
    		ECap2Regs.ECCTL1.bit.CAP1POL = 0;          //Capture Event 1 triggered on a rising edge (RE): EC_RISING 0x0
    		ECap2Regs.ECCTL1.bit.CAP2POL = 0;
    		ECap2Regs.ECCTL1.bit.CAP3POL = 0;
    		ECap2Regs.ECCTL1.bit.CAP4POL = 0;
    
    		ECap2Regs.ECCTL1.bit.CTRRST1 = 1;          //Do not reset counter on Capture Event 1 (absolute time stamp)
    		ECap2Regs.ECCTL1.bit.CTRRST2 = 1;
    		ECap2Regs.ECCTL1.bit.CTRRST3 = 1;
    		ECap2Regs.ECCTL1.bit.CTRRST4 = 1;
    
    		ECap2Regs.ECCTL1.bit.CAPLDEN = 0x1;        //Enable CAP1-4 register loads at capture event time.
    		ECap2Regs.ECCTL1.bit.PRESCALE = 0x0;       //Divide by 1 (i.e,. no prescale, by-pass the prescaler
    		ECap2Regs.ECCTL2.bit.CAP_APWM = 0x0;       //ECAP module operates in capture mode.
    
    		ECap2Regs.ECCTL2.bit.CONT_ONESHT = 0x0;    //Operate in continuous mode
    		ECap2Regs.ECCTL2.bit.SYNCO_SEL = 0x2;      //Disable sync out signal
    		ECap2Regs.ECCTL2.bit.SYNCI_EN = 0x1;       //Disable sync-in option
    		ECap2Regs.ECCTL2.bit.TSCTRSTOP = 0x1;      //Allow TSCTR to run
    
    
    }
    

  • Hi Natalia,

    I'd recommend taking a look at the eCAP Module Reference Guide:
    http://www.ti.com/lit/sprufg4

    My recommendation from my last post is similar to Example 1 (section 7.1).

    You'd then also want to enable synchonization at initialization to make sure that your three eCAP's timers are fully aligned.  
    See the "Multiple eCAP Modules In A 2823x/2833x System" and the "Details of the Counter and Synchronization Block" figures. With these figures in mind, the description I gave in my last email may make more sense.

    Outside of this, you'll need to do some experimentation to find what works for your system.


    Thank you,
    Brett

  • I already tried synchronizing the eCAP1 and eCAP2 timers but I can't know if they really are synchronized so I don't have the phase.
    this is my code, i would like to know what registers can I use and their values to synchronize them.


    #include "DSP28x_Project.h" // Device Headerfile and Examples Include File

    //----------------------------Definición de Funciones---------------------------------

    void configECapture();
    void Frecuencia();

    //---------------------------- Definición de Variables -------------------------------

    double Frec;
    Uint32 T1;
    Uint32 T2;
    Uint32 T3;
    Uint32 P1;
    Uint32 P2;

    double Frec2;
    Uint32 T12;
    Uint32 T22;
    Uint32 T32;
    Uint32 P12;
    Uint32 P22;
    //PHASE
    Uint32 E1;
    Uint32 E2;
    Uint32 E3;
    Uint32 E4;


    void main(void)
    {

    //-------------------- CONFIGURACION INICIAL ------------------------------------------------

    InitSysCtrl(); // Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.

    DINT; //Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts

    InitPieCtrl(); // Initialize the PIE control registers to their default state

    IER = 0x0000; // Disable CPU interrupts and clear all CPU interrupt flags
    IFR = 0x0000;

    InitPieVectTable(); // Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR).

    InitECap1Gpio(); // INICIAR ECAP1
    InitECap2Gpio();
    //-------------------------------- CODIGO PRINCIPAL ---------------------------------------------

    configECapture(); // CONFIGURACION ECAP1


    for(;;)
    {
    //CALCULAR FRECUENCIA
    Frecuencia();
    }

    }

    void Frecuencia()
    {
    T1 = ECap1Regs.CAP1; // Fetch Time-Stamp captured at t1
    T2 = ECap1Regs.CAP2; // Fetch Time-Stamp captured at t2
    T3 = ECap1Regs.CAP3; // Fetch Time-Stamp captured at t3
    P1 = T2-T1; // Calculate 1st period
    P2 = T3-T2; // Calculate 2st period

    T12 = ECap2Regs.CAP1; // Fetch Time-Stamp captured at t1
    T22 = ECap2Regs.CAP2; // Fetch Time-Stamp captured at t2
    T32 = ECap2Regs.CAP3; // Fetch Time-Stamp captured at t3
    P12 = T22-T12; // Calculate 1st period
    P22 = T32-T22; // Calculate 2st period
    //PHASE

    E1=ECap1Regs.TSCTR;
    E2=ECap1Regs.TSCTR;
    E3=T12-T1;
    E4=E1-E2;

    if(P1<P2)
    {
    Frec = 150e6/P1;
    }
    else if (P2<P1)
    {
    Frec = 150e6/P2;
    }

    if(P12<P22)
    {
    Frec2 = 150e6/P12;
    }
    else if (P2<P1)
    {
    Frec2 = 150e6/P22;
    }
    }

    void configECapture()
    {
    // ECAP module 1 config
    ECap1Regs.ECCTL1.bit.CAP1POL = 0; //Capture Event 1 triggered on a rising edge (RE): EC_RISING 0x0
    ECap1Regs.ECCTL1.bit.CAP2POL = 0;
    ECap1Regs.ECCTL1.bit.CAP3POL = 0;
    ECap1Regs.ECCTL1.bit.CAP4POL = 0;
    ECap1Regs.ECCTL1.bit.CTRRST1 = 0; //Do not reset counter on Capture Event 1 (absolute time stamp)
    ECap1Regs.ECCTL1.bit.CTRRST2 = 0;
    ECap1Regs.ECCTL1.bit.CTRRST3 = 0;
    ECap1Regs.ECCTL1.bit.CTRRST4 = 0;
    ECap1Regs.ECCTL1.bit.CAPLDEN = 0x1; //Enable CAP1-4 register loads at capture event time.
    ECap1Regs.ECCTL1.bit.PRESCALE = 0x0; //Divide by 1 (i.e,. no prescale, by-pass the prescaler
    ECap1Regs.ECCTL2.bit.CAP_APWM = 0x0; //ECAP module operates in capture mode.
    ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0x0; //Operate in continuous mode
    ECap1Regs.ECCTL2.bit.SWSYNC=1;
    ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0x1; //Disable sync out signal
    ECap1Regs.ECCTL2.bit.SYNCI_EN = 0x0; //Disable sync-in option
    ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0x1; //Allow TSCTR to run
    // ECAP module 1 config
    // ECAP module 1 config
    ECap2Regs.ECCTL1.bit.CAP1POL = 0; //Capture Event 1 triggered on a rising edge (RE): EC_RISING 0x0
    ECap2Regs.ECCTL1.bit.CAP2POL = 0;
    ECap2Regs.ECCTL1.bit.CAP3POL = 0;
    ECap2Regs.ECCTL1.bit.CAP4POL = 0;
    ECap2Regs.ECCTL1.bit.CTRRST1 = 0; //Do not reset counter on Capture Event 1 (absolute time stamp)
    ECap2Regs.ECCTL1.bit.CTRRST2 = 0;
    ECap2Regs.ECCTL1.bit.CTRRST3 = 0;
    ECap2Regs.ECCTL1.bit.CTRRST4 = 0;
    ECap2Regs.ECCTL1.bit.CAPLDEN = 0x1; //Enable CAP1-4 register loads at capture event time.
    ECap2Regs.ECCTL1.bit.PRESCALE = 0x0; //Divide by 1 (i.e,. no prescale, by-pass the prescaler
    ECap2Regs.ECCTL2.bit.CAP_APWM = 0x0; //ECAP module operates in capture mode.
    ECap2Regs.ECCTL2.bit.CONT_ONESHT = 0x0; //Operate in continuous mode
    ECap2Regs.ECCTL2.bit.SWSYNC=1;
    ECap2Regs.ECCTL2.bit.SYNCO_SEL = 0x1; //Disable sync out signal
    ECap2Regs.ECCTL2.bit.SYNCI_EN = 0x0; //Disable sync-in option
    ECap2Regs.ECCTL2.bit.TSCTRSTOP = 0x1; //Allow TSCTR to run

    }



    PLease help me.
  • Hi Natalia,

    You don't seem to be doing anything special with SYNCO_SEL and SYNCI_EN.  You should be.  Again, refer to the figures I described in my last post.

    To test that things are or are not working, you can use the watch window.  With your code running you should see each eCAP's TSCTR increment, when in real time mode.  You can then write to one of the eCAP's TSCTR register to make them unsynchronized.  They should stay unsynchronized until you write to eCAP1's SWSYNC register.

    Hopefully this helps!


    Thank you,
    Brett