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.

TM4C1294NCPDT: timer capture mode to get frequency

Part Number: TM4C1294NCPDT

Hello 

i am trying to calculate frequency of an input  signal with timer capture mode.

however it running good but sometime the result get 0 value .

how could this happen ?

how  eliminate  this error?

#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_ints.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/fpu.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
void calc_freq(void)
;
volatile uint32_t  g_ui32Counter = 0;
uint32_t ui32SysClock=0,    time=0, start=0,end=0;
bool flag=false;
void
SysTickIntHandler(void)
{
    //
    // Update the Systick interrupt counter.
    //
    if(g_ui32Counter>10000000){
        g_ui32Counter=0;}
    g_ui32Counter++;


}

void
InitConsole(void)
{

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioConfig(0, 115200, 16000000);
}
void edge_capture(void)
{
    TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT);
  if (flag==false){
    start = TimerValueGet(TIMER1_BASE, TIMER_B);
    flag=true;
  }
    else if (flag==true){
        end=TimerValueGet(TIMER1_BASE, TIMER_B);
        time=end-start;
       flag=false;
       TimerLoadSet(TIMER1_BASE, TIMER_B,(10000-1));

   }
    }
void Configure_timer(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_3);
    GPIOPinConfigure(GPIO_PD3_T1CCP1);
    TimerConfigure(TIMER1_BASE,(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_CAP_TIME_UP));
    TimerControlEvent(TIMER1_BASE,TIMER_B,TIMER_EVENT_POS_EDGE);
    TimerPrescaleSet(TIMER1_BASE, TIMER_B, (120-1));
    TimerLoadSet(TIMER1_BASE, TIMER_B,(10000-1));
    IntRegister(INT_TIMER1B, edge_capture);
    TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT);
    TimerIntEnable(TIMER1_BASE, TIMER_CAPB_EVENT);
    IntEnable(INT_TIMER1B);
    TimerEnable(TIMER1_BASE, TIMER_B);
    }

int main(void)
{
    FPULazyStackingEnable();
    ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                       SYSCTL_OSC_MAIN |
                                       SYSCTL_USE_PLL|SYSCTL_CFG_VCO_480), 120000000);
    InitConsole();
    Configure_timer();
    SysTickPeriodSet(ui32SysClock/1000000);
    IntMasterEnable();
    SysTickIntEnable();
    SysTickEnable();
    while(1)
    {
if(time!=0)
{
calc_freq();
}
    }
}
void calc_freq(void)
{
float y;
y=time/1200 ;
y=1/y;
time=100000*y;
UARTprintf("start :%d\n",time);
time=0;
end=0;
start=0;
}

 

  • Hi,
    How fast is the input signal? If your signal is too fast then it is possible that you may not be able to capture the time correctly. For example, if the timer detects an edge and it will capture a timer value of X. It will then generate an interrupt. However, it takes some time (about 12 cycles) for the CPU to enter the interrupt ISR and once it is inside the ISR it needs to execute some instructions. As in your case it needs to clear the status register and determines if the flag is true or false before it calls the TimerValueGet. If your next edge has come too fast then it is possible that the timer has already saved the next timer value (let's call it Y) overwriting the previous X value. By the time you call TimerValueGet it has changed from X to Y. So your start and end can be both Y and the difference will be zero.

    If you have a fast signal you might want to consider routing that input to two different timer modules. In this approach you can take the difference between the two different timer values from two different timer modules. For example, use the timer A to record the start and timer B to record the end and take the difference between them.
  • Yes or may be too small I test it from 30kHz to 1kHz