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.

CCS/LAUNCHXL-F28069M: Frequency Meter. Guidelines and Optimizing

Part Number: LAUNCHXL-F28069M


Tool/software: Code Composer Studio

Hi everyone.

I wrote a code for a frequency meter but it has some issues. So I decided to post this new thread.

Here it is the code I did.

#include "F2806x_Device.h"
#include "F2806x_Examples.h"
#include "DSP28x_Project.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>


extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;

__interrupt void ecap1_isr(void);
Uint32  t1,t2,t3,t4,t;
Uint32  conteo;


float f;
void main(void)
{
    InitSysCtrl();                       
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadEnd); 
                                                                             
                                                                             
    InitFlash();                        
    EALLOW;                             
    GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;   // PIN35 ON LAUNCHPAD
    GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0; 
    GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 3;  
    EDIS;                                
    DINT;                                
    InitPieCtrl();                       
    IER = 0x0000;                       
    IFR = 0x0000;                       
    InitPieVectTable();                  
    EALLOW;                              
    PieVectTable.ECAP1_INT = &ecap1_isr; 
    EDIS;                                
    t1=0;
    t2=0;
    t3=0;
    t4=0;
    t=0;
    conteo = 0;
    IER |= M_INT4;                      
    PieCtrlRegs.PIEIER4.bit.INTx1 = 1;  
    EINT;                               
    ERTM;                               
    EALLOW;                             
    ECap1Regs.ECEINT.all = 0x0000; 
    ECap1Regs.ECCLR.all = 0x0000;  
    ECap1Regs.ECCTL1.bit.CAP1POL= 0x1;       
    ECap1Regs.ECCTL1.bit.CAP2POL= 0x1;       
    ECap1Regs.ECCTL1.bit.CAP3POL= 0x1;       
    ECap1Regs.ECCTL1.bit.CAP4POL= 0x1;       
    ECap1Regs.ECCTL1.bit.CTRRST1 = 0x1;      
    ECap1Regs.ECCTL1.bit.CTRRST2 = 0x1;      
    ECap1Regs.ECCTL1.bit.CTRRST3 = 0x1;      
    ECap1Regs.ECCTL1.bit.CTRRST4 = 0x1;      
    ECap1Regs.ECCTL1.bit.CAPLDEN = 0x1;      
    ECap1Regs.ECCTL1.bit.PRESCALE = 0x1;     
    ECap1Regs.ECCTL2.bit.CAP_APWM = 0x0;     
    ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0x0;  
    ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0x2;    
    ECap1Regs.ECCTL2.bit.SYNCI_EN = 0x0;     
    ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0x1;    
    ECap1Regs.ECEINT.bit.CEVT4 = 1;          
    GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;     
    GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;    
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;      
    EDIS;
    for(;;)
    {
        EALLOW;                                
        GpioDataRegs.GPBSET.bit.GPIO34 = 1;    
        DELAY_US(100000);                      
        GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;  
        DELAY_US(100000);                      
        f=180734328.8/t;                      
                                               
        EDIS;                                  
    }


}
__interrupt void
ecap1_isr(void)
{

    conteo++;
    t1=ECap1Regs.CAP1;                       
    t2=ECap1Regs.CAP2;                       
    t3=ECap1Regs.CAP3;                      
    t4=ECap1Regs.CAP4;                       
    t=(t1+t2+t3+t4)/4;                       
    ECap1Regs.ECCLR.bit.CEVT4 = 1;          
    ECap1Regs.ECCLR.bit.INT = 1;             
    ECap1Regs.ECCTL2.bit.REARM = 1;                                               
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;  
}

As you see I used the eCAP module and the CAP1-CAP4 Load, in the falling edge, then I added the 4 captures and I got an average.

The number 180734328.8 came from the Timer Stamp at 1 Hz signal square. 

It has an error of 10 mHz.

The issue with this code is when I put a signal less of 10 Hz in  35 pin of the  LAUNCHXL-F28069M it is slow to update the data, it freezes, I think is when the CAP1- CAP4 is generating, then the data updates itself and then all the things are good again.

I think there are some other ways to do it, If yes, please give some guidelines or, on the other hand, if it is possible to optimize this.

Regards

Mike

  • Mike,

    The way you have the eCAP configured your ISR will only run every 4th falling edge. If your signal is 10Hz you will only get an update at a rate of 2.5Hz (10Hz/4).

    If you would like to average your last four values and also receive an update every time you the eCAP is triggered then would you suggest that you use a "rolling average".

    To do this configure the eCAP to trigger an ISR after every event. You should keep an array of length 4(or any number of values you desire to average across) and an index that will always point to the oldest value in the array. When you receive a new value write it into the array, replacing the oldest value,  and recalculate your average frequency.

    Regards,
    Cody 

  • Hi Cody

    I used this at the ISR routine, It worked for me but I see a little delay in the update of the data. The last part you said you were talking about pointers, but I'm not good at it. I think it could be solve the issue. Also I changed the configuration just to do an ISR after every event. Do you think there are more ways to do this frequency meter?

        for(i=0;i<3;i++) 
        {
          
            t[i]=ECap1Regs.CAP1;
            T=t[i];
        }

    Regards

    Mike

  • Mike,

    You're moving in the right direction, but I think that code will simply fill all elements in the array "t" with the same value. Then assign T to the value in the last element.

    To get the fastest response using a rolling average you will need to add the latest value from the eCAP to one element of the array each time the ISR is triggered. Then increment your index "i" once, recalculate your average value and finally return from the ISR. I would suggest using the Modulus function or something similar on "i" to ensure that it does NOT increment past the number of elements in the array "t"

    Regards,
    Cody