Jump to content
43oh

Recommended Posts

Hello,

I am trying to read a pulse that is 1-2ms wide and has a PRI of 20ms. This code is producing a value of ~30000 (1.5mS). No matter what I change the prescale value to, the count is always the same.

My understanding from the data sheet is that the prescaler only works when the timer is in half width mode, which I assume it is due to configuring it as a split pair. Is this assumption correct?

#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <string.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_gpio.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "driverlib/interrupt.h"
#include "utils/uartstdio.h"

volatile uint16_t t1A = 0, t2A = 0, timeA = 0, offTimeA = 0;
volatile uint16_t t1B = 0, t2B = 0, timeB = 0, offTimeB = 0;

//*****************************************************************************
//
// Timer2 interrupt
//
//*****************************************************************************
void
IntWTimer2AHandler(void)
{
	if(TimerIntStatus(WTIMER2_BASE, TIMER_CAPA_EVENT))
	{
		TimerIntClear(WTIMER2_BASE, TIMER_CAPA_EVENT);
		t2A = TimerValueGet(WTIMER2_BASE, TIMER_A);
		if(t2A > t1A) timeA = t2A - t1A;
		else timeA = (UINT32_MAX - t1A) + t2A;
		t1A = t2A;
	}
}

//*****************************************************************************
//
// Configure the UART and its pins.  This must be called before UARTprintf().
//
//*****************************************************************************
void
ConfigureUART(void)
{
    //
    // Enable the GPIO Peripheral used by the UART.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Enable UART0
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    //
    // Configure GPIO Pins for UART mode.
    //
    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    //
    // Initialize the UART for console I/O.
    //
    UARTStdioConfig(0, 115200, 16000000);
}

//*****************************************************************************
//
// This is the main loop that runs the application.
//
//*****************************************************************************
int
main(void)
{
    //
    // Turn on stacking of FPU registers if FPU is used in the ISR.
    //
    FPULazyStackingEnable();

    //
    // Set the clocking to run from the PLL at 10MHz.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    ROM_IntMasterDisable();
    //
    // Enable the Debug UART
    //
    ConfigureUART();
    //
    // Enable Peripheral Clocks
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER2);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    //
    // Enable pin PD1 for WTIMER2 WT2CCP1
    //
    GPIOPinConfigure(GPIO_PD1_WT2CCP1);
    GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_1);
    //
    // Enable pin PD0 for WTIMER2 WT2CCP0
    //
    TimerConfigure(WTIMER2_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP /*| TIMER_CFG_B_CAP_TIME_UP*/);
	TimerPrescaleSet(WTIMER2_BASE, TIMER_BOTH, 2);
    TimerControlEvent(WTIMER2_BASE, TIMER_A, TIMER_EVENT_BOTH_EDGES);
    //TimerControlEvent(WTIMER2_BASE, TIMER_B, TIMER_EVENT_BOTH_EDGES);

    SysCtlDelay(10);
    TimerEnable(WTIMER2_BASE, TIMER_A);

    ROM_IntEnable(INT_WTIMER2A);

    TimerIntClear(WTIMER2_BASE, TIMER_CAPA_EVENT);

    //
    // Enable interrupts to the processor.
    //
    TimerIntEnable(WTIMER2_BASE, TIMER_CAPA_EVENT);
    //TimerIntEnable(WTIMER2_BASE, TIMER_CAPB_EVENT);

    ROM_IntPrioritySet(INT_TIMER2A, 0x00);

    UARTprintf("ready clock: %d\n", SysCtlClockGet());
    ROM_IntMasterEnable();

    TimerIntClear(WTIMER2_BASE, TIMER_CAPA_EVENT);
    SysCtlDelay(SysCtlClockGet());

    while(1)
	{
		UARTprintf("timeA:%i\ttimerB:%i\n", timeA, TimerPrescaleGet(WTIMER2_BASE, TIMER_A));
		SysCtlDelay(SysCtlClockGet()/20);
	}
}

Link to post
Share on other sites

Hi,

Well, mostly No!

When counting up in one-shot or periodic modes, the prescaler acts as a timer extension and holds the most-significant bits of the count. In input edge count, input edge time and PWM mode, the prescaler always acts as a timer extension, regardless of the count direction. (From user manual)

Since the counting is up and both edges are selected, then the pulse duration is measured - seems this was the goal, reading the code snippet.

But: you may verify this with an oscilloscope to confirm the results.

Also: since both edges are enabled for capture, then to have always consistent results, you need to know which edge comes first -either the positive one, either the negative one. Assume the pulse is not 50%of duration.

L

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...