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.

TM4C123GH6PM: Pulse Capture Issues

Part Number: TM4C123GH6PM


Hello, 

I am tring to properly capture the up-time for a 333Hz pulse. The pulse is a PPM signal from a RC tx, so the duty cycle of the input is adjustable. I am having a problem: when I drop the duty cycle of the input the values for the capture just from the period of time low of the signal, to the period of time high on the signal. I think this is happening because the timer I am using is rolling over and making the data useless. Any insight would be very helpful. Thank you.

#define PART_TMC123GH6PM

#include <stdint.h> // Variable definitions for the C99 standard.
#include <stdio.h> // Input and output facilities for the C99 standard.
#include <stdbool.h> // Boolean definitions for the C99 standard.
#include "inc/hw_ints.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/pwm.h"
#include "driverlib/sysctl.h" // Definitions and macros for System Control API of DriverLib.
#include "driverlib/interrupt.h" // Defines and macros for NVIC Controller API of DriverLib.
#include "driverlib/gpio.h" // Definitions and macros for GPIO API of DriverLib.
#include "driverlib/timer.h" // Defines and macros for Timer API of DriverLib.
#include "driverlib/pin_map.h" //Mapping of peripherals to pins for all parts.
#include "driverlib/adc.h" // Definitions for ADC API of DriverLib.
#include "driverlib/fpu.h" // Prototypes for the FPU manipulation routines.
#include "inc/tm4c123gh6pm.h" // Definitions for the interrupt and register assignments.
#include "inc/hw_memmap.h" // Memory map definitions of the Tiva C Series device.
#include "inc/hw_types.h" // Definitions of common types and macros.



volatile int intFlag=0;
volatile int widthFlag=0;
volatile unsigned int posEdge=0;
volatile unsigned int negEdge=0;
volatile unsigned int pulseWidth=0;
volatile unsigned int valueArray[10];
volatile unsigned int i=0;
volatile unsigned int posAverage=0;
volatile unsigned int divVar=10;
double x=0;
double checkVar=0;

void TIMER_Initialize(void)
{
// Enables timer 1
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
// PB5 pin configured with timer 1
    GPIOPinConfigure(GPIO_PB5_T1CCP1);
// Timer type set
    GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_5);
// Configure timer to edge time capture
    TimerConfigure(TIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_CAP_TIME_UP);
// Event set to both pulse edges
    TimerControlEvent(TIMER1_BASE, TIMER_B, TIMER_EVENT_BOTH_EDGES);
    TimerPrescaleSet(TIMER1_BASE, TIMER_B, 255);
// Configure timer 1b interrupts
    IntEnable(INT_TIMER1B);
// Enable timer interrupts
    TimerIntEnable(TIMER1_BASE, TIMER_CAPB_EVENT);
    // Enables processor interrupts
    IntMasterEnable();
// Enables the timers
    TimerEnable(TIMER1_BASE, TIMER_B);

}

int main(void)
 {
    SysCtlClockSet(
          SYSCTL_SYSDIV_64 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN
                  |SYSCTL_XTAL_16MHZ);
    TIMER_Initialize();

    while (1)
    {
      //checkVar = TimerLoadGet(TIMER1_BASE, TIMER_B);
      //TimerEnable(TIMER1_BASE, TIMER_B);

    }
}

void Timer1IntHandler(void)
{
   TimerIntClear(TIMER1_BASE, TIMER_CAPB_EVENT);
     if (intFlag==0)
    {
    posEdge=TimerValueGet(TIMER1_BASE, TIMER_B);
    intFlag=1;
    widthFlag=0;
    }
    else
    {
    negEdge=TimerValueGet(TIMER1_BASE, TIMER_B);
    intFlag=0;
    widthFlag=1;
    }
    if ((widthFlag==1)&&(negEdge>posEdge))
        {
            pulseWidth = (negEdge - posEdge);
            valueArray[i]=pulseWidth;
            x+=valueArray[i];
            i++;
        }
    if (i==10)
    {checkVar=TimerValueGet (TIMER1_BASE, TIMER_B);
        i=0;
        posAverage=(x/divVar);
        x=0;
        divVar=10;
        posEdge=0;
        negEdge=0;
       // TimerLoadSet(TIMER1_BASE, TIMER_B, 20000);
    }

}

  • Would your task not be made so much easier by employing TWO timers - as opposed to just one? One timer detects (interrupts) upon, "Rising Edge" - second "Falling Edge?"

    We read your earlier post in this regard - "knew" that the use of single timer would (likely) lead to delay/frustration.     By routing your input, 333Hz pulse signal into TWO Timer pins (configured as above) you greatly speed, ease & enhance such measurement.

    KISS rules.    (saving one {one of MANY} timers - who cares?)

  • Ok, I have spent enough time trying to get this working on one pin/timer. I will go with two. Thank you for the response, cb1_mobile.
  • Good for you & thanks as well.
    As your career progresses you will (likely) learn that "mission" comes first - "l'elegance" a (distant) second...