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: Measure period mode capture

Part Number: TM4C1294NCPDT

Hello.
I am writing a code to measure the period of an oscillator circuit 555.
I configured two timers, Timer0A for interrupts every 1 second, and Timer1A for capture mode.
Timer0A interruption is working perfectly, but Timer1A is not being directed to interrupt.

Follows the configuration code ...
I already researched the forum on the subject but I could not solve the problem.
NOTE: The code is not finished, but it is not being directed to the interrupt.
Thank you.

#define VET_TRANSMIT 20
#define VET_PERIOD_FREQ 50
#define FREQ_MICRO 16000000.0

void Config_Clock(void);
void Config_Timer(void);

uint32_t g_ui32SysClock;
uint32_t tempo = 0, allCaptured = 0;

volatile uint32_t count, edge1, edge2, period[VET_PERIOD_FREQ], t = 0, l = 0,
        flag = 0, tx_index = 0, temp = 0, segundo = 0;
volatile float freq[VET_PERIOD_FREQ], cap = 0, media_freq = 0, soma_freq = 0;
char buffer[VET_TRANSMIT], i = 0;

void main(void)
{

    Config_Clock();
    Config_Timer();

    while (1)
    {

        flag = 0; // Initialise count for new capture

        if (allCaptured == 1)
        {

            allCaptured = 0;

            if (edge2 > edge1)
            {                         // Ignore calculation if overflow occured

                period[t] = edge2 - edge1;         // Calculate Period
                t++;
                edge1 = edge2;

            }
        }
    }
}

void Config_Clock(void)
{

    g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480),
                                        120000000);
}

void Config_Timer(void)
{

    //--------------Config TimerA0 Interupcao cada 1s---------------//
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);  //habilita clock para o timer
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); // configura o timer para interpcoes periodicas
    TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock); //gera uma interupcao a cada 1s
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    TimerEnable(TIMER0_BASE, TIMER_A);
    IntEnable(INT_TIMER0A);

    //----------------------Timer2A Mode Capture--------------//
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); // Enable the GPIO port that is used for the input edge counting
    GPIOPinTypeTimer(GPIO_PORTM_BASE, GPIO_PIN_0); // Configure PM0 as the positive edge capture on Timer 2A
    GPIOPinConfigure(GPIO_PM0_T2CCP0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2); // For use with edge-time mode
    TimerConfigure(TIMER2_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME));
    TimerControlEvent(TIMER2_BASE, TIMER_A, TIMER_EVENT_NEG_EDGE);
    TimerIntEnable(TIMER2_BASE, TIMER_CAPA_EVENT);
    TimerEnable(TIMER2_BASE, TIMER_A); // Enable the timers
    IntEnable(INT_TIMER2A); // Enable interrupt for Timer s
    IntMasterEnable();
}

void Interrupt_Timer0A(void)
{

    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    tempo++;

}

