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.

Tiva C frequency measurement

Other Parts Discussed in Thread: TM4C123GH6PM

Hii all

I am using

Tiva C series arm cortex M4 TM4C123GH6PM Launchpad. i wrote a code to measure frequency of input pulse given at Port F pin 4. compiler is not showing any error but i m not getting desired result. kindly help.

#include<tm4c123gh6pm.h>
#include<stdbool.h>
#include<stdint.h>
#include<interrupt.h>
#include<sysctl.h>
#include<gpio.h>
#include<hw_memmap.h>
#include<timer.h>

void PortFIntHandler(void);
void PortFInit(void);
void TimerInit(void);

volatile unsigned long ui32Loop,Count,f;
float Freq;
int main(void){
PortFInit(); // initialize GPIO Port F interrupt
while(1)
{}
}

void PortFInit(void){
IntDisable(INT_GPIOF);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3);
GPIO_PORTF_PUR_R |= 0x10; // enable weak pull-up on PF4
IntEnable(INT_GPIOF);
GPIOIntEnable(GPIO_PORTF_BASE | GPIO_PIN_4, GPIO_FALLING_EDGE);
}

void PortFIntHandler(void){
if(f!=1)
TimerInit();
else
{
GPIO_PORTF_ICR_R = 0x10; // acknowledge flag4
Count=TimerValueGet(TIMER0_BASE, TIMER_A);
Freq=80000000/Count;
TimerInit();
f=1;
}}

