EmbeddedRelated.com
Forums

frequency counter

Started by Stijn November 10, 2009
Hi All,

I'm trying to display the frequency of a signal by measuring the time between 2 pulses.

Are there any suggestions on how to start with it?
I want to use the standard timer counter function, but don't know how to implemt it correctly.

Can somebody show me some examples, or push me in the right direction?

I'm using the lpc 2148 controller with the Keil compiler.
this is what I have for now.

VPBDIV = 0x00000001; //VPB clock is the same as processor clock
PINSEL1 = 0x00000003; //Enable pin 0.16 as capture 0.2
T0PR = 0x0000001E; //Load prescaler for 1 Msec tick
T0TCR = 0x00000002; //Reset counter and prescaler
T0CCR = 0x00000040; //Capture on rising edge of 0.2
T0CTCR = 0x00000000; // timer mode
T0TCR = 0x00000001; //enable timer

If I want to measure the time between 2 pulses, then I have to stop the timer on the next puls, read the timervalue, reset the timer and start it again.

But how can I stop the timer on the next pulse?

thanks in advance!

An Engineer's Guide to the LPC2100 Series

Hi:

You are referring to the Input Capture Feature that the Timers have.
As soon as you enable the timer, the timer counter register starts counting.

As soon as there is an event in the Capture pin, the capture register will "capture" the current value of the timer counter in the capture register.

I would suggest to enable both rising and falling capture events, and Interrupt on Capture on T0CCR, so that every edge (either falling or rising) an interrupt is generated and you can copy the content of the capture register into a buffer. The difference between the last to measurements give you the last pulse width.

Regards,

Alex
--- In l..., "Stijn" wrote:
>
> Hi All,
>
> I'm trying to display the frequency of a signal by measuring the time between 2 pulses.
>
> Are there any suggestions on how to start with it?
> I want to use the standard timer counter function, but don't know how to implemt it correctly.
>
> Can somebody show me some examples, or push me in the right direction?
>
> I'm using the lpc 2148 controller with the Keil compiler.
> this is what I have for now.
>
> VPBDIV = 0x00000001; //VPB clock is the same as processor clock
> PINSEL1 = 0x00000003; //Enable pin 0.16 as capture 0.2
> T0PR = 0x0000001E; //Load prescaler for 1 Msec tick
> T0TCR = 0x00000002; //Reset counter and prescaler
> T0CCR = 0x00000040; //Capture on rising edge of 0.2
> T0CTCR = 0x00000000; // timer mode
> T0TCR = 0x00000001; //enable timer
>
> If I want to measure the time between 2 pulses, then I have to stop the timer on the next puls, read the timervalue, reset the timer and start it again.
>
> But how can I stop the timer on the next pulse?
>
> thanks in advance!
>

If you are truly interested in pulse counting rather than measuring the period between two pulses, you can configure one timer to take an external clock input, and connect the signal you want to count to the external input.

This approach is more practical if you are counting random pulses or high frequency pulse streams. At high frequencies, using the input capture can cause you to lose pulses during execution of the ISR.

You also need to set up a periodic timer to read the resulting pulse count and calculate the frequency.

The 2148 has two timers so this is relatively easy to do.

Mark

--- In l..., "Stijn" wrote:
>
> Hi All,
>
> I'm trying to display the frequency of a signal by measuring the time between 2 pulses.
>
> Are there any suggestions on how to start with it?
> I want to use the standard timer counter function, but don't know how to implemt it correctly.
>
> Can somebody show me some examples, or push me in the right direction?
>
> I'm using the lpc 2148 controller with the Keil compiler.
> this is what I have for now.
>
> VPBDIV = 0x00000001; //VPB clock is the same as processor clock
> PINSEL1 = 0x00000003; //Enable pin 0.16 as capture 0.2
> T0PR = 0x0000001E; //Load prescaler for 1 Msec tick
> T0TCR = 0x00000002; //Reset counter and prescaler
> T0CCR = 0x00000040; //Capture on rising edge of 0.2
> T0CTCR = 0x00000000; // timer mode
> T0TCR = 0x00000001; //enable timer
>
> If I want to measure the time between 2 pulses, then I have to stop the timer on the next puls, read the timervalue, reset the timer and start it again.
>
> But how can I stop the timer on the next pulse?
>
> thanks in advance!
>

Can you show me how to work this out in c code?

Do I need to use vectored interrupts?

Why do i have to enable both rising and falling edge?
Correct me if I'm wrong, but for calculating the frequency out of the time between the pulses, I think I only need the pulse on rising or falling edge....

in my previous post, there was the code i started with, but don't know how to go on with it.

Can you give me an example, or good link?
thanks in advance

