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/TM4C1294NCPDT: Capture mode - measure period

Part Number: TM4C1294NCPDT

Tool/software: Code Composer Studio

Hello.

I need to measure the period of an oscillator (CI555), with a frequency varying from 500kHz to 1kHz, but the code is not calculating the period correctly.

I'm starting with this microcontroller so I'm having some difficulties.

I would like to zero the timer2A counter after it captures 2 positive edges then to calculate the period, but I did not find this option.

I believe that the problem of my code is my programming logic, if anyone can give me a help I thank you very much.

Thank you.

float g_ui32SysClock;

volatile double freq = 0, cap = 0;

volatile uint32_t edge1, edge2, flag = 0, temp = 0, allCaptured = 0, period = 0;;




void main(void) {

    Config_Clock();
    Config_Timer();
 

    while (1)  {

  

        if(allCaptured){
            

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

               period = edge2 - edge1;         // Calculate Period
               freq = g_ui32SysClock/period;
               

               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)
{

    
    //----------------------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_POS_EDGE);

    //TimerLoadSet(TIMER2_BASE, TIMER_A, 0xFFFF);

    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_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;
        }

       else if (flag){ // Once falling edge has been captured, store the value of the second rising edge which completes the sample

            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;


         }
 }

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

}

  • Hello Dalacort,

    I think you just have a small error.

    You are just resetting allCaptured = 0; inside your check for overflow... but you should clear this every time you enter the if (allCaptured) if statement.

    Take the allCaptured = 0; out of your edge2 > edge1 comparison and you should get consistent results.