Frequency counter

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Frequency counter

499 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by larento on Sat Dec 27 00:26:53 MST 2014
Hi all,

I'm trying to implement a frequency counter on lpc1769 mcu on LPCXpresso LPC1769. Timer 2 is used as a counter while timer 1 is used as a 1 sec timer interrupt. So far i manage to get counts on P0.4(CAP2.[0]). However the counts are not the  same value value that i have input. I.e a 200Hz PWM signal was input to P0.4(CAP2.[0]) however only approximately 183-190Hz(counts) was returned. I have managed to trace down to the Chip_TIMER_Reset(LPC_TIMER2). By disabling this line i'm able to get near to input counts of 200Hz. How can i reset the count timer while counting accurately?

/*
===============================================================================
 Name        : PulseCount.c
 Author      : $(author)
 Version     :
 Copyright   : $(copyright)
 Description : main definition
===============================================================================
*/

#if defined (__USE_LPCOPEN)
#if defined(NO_BOARD_LIB)
#include "chip.h"
#else
#include "board.h"
#endif
#endif

#include <cr_section_macros.h>

// TODO: insert other include files here

// TODO: insert other definitions and declarations here
uint32_t timerFreq;
uint32_t timer2count;
bool flag;

//function to initialize LED2
void LED2_init()
{
Chip_GPIO_Init(LPC_GPIO);
Chip_GPIO_SetPinDIR(LPC_GPIO,0,22,true);
Chip_GPIO_WritePortBit(LPC_GPIO,0,22,false);
}

//toggle change of LED2 status
void LED2_Toggle()
{
if (Chip_GPIO_GetPinState(LPC_GPIO,0,22)==1)
{
Chip_GPIO_WritePortBit(LPC_GPIO,0,22,false);
}
else
{
Chip_GPIO_WritePortBit(LPC_GPIO,0,22,true);
}

}

//initialise input pin to cap2.0
void timer2_Pin_init()
{
        
Chip_IOCON_Init(LPC_IOCON);
Chip_IOCON_PinMux(LPC_IOCON, 0, 4 ,IOCON_MODE_INACT, IOCON_FUNC3);
}

//Timer 1 interrupt
void TIMER1_IRQHandler(void)
{
if (Chip_TIMER_MatchPending(LPC_TIMER1, 1)) {
Chip_TIMER_ClearMatch(LPC_TIMER1, 1);
                //toggle LED2
LED2_Toggle();
//assign counts to timer count
timer2count = Chip_TIMER_ReadCount(LPC_TIMER2);
flag=true;

}
}


int main(void) {

#if defined (__USE_LPCOPEN)
#if !defined(NO_BOARD_LIB)
    // Read clock settings and update SystemCoreClock variable
    SystemCoreClockUpdate();
    // Set up and initialize all required blocks and
    // functions related to the board hardware
    Board_Init();
    // Set the LED to the state of "On"
    Board_LED_Set(0, true);
#endif
#endif

    /*Initialize LED2*/
    LED2_init();
    timer2_Pin_init();
    timer2count = 0;

    /* Enable timer 2 clock */
    Chip_TIMER_Init(LPC_TIMER2);
    /*Reset Timer2*/
    Chip_TIMER_Reset(LPC_TIMER2);
    /*Capture on rising edge timer*/
    //Chip_TIMER_CaptureRisingEdgeEnable(LPC_TIMER2,0);
    //LPC_TIMER2->CCR=1;
    /*Set clock source to Rising edge --Count control register*/
    Chip_TIMER_TIMER_SetCountClockSrc(LPC_TIMER2,TIMER_CAPSRC_RISING_CAPN ,1);


    /*Enable timer 1 clock*/
    Chip_TIMER_Init(LPC_TIMER1);
    /* Timer rate is system clock rate */
    timerFreq = Chip_Clock_GetSystemClockRate();
    Chip_TIMER_Reset(LPC_TIMER1);
    Chip_TIMER_MatchEnableInt(LPC_TIMER1, 1);
    Chip_TIMER_SetMatch(LPC_TIMER1, 1, (timerFreq/4-1));
    Chip_TIMER_ResetOnMatchEnable(LPC_TIMER1, 1);


    /*Enable Timer 1 & 2*/
    Chip_TIMER_Enable(LPC_TIMER1);
    Chip_TIMER_Enable(LPC_TIMER2);

    /* Enable timer 1 interrupt */
    NVIC_ClearPendingIRQ(TIMER1_IRQn);
    NVIC_EnableIRQ(TIMER1_IRQn);




    while(1) {
    if (flag==true)
    {
    //prints the timer2count to debug screen
                printf("%u\n",timer2count);
                //by disabling this reset line , able to get close to 200Hz(counts)
    Chip_TIMER_Reset(LPC_TIMER2);
    flag=false;
    }
    }
    return 0 ;
}
Labels (1)
0 Kudos
3 Replies

378 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by larento on Sat Dec 27 09:23:44 MST 2014
Thanks everyone for the advises. Finally i got it working. Had modified the library to include Chip_TIMER_WriteCount(...) so that i can reuse for future project.
0 Kudos

378 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by 1234567890 on Sat Dec 27 03:24:28 MST 2014

Quote:
A Chip_TIMER_WriteCount function should do that, but this function has been forgotten Crying



That's right, so in this case something like LPC_TIMER2->TC=0 would be the easiest solution.

A good example that LPCOpen isn't the best solution for all cases because of it's 'allways save' philosophy. One have to look allways behind the functions what's really done.

It's better to read timer2 at the very first chance in your timer1 ISR and instantly set TC to zero. A printf and function call (LED) between that results definately in a wrong value.
0 Kudos

378 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Sat Dec 27 01:14:47 MST 2014

Quote: larento
I have managed to trace down to the Chip_TIMER_Reset(LPC_TIMER2). By disabling this line i'm able to get near to input counts of 200Hz. How can i reset the count timer while counting accurately?



Of course it's nonsense to reset Timer2   :)

You should reset TC after reading it with Chip_TIMER_ReadCount in ISR.

A Chip_TIMER_WriteCount function should do that, but this function has been forgotten  :((

0 Kudos