--- In l..., "alexander_ribero" wrote:
>
> Hi:
>
> You are referring to the Input Capture Feature that the Timers have.
> As soon as you enable the timer, the timer counter register starts counting.
>
> As soon as there is an event in the Capture pin, the capture register will "capture" the current value of the timer counter in the capture register.
>
> I would suggest to enable both rising and falling capture events, and Interrupt on Capture on T0CCR, so that every edge (either falling or rising) an interrupt is generated and you can copy the content of the capture register into a buffer. The difference between the last to measurements give you the last pulse width.
>
> Regards,
>
> Alex
> --- In l..., "Stijn" wrote:
> >
> > Hi All,
> >
> > I'm trying to display the frequency of a signal by measuring the time between 2 pulses.
> >
> > Are there any suggestions on how to start with it?
> > I want to use the standard timer counter function, but don't know how to implemt it correctly.
> >
> > Can somebody show me some examples, or push me in the right direction?
> >
> > I'm using the lpc 2148 controller with the Keil compiler.
> >
> >
> > this is what I have for now.
> >
> > VPBDIV = 0x00000001; //VPB clock is the same as processor clock
> > PINSEL1 = 0x00000003; //Enable pin 0.16 as capture 0.2
> > T0PR = 0x0000001E; //Load prescaler for 1 Msec tick
> > T0TCR = 0x00000002; //Reset counter and prescaler
> > T0CCR = 0x00000040; //Capture on rising edge of 0.2
> > T0CTCR = 0x00000000; // timer mode
> > T0TCR = 0x00000001; //enable timer
> >
> > If I want to measure the time between 2 pulses, then I have to stop the timer on the next puls, read the timervalue, reset the timer and start it again.
> >
> > But how can I stop the timer on the next pulse?
> >
> > thanks in advance!
>

Hi Stijn,

I think it is nicely described in words and you might have to translate it to C code yourself.

If the pulses are slow or you need to measure only very small amount of pulses, then it might be OK to use interrupts (on capture)
as Alex describes. If the pulses are fast it is better to use DMA to store the captured values to memory. Such code was easier (in
my experience) to debug than the interrupt-based code, because in debug mode the processor was not be able to serve them in time.
Sorry, I can't send you the example, it is for STM32F10x anyway.

With regards,
Jan

----- Original Message -----
From: "Stijn"
To:
Sent: Monday, November 16, 2009 4:07 PM
Subject: [lpc2000] Re: frequency counter
Can you show me how to work this out in c code?

Do I need to use vectored interrupts?

Why do i have to enable both rising and falling edge?
Correct me if I'm wrong, but for calculating the frequency out of the time between the pulses, I think I only need the pulse on
rising or falling edge....

in my previous post, there was the code i started with, but don't know how to go on with it.

Can you give me an example, or good link?
thanks in advance

--- In l..., "alexander_ribero" wrote:
>
> Hi:
>
> You are referring to the Input Capture Feature that the Timers have.
> As soon as you enable the timer, the timer counter register starts counting.
>
> As soon as there is an event in the Capture pin, the capture register will "capture" the current value of the timer counter in the
> capture register.
>
> I would suggest to enable both rising and falling capture events, and Interrupt on Capture on T0CCR, so that every edge (either
> falling or rising) an interrupt is generated and you can copy the content of the capture register into a buffer. The difference
> between the last to measurements give you the last pulse width.
>
> Regards,
>
> Alex
> --- In l..., "Stijn" wrote:
> >
> > Hi All,
> >
> > I'm trying to display the frequency of a signal by measuring the time between 2 pulses.
> >
> > Are there any suggestions on how to start with it?
> > I want to use the standard timer counter function, but don't know how to implemt it correctly.
> >
> > Can somebody show me some examples, or push me in the right direction?
> >
> > I'm using the lpc 2148 controller with the Keil compiler.
> >
> >
> > this is what I have for now.
> >
> > VPBDIV = 0x00000001; //VPB clock is the same as processor clock
> > PINSEL1 = 0x00000003; //Enable pin 0.16 as capture 0.2
> > T0PR = 0x0000001E; //Load prescaler for 1 Msec tick
> > T0TCR = 0x00000002; //Reset counter and prescaler
> > T0CCR = 0x00000040; //Capture on rising edge of 0.2
> > T0CTCR = 0x00000000; // timer mode
> > T0TCR = 0x00000001; //enable timer
> >
> > If I want to measure the time between 2 pulses, then I have to stop the timer on the next puls, read the timervalue, reset the
> > timer and start it again.
> >
> > But how can I stop the timer on the next pulse?
> >
> > thanks in advance!
>

Jan Vanek wrote:
> If the pulses are fast it is better to use DMA to store the captured
> values to memory.

You could also just use a hardware counter and a timer interrupt
separately. The timer ISR simply reads the counter and then zeroes it.

The value read will tell you how many pulses were counted within the
timer's period, which gives you the frequency (through the magic of
division... or multiplication depending on which way you look at it).

You can let another task do the calculation (if using an RTOS). Of
course, this all depends on how early you need to know the frequency (or
how often it will change)...

This method has the advantage that (frequent) spurious pulses produce
incorrect results, but do not bring down the rest of the system by
letting an ISR starve the other tasks of CPU time.

Pete
You're right. It's about calculating frequency, he just needs the count of pulses, but not the lengths of individual pulses. I
needed the lengths in my app and was blinded to see the better solution...

Regards,
Jan
----- Original Message -----
From: "Pete Vidler"
To:
Sent: Tuesday, November 17, 2009 11:01 AM
Subject: Re: [lpc2000] Re: frequency counter
> Jan Vanek wrote:
>> If the pulses are fast it is better to use DMA to store the captured
>> values to memory.
>
> You could also just use a hardware counter and a timer interrupt
> separately. The timer ISR simply reads the counter and then zeroes it.
>
> The value read will tell you how many pulses were counted within the
> timer's period, which gives you the frequency (through the magic of
> division... or multiplication depending on which way you look at it).
>
> You can let another task do the calculation (if using an RTOS). Of
> course, this all depends on how early you need to know the frequency (or
> how often it will change)...
>
> This method has the advantage that (frequent) spurious pulses produce
> incorrect results, but do not bring down the rest of the system by
> letting an ISR starve the other tasks of CPU time.
>
> Pete
>