void TimerInit(void)
{
TimerDisable(TIMER0_BASE,TIMER_A);
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP);
TimerLoadSet(TIMER0_BASE, TIMER_A, 0xFFFFFFFF);
TimerEnable(TIMER0_BASE, TIMER_A);
}

  • Hi Prashant,

    What result are you exacly getting and why is it rong?

     

    Remember to use a SysCtlDelay(3) after the SysCtlPeripheralEnable. You need to wait some clk cycles before you can mess with the registers of that peripheral.

    I don't see anything enabling the Timer peripheral.

    I also don't see anything to output the value so you can see it, i assume you omitted that part to be easier to read here?

    Do you have the handler in the startup.c? 

    You should try to avoid functions calls inside the interrupt so it's faster.

  • hii luis,

    my code is going in an infinite loop ie FaultISR(); so i am getting zero.

    now i am using SysCtlDelay(3) after enabling register but still no improvement.

    enabled the TIMER0 with SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); but no improvement.

    here 'count" is the variable.

    yes i have interrupt handler in startup.c

    Regards

    Prashant

  • if you get a FaultISR you should always say so.

    To me not getting the desired results i intended as you were getting wrong values.

    I didn't even see before but GPIOIntEnable(GPIO_PORTF_BASE | GPIO_PIN_4, GPIO_FALLING_EDGE); is completely wrong. It's 

    GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);

    and to set the pin to falling edge it's

    GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE);


    You seem to be missing key and basic stuff. Maybe this will help you understand how to configure simple GPIO interrupts. https://sites.google.com/site/luiselectronicprojects/tutorials/tiva-gpio/digital-input-with-interrupt
  • hii luis

    i got your point. after modifications my code is working but i am unable to reset count value. after disabling and enabling the counter, i am not getting how to restart the count value.

    regards

    prashant

  • Hi Prashant ,

     

    To restart the count value TimerLoadSet should do. if it isn't working could you please post your current code? 

  • Hii Luis

    now code is not going in FaultISR but it is not reseting count in timer. please have a look.

    #include<tm4c123gh6pm.h>
    #include<stdbool.h>
    #include<stdint.h>
    #include<interrupt.h>
    #include<sysctl.h>
    #include<gpio.h>
    #include<hw_memmap.h>
    #include<timer.h>
    void PortFIntHandler(void);
    void PortFInit(void);
    void TimerInit(void);
    volatile unsigned long FallingEdges = 0;
    volatile unsigned long ui32Loop,Count;
    volatile unsigned long f=0;
    float Freq;

    int main(void){
    TimerInit();
    PortFInit(); // initialize GPIO Port F interrupt
    while(1){
    GPIO_PORTF_DATA_R |= 0x08;

    //
    // Delay for a bit.
    //
    for(ui32Loop = 0; ui32Loop < 20000; ui32Loop++)
    {
    }

    //
    // Turn off the LED.
    //
    GPIO_PORTF_DATA_R &= ~(0x08);

    //
    // Delay for a bit.
    //
    for(ui32Loop = 0; ui32Loop < 20000; ui32Loop++)
    {
    }

    }
    }
    void PortFInit(void){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlDelay(3);
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3);
    GPIO_PORTF_PUR_R |= 0x10; // enable weak pull-up on PF4
    GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE);
    IntEnable(INT_GPIOF);
    GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);

    }

    void PortFIntHandler(void){
    GPIO_PORTF_ICR_R = 0x10; // acknowledge flag4
    FallingEdges = FallingEdges + 1;
    Count=TimerValueGet(TIMER0_BASE, TIMER_A);
    Freq=80000000/Count;
    TimerLoadSet(TIMER0_BASE, TIMER_A, 0x00000000);
    TimerInit();
    }

    void TimerInit(void)
    {
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerDisable(TIMER0_BASE,TIMER_A);
    SysCtlDelay(3);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP);
    TimerLoadSet(TIMER0_BASE, TIMER_A, 0x00FFFFFF);
    TimerEnable(TIMER0_BASE, TIMER_A);
    }

    Regards

    Prashant

  • First, really try to avoid function calls inside the interrupt handler.

    Second, inside the interrupt handler you shouldn't use SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); nor TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP);.  That should be only in the beginning, once. In this case i don't think it will cause problems besides making the interrupt longer than it needs to be.

    It's simple, you are using a 32bit timer in count up. I assume you want to count starting at 0. So you should Load the value 0 into the timer. 

  • hii luis

    as per your instruction, i have modified my code. removed function calls in ISR.

    new code is

    //working but timer count is not reseting
    #include<tm4c123gh6pm.h>
    #include<stdbool.h>
    #include<stdint.h>
    #include<interrupt.h>
    #include<sysctl.h>
    #include<gpio.h>
    #include<hw_memmap.h>
    #include<timer.h>
    void PortFIntHandler(void);
    void PortFInit(void);
    volatile unsigned long FallingEdges = 0;
    volatile unsigned long ui32Loop,Count;
    volatile unsigned long f=0;
    float Freq;

    int main(void){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    SysCtlDelay(3);
    TimerDisable(TIMER0_BASE,TIMER_A);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP);
    TimerEnable(TIMER0_BASE, TIMER_A);
    PortFInit(); // initialize GPIO Port F interrupt
    while(1){
    GPIO_PORTF_DATA_R |= 0x08;

    //
    // Delay for a bit.
    //
    for(ui32Loop = 0; ui32Loop < 20000; ui32Loop++)
    {
    }

    //
    // Turn off the LED.
    //
    GPIO_PORTF_DATA_R &= ~(0x08);

    //
    // Delay for a bit.
    //
    for(ui32Loop = 0; ui32Loop < 20000; ui32Loop++)
    {
    }

    }
    }
    void PortFInit(void){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlDelay(3);
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3);
    GPIO_PORTF_PUR_R |= 0x10; // enable weak pull-up on PF4
    GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE);
    IntEnable(INT_GPIOF);
    GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);

    }

    void PortFIntHandler(void){
    GPIO_PORTF_ICR_R = 0x10; // acknowledge flag4
    FallingEdges = FallingEdges + 1;
    Count=TimerValueGet(TIMER0_BASE, TIMER_A);
    Freq=80000000/Count;
    TimerLoadSet(TIMER0_BASE, TIMER_A, 0x00000000);
    }

    still counter is not reseting :( . please look.

    regards

    prashant

  • hii luis

    finally my  code is working. Thanks a lot.

    Regards

    Prashant

  • Hi Prashant,

    Good to know you figured it out. Could you please post the final code and describe what was the problem from the last code? To help other users that search for similar problems to theirs.

    Please use the "Insert code tool" on the top right of the editor, it's looks like this: </>

  • hii
    this code is working.still counter is not reseting but i used some other technique to measure count.
    //working code // connect PF4 and PF3 #include<tm4c123gh6pm.h> #include<stdbool.h> #include<stdint.h> #include<interrupt.h> #include<sysctl.h> #include<gpio.h> #include<hw_memmap.h> #include<timer.h> void PortFIntHandler(void); void PortFInit(void); volatile unsigned long FallingEdges = 0; volatile unsigned long ui32Loop,Count; volatile unsigned long Old_Count,Elapsed_Count; volatile unsigned long New_Count=0; float freq; int main(void){ SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); SysCtlDelay(3); TimerDisable(TIMER0_BASE,TIMER_A); TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP); TimerLoadSet(TIMER0_BASE, TIMER_A, 0x00FFFFFF); TimerEnable(TIMER0_BASE, TIMER_A); PortFInit(); // initialize GPIO Port F interrupt while(1) { GPIO_PORTF_DATA_R |= 0x08; for(ui32Loop = 0; ui32Loop < 16582; ui32Loop++) {} GPIO_PORTF_DATA_R &= ~(0x08); for(ui32Loop = 0; ui32Loop < 16582; ui32Loop++) {} } } void PortFInit(void){ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); SysCtlDelay(3); GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4); GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3); GPIO_PORTF_PUR_R |= 0x10; // enable weak pull-up on PF4 GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE); IntEnable(INT_GPIOF); GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4); } void PortFIntHandler(void){ GPIO_PORTF_ICR_R = 0x10; // acknowledge flag4 FallingEdges = FallingEdges + 1; Old_Count=New_Count; New_Count=TimerValueGet(TIMER0_BASE, TIMER_A); if(New_Count>Old_Count) { Elapsed_Count=New_Count-Old_Count; freq=16011202/Elapsed_Count; } }

    regards

    prashant

  • Thank you for posting your code. May I know the purpose of while loop and blinking green LED.
    while(1) { GPIO_PORTF_DATA_R |= 0x08;
    for(ui32Loop = 0; ui32Loop < 16582; ui32Loop++)
    {} GPIO_PORTF_DATA_R &= ~(0x08);
    for(ui32Loop = 0; ui32Loop < 16582; ui32Loop++)
    {} }
    And also how the frequency counted using the following expression? How the value "16011202" is decided?
    freq=16011202/Elapsed_Count;
  • If I may - poster's report, "Code is working - yet still count is not resetting" does not yield (complete) confidence.

    Specifically - you've not noted (nor challenged) poster's: "TimerLoadSet(TIMER0_BASE, TIMER_A, 0x00FFFFFF);"

    Such forces his periodic, up counter to start from an extremely high value - does it not?   And that fact almost insures that we'll enocunter (dreaded) timer "roll-over!"

    Poster's code seems to avoid any (handling) of this (likely) timer roll-over - instead comparing (only) against timer values.  The fact that the timer was not reset (as Luis - several times - suggested) points to inconsistencies and/or grave errors in these results.

    Poster's (unique) 16011202 (so much exactness here - so little wrt roll-overs!) is (likely) the result of his measurement of system clock.  16MHz should prove (perfectly) fine for all but the (most demanding) G'ovt Work!

    To me - frequency measurement is best done by opening a counter for a precise (and well known) duration - and counting the number of signals arriving during that interval.  That count data is then safely stored - and the stored value is then scaled to frequency.  The frequency to be measured determines the counter's "open time."   Frequency then is determined via: # of counts / time interval of measurement.   By properly clearing both the timer/counter - and timer interval - there is NO need to subtract past from current measures.

  • your code work for this range [1 to 2 Mhz] ?
  • Poster was last seen/heard here, "Sept 2014." (mousing over a poster's name enables review of "Recent Activity.")

    If you trust this code (which I do not) you may test/verify - first at lower frequencies - and then gradually at higher ones - and achieve your answer...
  • Hi, I tested it at 1 khz. It was working fine. You can use averaging method for more accurate results.
  • Poster's desired usage was 1000x that 1KHz...
  • Hello cb1,

    Indeed. Pulse width measurements at 1-2MHz should be very much doable.
  • I can not measures at 1-2 Mhz ... any help?
    some code?
    I use this code :

    #include<tm4c123gh6pm.h>
    #include<stdbool.h>
    #include<stdint.h>
    #include<interrupt.h>
    #include<sysctl.h>
    #include<gpio.h>
    #include<hw_memmap.h>
    #include<timer.h>

    void PortFIntHandler(void);
    void PortFInit(void);
    volatile unsigned long FallingEdges = 0;
    volatile unsigned long ui32Loop,Count;
    volatile unsigned long Old_Count,Elapsed_Count;
    volatile unsigned long New_Count=0;
    float freq;
    int main(void){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    SysCtlDelay(3);
    TimerDisable(TIMER0_BASE,TIMER_A);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP);
    TimerLoadSet(TIMER0_BASE, TIMER_A, 0x00FFFFFF);
    TimerEnable(TIMER0_BASE, TIMER_A);
    PortFInit(); // initialize GPIO Port F interrupt
    while(1)
    {
    GPIO_PORTF_DATA_R |= 0x08;
    for(ui32Loop = 0; ui32Loop < 16582; ui32Loop++)
    {}
    GPIO_PORTF_DATA_R &= ~(0x08);
    for(ui32Loop = 0; ui32Loop < 16582; ui32Loop++)
    {}
    }
    }
    void PortFInit(void){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlDelay(3);
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3);
    GPIO_PORTF_PUR_R |= 0x10; // enable weak pull-up on PF4
    GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE);
    IntEnable(INT_GPIOF);
    GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4);
    }

    void PortFIntHandler(void){
    GPIO_PORTF_ICR_R = 0x10; // acknowledge flag4
    FallingEdges = FallingEdges + 1;
    Old_Count=New_Count;
    New_Count=TimerValueGet(TIMER0_BASE, TIMER_A);
    if(New_Count>Old_Count)
    {
    Elapsed_Count=New_Count-Old_Count;
    freq=16011202/Elapsed_Count;
    }
    }


    any help please ?
  • Hello Mohammed,

    Please use the Capture Time mode for putting time stamps instead of periodic count mode.
  • Hello Amit !! How to do this ? any example please ? I'm new in this.
  • Hello Mohammad

    Please refer to the example in TivaWare for D:\ti\TivaWare_C_Series-2.1.3.156\examples\peripherals\timer\edge_count.c

    Now this example counts the edges. Instead of using the Edge Count for configuration, please use Edge Time during configuration.
  • I'm trying to Build Parsha's code, and .... NOTHING.
    errors:

    Description Resource Path Location Type
    #10010 errors encountered during linking; "TIVA_Freq.out" not built
    #10234-D</a> unresolved symbols remain
    gmake: *** [TIVA_Freq.out] Error 1
    gmake: Target 'all' not remade because of errors.
    unresolved symbol GPIOIntEnable, first referenced in ./main.obj
    unresolved symbol GPIOIntTypeSet, first referenced in ./main.obj
    unresolved symbol GPIOPinTypeGPIOInput, first referenced in ./main.obj
    unresolved symbol GPIOPinTypeGPIOOutput, first referenced in ./main.obj
    unresolved symbol IntEnable, first referenced in ./main.obj
    unresolved symbol SysCtlDelay, first referenced in ./main.obj
    unresolved symbol SysCtlPeripheralEnable, first referenced in ./main.obj
    unresolved symbol TimerConfigure, first referenced in ./main.obj
    unresolved symbol TimerDisable, first referenced in ./main.obj
    unresolved symbol TimerEnable, first referenced in ./main.obj
    unresolved symbol TimerLoadSet, first referenced in ./main.obj
    unresolved symbol TimerValueGet, first referenced in ./main.obj
  • Hello Mohammed

    Please add the driverlib.lib from TivaWare to the linker stage of the build process. This can be changed by going to the project settings.