void Interrupt_Timer2A(void)
{

    uint32_t InterruptFlags = TimerIntStatus(TIMER2_BASE, true);

    if (InterruptFlags & TIMER_CAPA_EVENT)
    {

       if (!flag)
        {
            // Capture first edge timer value and indicate that the program has captured first on
            edge1 = MAP_TimerValueGet(TIMER2_BASE, TIMER_A);
            flag = 1;
        }
        // Once falling edge has been captured, store the value of the second rising edge which completes the sample
        else if (flag)
        {
            edge2 = MAP_TimerValueGet(TIMER2_BASE, TIMER_A);
            // Indicates that all three edges required for calculations have been capture and is ready to calculate
            allCaptured = 1;

        }
    }
    // Clear interrupt flag to enable to interrupt to occur once more.
    TimerIntClear(TIMER2_BASE, TIMER_CAPA_EVENT);

}

  • You setup TimerA1 to count falling edges, but did not set a match value. Did you want to generate an interrupt after some number of falling edges? If you are measuring a frequency by counting edges for one second, then you just want to read the timerA1 count value and then clear it in the one second interrupt routine.
  • Boa tarde Ricardo,

    Do yourself and willingfull helpers here a favor: edit your message, use Rich Formatting, cut the program code and past using the </> option. That will make it much easier for us to read and help.

    You want your timer on TIMER_CFG_A_CAP_TIME mode, not COUNT mode.

    Also, pay attention: you will evaluate the time difference between the current transition and the previous transition, by looking at the timer counter - but note that the timer width is limited, so you need to properly consider timer roll over, ok?

    Finally, I don't have a problem with that - but it might be a good idea to start using English comments on your code... particularly when you ask for feedback here... Good old Portuguese is useful for just a few 260 million people...

    Cheers

    Bruno
  • Bruno Saraiva said:
    Good old Portuguese is useful for just a few 260 million people...

    And are not most of those (260M) resident w/in Brazil?         Must note that your language is so much more lyrical/musical than English.

    (note: cb1/staff have "restored" their "red-gun gain" now that your new avatar has landed...)

  • Glad to hear! I hope that this short period has not unbalancedly aged your R-G-B matrix!

    Yes, most of those 260M speak "Brazilian", as opposed to the "real" Portuguese.
  • Bruno: "as opposed to the "real" Portuguese."

    You mean like we (transplanted/escaped) New York City guys speak, "real English?" (Dese, Dem, Dose, Gimme etc...)
  • cb1_mobile said:
    You mean like we (transplanted/escaped) New York City guys speak, "real English?"

    Absolutely the contrary! I actually said that the escapers (in these case the ones who crossed the Equator) - speak Brazilian, while Portuguese is a language of few!

    "Real English" is limited to within the Land of The Queen!

    Now, I wonder if Poster ever got the reply to his question? Was it useful? Zero feedback makes it a bit hard on incentive and even quality control...

  • Hello. I got the code to be redirected to the interrupt as it should be. However, it is still not working as expected.

    As previously commented, I am capturing the negative edges of a square wave from an IC 555 to calculate the period and frequency.

    If anyone can help, I appreciate it. Follow the code

    Note: Timer0A does not have border count counting.


    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    #include "driverlib/flash.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/systick.h"
    #include "driverlib/timer.h"
    #include "driverlib/rom_map.h"
    #include "utils/locator.h"
    #include "utils/lwiplib.h"
    #include "utils/uartstdio.h"
    #include "utils/ustdlib.h"
    #include "httpserver_raw/httpd.h"
    #include "drivers/pinout.h"
    #include "io.h"
    #include "cgifuncs.h"
    #include "inc/hw_gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include <stdlib.h>
    #include <string.h>
    
    #include "driverlib/ssi.h"
    #include "spi.h"
    #include "nrf24/nrf24.h"
    #include <math.h>
    #include <stdio.h>
    
    #define VET_TRANSMIT 20
    #define VET_PERIOD_FREQ 50
    #define FREQ_MICRO 16000000.0
    
    void Config_Clock(void);
    void Config_Timer(void);
    
    uint32_t g_ui32SysClock;
    uint32_t tempo = 0, allCaptured = 0;
    
    volatile uint32_t count, edge1, edge2, period[VET_PERIOD_FREQ], t = 0, l = 0,
    flag = 0, tx_index = 0, temp = 0, segundo = 0;
    volatile float freq[VET_PERIOD_FREQ], cap = 0, media_freq = 0, soma_freq = 0;
    char buffer[VET_TRANSMIT], i = 0;
    
    void main(void)
    {
    
    Config_Clock();
    Config_Timer();
    
    while (1)
    {
    
    flag = 0; // Initialise count for new capture
    
    if (allCaptured == 1)
    {
    
    allCaptured = 0;
    
    if (edge2 > edge1)
    { // Ignore calculation if overflow occured
    
    period[t] = edge2 - edge1; // Calculate Period
    t++;
    edge1 = edge2;
    
    }
    }
    }
    }
    
    void Config_Clock(void)
    {
    
    g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
    SYSCTL_OSC_MAIN |
    SYSCTL_USE_PLL |
    SYSCTL_CFG_VCO_480),
    120000000);
    }
    
    void Config_Timer(void)
    {
    
    //--------------Config TimerA0 Interupcao cada 1s---------------//
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); //habilita clock para o timer
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); // configura o timer para interpcoes periodicas
    TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock); //gera uma interupcao a cada 1s
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    TimerEnable(TIMER0_BASE, TIMER_A);
    IntEnable(INT_TIMER0A);
    
    //----------------------Timer2A Mode Capture--------------//
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); // Enable the GPIO port that is used for the input edge counting
    GPIOPinTypeTimer(GPIO_PORTM_BASE, GPIO_PIN_0); // Configure PM0 as the positive edge capture on Timer 2A
    GPIOPinConfigure(GPIO_PM0_T2CCP0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2); // For use with edge-time mode
    TimerConfigure(TIMER2_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME));
    TimerControlEvent(TIMER2_BASE, TIMER_A, TIMER_EVENT_NEG_EDGE);
    TimerIntEnable(TIMER2_BASE, TIMER_CAPA_EVENT);
    TimerEnable(TIMER2_BASE, TIMER_A); // Enable the timers
    IntEnable(INT_TIMER2A); // Enable interrupt for Timer s
    IntMasterEnable();
    }
    
    void Interrupt_Timer0A(void)
    {
    
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    tempo++;
    
    }
    
    void Interrupt_Timer2A(void)
    {
    
    uint32_t InterruptFlags = TimerIntStatus(TIMER2_BASE, true);
    
    if (InterruptFlags & TIMER_CAPA_EVENT)
    {
    
    if (!flag)
    {
    // Capture first edge timer value and indicate that the program has captured first on
    edge1 = MAP_TimerValueGet(TIMER2_BASE, TIMER_A);
    flag = 1;
    }
    // Once falling edge has been captured, store the value of the second rising edge which completes the sample
    else if (flag)
    {
    edge2 = MAP_TimerValueGet(TIMER2_BASE, TIMER_A);
    // Indicates that all three edges required for calculations have been capture and is ready to calculate
    allCaptured = 1;
    
    }
    }
    // Clear interrupt flag to enable to interrupt to occur once more.
    TimerIntClear(TIMER2_BASE, TIMER_CAPA_EVENT);
    
    }

  • Hello Bob.
    I just need to calculate the period of a signal from an IC 555 ..
    This period will be variable, so I need to monitor the variation of this period.
    This frequency ranges from approximately 500kHz to 10kHz.

    TimerA0 is configured for other applications.

    I have the code below ... if you can help thanks.
    Thank you.
  • Dalacort,
    You did not even read the (short) paragraph where I asked you to post your code in a formatted way.
    Interaction on this forum is on a "voluntary help" basis. If you don't read one sentence that someone post, it is unlikely that anyone else will read a complete code and try to find errors in it... PARTICULARLY if the code is NOT formatted.
    Regards
    Bruno
  • Hello.
    My code is running the correct way now thanks to a long weekend ..

    But you are not calculating the Period yet, Frequency is correct.
    I have an input signal of the IC 555 of 320Khz and I still have not been able to reach this value with the number of counts I got.

    Could it be my main clock being configured wrong?

    If anyone can help, I appreciate it.
    Thank you

    #define VET_TRANSMIT 20
    #define VET_PERIOD_FREQ 50
    #define FREQ_MICRO 16000000.0
    
    void Config_Clock(void);
    void Config_Timer(void);
    
    uint32_t g_ui32SysClock;
    uint32_t t = 0;
    
    volatile uint32_t edge1, edge2, period[VET_PERIOD_FREQ], flag = 0, temp = 0, allCaptured = 0;
    
    
    
    void main(void)
    {
    
        Config_Clock();
        Config_Timer();
    
        while (1)
        {
           // flag = 0;
                  if (allCaptured == 1){
    
                      if (edge2 > edge1){    // Ignore calculation if overflow occured
    
                          period[t] = edge2 - edge1;         // Calculate Period
                          t++;
                          //edge1 = edge2;
                          allCaptured = 0;
    
                       if(t==VET_PERIOD_FREQ){
                          t=0;
                      }
                  }
                      else{
                          allCaptured = 0;
    
                      }
    
                  }
    
    
        }
    }
    
    void Config_Clock(void)
    {
    
        g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
        SYSCTL_OSC_MAIN |
        SYSCTL_USE_PLL |
        SYSCTL_CFG_VCO_480), 120000000);
    }
    
    void Config_Timer(void)
    {
    
        //--------------Config TimerA0 Interupcao cada 1s---------------//
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);  //habilita clock para o timer
        TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); // configura o timer para interpcoes periodicas
        TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock); //gera uma interupcao a cada 1s
        TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        TimerEnable(TIMER0_BASE, TIMER_A);
        IntEnable(INT_TIMER0A);
    
        //----------------------Timer2A Mode Capture--------------//
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM); // Enable the GPIO port that is used for the input edge counting
        GPIOPinTypeTimer(GPIO_PORTM_BASE, GPIO_PIN_0); // Configure PM0 as the positive edge capture on Timer 2A
        GPIOPinConfigure(GPIO_PM0_T2CCP0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2); // For use with edge-time-up mode
        TimerConfigure(TIMER2_BASE, (TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP));
        TimerControlEvent(TIMER2_BASE, TIMER_A, TIMER_EVENT_NEG_EDGE);
    
        //TimerLoadSet(TIMER2_BASE, TIMER_A, 0xFFFFFFFF); // Start count 0x0000
    
        TimerIntClear(TIMER2_BASE, TIMER_CAPA_EVENT);
        TimerEnable(TIMER2_BASE, TIMER_A); // Enable the timers
        TimerIntEnable(TIMER2_BASE, TIMER_CAPA_EVENT);
        IntEnable(INT_TIMER2A);
        //IntMasterEnable();
    
    
    
    }
    
    void Interrupt_Timer0A(void)
    {
    
        TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        temp++;
    
    }
    
    void Interrupt_Timer2A(void)
    {
    
        uint32_t InterruptFlags = TimerIntStatus(TIMER2_BASE, true);
    
        if (InterruptFlags & TIMER_CAPA_EVENT)
        {
    
           if (!flag)  {  // Capture first edge timer value and indicate that the program has captured first on
    
                edge1 = TimerValueGet(TIMER2_BASE, TIMER_A);
                flag = 1;
            }
            // Once falling edge has been captured, store the value of the second rising edge which completes the sample
           else if (flag){
    
                edge2 = TimerValueGet(TIMER2_BASE, TIMER_A);
    
                allCaptured = 1;  // Indicates that all three edges required for calculations have been capture and is ready to calculate
                flag = 0;
               }
    
        }
        // Clear interrupt flag to enable to interrupt to occur once more.
        TimerIntClear(TIMER2_BASE, TIMER_CAPA_EVENT);
    
    }