Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

High speed counter with microcontroller

Status
Not open for further replies.

aknalemdar

Newbie level 6
Joined
Sep 2, 2021
Messages
13
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
108
Hello everyone.
I am using a counter with the PIC. The counter I am currently using is 16 bits and uses the internal oscillator. Internal oscillator = 64 MHz
Microcontroller = PIC18F25Q43
I want the clock speed of the meter to be more than 64 MHz. Is it possible to do this with PLL?
Or do you have a recommendation for a microcontroller with this feature? As seen in the code I shared as an example, I count 64000 in 1 millisecond. I want to do more counts in 1 millisecond. In this case, I need a 24-bit or 32-bit counter. I need your help for these two situations.
Respects.


Adsız.png


Code:
#include <main.h>
#define LCD_ENABLE_PIN  PIN_E0                                
#define LCD_RS_PIN      PIN_E1                                  
#define LCD_RW_PIN      PIN_E2                                  
#define LCD_DATA4       PIN_D4                                  
#define LCD_DATA5       PIN_D5                                
#define LCD_DATA6       PIN_D6                                  
#define LCD_DATA7       PIN_D7
#include <lcd.c>
unsigned int16 sayac=0;
void main()
{
   lcd_init();
   setup_timer_1(T1_FOSC | T1_DIV_BY_1);
   while(TRUE)
   {
      set_timer1(0);
      delay_us(1000);
      sayac=get_timer1();
      lcd_gotoxy(1,1);
      printf(lcd_putc,"SAYAC = %lu",sayac);
   }
}
 

If you used a divide by 2 external, say single gate logic type of part, easily
clocked > 100 Mhz, you could meet many manufacturers count speed.


32 bit counters, PSOC has ability to give you many 32 bit counters.
Need a 48 bit or larger counter, can do that easily in PSOC as well.
With muxed input.

Whats on PSOC (you can create custom onboard f()'s as well using schematic capture
and or Verilog), multiple copies of many of these, onboard routable :

1662727531936.png


Regards, Dana.
 
Last edited:
Please explain the purpose of doing this. I ask because counting alone is pointless, presumably you want to use the number you re counting for some purpose and the extra code needed to achieve that could very significantly slow things down. For example, I think the code you show is to 'snapshot' the timer value once per millisecond but the routines to display the value could well take longer than that.

Brian.
 
Please explain the purpose of doing this. I ask because counting alone is pointless, presumably you want to use the number you re counting for some purpose and the extra code needed to achieve that could very significantly slow things down. For example, I think the code you show is to 'snapshot' the timer value once per millisecond but the routines to display the value could well take longer than that.

Brian.
I have a measurement interval of one millisecond. In this measurement range, a pulse may come while my signal is low for 1 millisecond. This pulse can be 1 microsecond or 900 microsecond. There may even be a pulse down to nanoseconds. I want to count with this pulse timer. So my goal is to use high speed and increase resolution and accuracy at the same time.
 

In that case the best strategy would be to feed your pulse into one of the timers as an external source and create a time window to capture in using one of the other timers using the internal source. For example, use timer 0 to create the 1mS window and route the incoming pulse to timer 1. Use interrupts for the window timing, they will be far more accurate than a software delay.

Brian.
 
That was pretty contradictory. Make up your mind: is your shortest pulse 1 microsecond, or nanoseconds? Are you trying to count pulses or pulse width? It’s unclear. if you’re only trying to count pulses, it doesn’t matter if it’s 1 microsecond or 900 microseconds wide. (1 nanosecond might be a problem).
 
Hi,

I agree with the above.

Mind: if you want to measure in the ns range then also the gating needs to be accurate down to the ns range.
This usually the microcontroller hardware can not guarantee and a software solution - even via interrupt - is way worse.

The most precise solution I know are dedicated "time - to - digital" converters.
Then hardware counters, maybe in an FPGA..

Klaus
 
re zamanlaması için
In that case the best strategy would be to feed your pulse into one of the timers as an external source and create a time window to capture in using one of the other timers using the internal source. For example, use timer 0 to create the 1mS window and route the incoming pulse to timer 1. Use interrupts for the window timing, they will be far more accurate than a software delay.

Brian.
I have developed such a code block. Doing these operations with while inside the interrupt? Or do it all with separate cuts? When you calculate the command time, it's like they both come to the same time...

Code:
#INT_TIMER1
void  TIMER(void)
{
   disable_interrupts(INT_TIMER1);
   while(input(pin_c0));
   set_timer1(0);
   while(!input(pin_c0));
   x=get_timer1();
   set_timer1(0);
   while(input(pin_c0));
   cap=get_timer1();
   set_timer1(0);
   while(!input(pin_c0));
   y=get_timer1();
}
--- Updated ---

That was pretty contradictory. Make up your mind: is your shortest pulse 1 microsecond, or nanoseconds? Are you trying to count pulses or pulse width? It’s unclear. if you’re only trying to count pulses, it doesn’t matter if it’s 1 microsecond or 900 microseconds wide. (1 nanosecond might be a problem).
s1.png
s2.png
s3.png

I'm sending you a signal sample. The pulse duration within this 1 ms is variable. I am trying to measure this time.

Topluluk Doğrulandı küçültme
 

Hello!

From what I see, you have always 2 pulses of the same length, right?
One statistical way to do it:
Measure the signal fast enough at random and increment 2 counters, low and high.
I suppose you guessed that if the signal is low you increment counter_low, and if the
signal is high, you increment counter_high.
Then you will have 2 values from which you can calculate the accurate pulse width.
2 external counters with latches, feed your signal to the chip select and yo're done.
Every once in a while, you stop the chip select signals, read the 2 values and reset.
And you don't have to mess with high speed chips.

Dora.
 
Do it in assembler code. You add extra delays by writing it in C. It isn't complicated and you can incorporate a block of assembly language inside the C code if you wish.

1. Set up the first timer to overflow in 1mS.
2. Set up the second timer to count mode.
3. Clear the count in the second timer.
4. Enable the first timer interrupts.
5. In the ISR, read the second timer, it will hold the number of pulses in the 1mS window.
6. After using the data, reload the first timer to overflow in 1mS again then go to step 3.

Brian.
 
Mandallı 2 harici cihazları, ekran kartınızı seçiminiz için işleyin ve bitti.
İlk zamanlayıcıyı 1mS'de taşınacak şekilde ay

Do it in assembler code. You add extra delays by writing it in C. It isn't complicated and you can incorporate a block of assembly language inside the C code if you wish.

1. Set up the first timer to overflow in 1mS.
2. Set up the second timer to count mode.
3. Clear the count in the second timer.
4. Enable the first timer interrupts.
5. In the ISR, read the second timer, it will hold the number of pulses in the 1mS window.
6. After using the data, reload the first timer to overflow in 1mS again then go to step 3.

Brian.
Now I am doing this process with PIC18F47Q43. But my system's internal oscillator speed is 64 MHz. For the timer I could probably pulse 64 MHz max. How can I count this at higher speeds? I am counting more than 60 thousand in 1 millisecond right now. How can I achieve higher count values? I don't want to struggle to be my FPGA knowledge.
--- Updated ---

I thought of using a 300 MHz crystal and dividing this frequency and sending it to the processor. Then I thought of multiplying mathematically. Is this a sensible solution?
 

I have developed such a code block. Doing these operations with while inside the interrupt? Or do it all with separate cuts? When you calculate the command time, it's like they both come to the same time...

Code:
#INT_TIMER1
void  TIMER(void)
{
   disable_interrupts(INT_TIMER1);
   while(input(pin_c0));
   set_timer1(0);
   while(!input(pin_c0));
   x=get_timer1();
   set_timer1(0);
   while(input(pin_c0));
   cap=get_timer1();
   set_timer1(0);
   while(!input(pin_c0));
   y=get_timer1();
}
--- Updated ---


View attachment 178467View attachment 178468View attachment 178469
I'm sending you a signal sample. The pulse duration within this 1 ms is variable. I am trying to measure this time.

View attachment 178470
This is still stupendously unclear. Whats your timescale? WHAT is “this 1ms”? The full display? The time between the two pulse-pairs? We have no way of knowing. WHAT pulse width are you trying to measure, I see 2 different positive pulses. If you need to count more than 60000, use a larger variable, or simply increment a second variable when the first one overflows. If you take a high frequency (300MHz) and then divide it, you now have a lower frequency; what do you think this is going to gain you?

Please answer these two fundamental questions:

1) What is the maximum pulse width you’re trying to measure?
2) What resolution do you need?
 
The pulse diagrams confusing, you need to measure both + going and - going pulses ?

What is considered the pulse in each of those 3 trains you posted ?

If you need to measure a `10 nS pulse, what resolution do you want at that width ?
And what is the minimum width you are trying to measure, this is not a spec -

There may even be a pulse down to nanoseconds.
Can there be more than 1 pulse in the mS window ? What is absolute accuracy needed
of measurement ?

Even if you use external 100's of Mhz counters you have to enable them with the 1 mS
frame, and coming from a UP with clock jitter that measurement gets suspect real fast.
And its not sychrous, unless you design for that, so that the 1 mS jitter can impact the
counter start. Plus you have to use that high speed pulse as a gate for an external clock
with low jitter that can meet the resolution you want. PCB layout alone a challenge.


Regards, Dana.
 
Hello!

Do it in assembler code. You add extra delays by writing it in C.

That used to be true, but recently, the C/C++ compilers are so efficient that there is no
difference at all. Might depend on the processor too (I mean not the processor itself but the environment.
Some processors might be better supported).
As there is this persistent legend: asm faster than C which is faster than C++ which is faster than xxx.
I wanted to try myself, and I tried to actually measure this using MSP430.
Examples:
- On the scope: signal coming from a button vs GPIO set at the beginning of the interrupt routine.
Exact same delay in C or ASM. Not even 1 clock difference.
- Even simpler: toggle a LED in a loop: again, no difference at all between ASM and C, not even 1 clock.
I also did experiments on Arduino, but here things are very different. Using arduino digitalWrite takes
ages, and the best is to write your own function or using instructions like PORTA |= 0x01;

Dora.
 
I am sending you a sample simulation example. Explains video signal interaction more clearly. I actually have a fixed frequency signal. Only in the low part of this signal a new variable signal is formed. This variable signal does not affect the main frequency. I want to count this variable signal with timer. I've done it now. But how can I improve for a clearer resolution? How accurate do you think the timer count will be?



 

Hi,
That used to be true, but recently, the C/C++ compilers are so efficient that there is no
difference at all.
I have to disagree to this "general" statement.

It extremely depends on what you and how you do.

My recommendation:
If you have timing critical situations: always do a timing check on the real part.
It may be as simple as
* set pin before a critical function
* clear the pin afterwards
* check the pin with a scope (best a digital scope with infinite view of the pulses)
(mind: any function may take longer time than usual when interrrupts cause additional delay)

Klaus
 
Hi,

I have to disagree to this "general" statement.

It extremely depends on what you and how you do.

My recommendation:
If you have timing critical situations: always do a timing check on the real part.
It may be as simple as
* set pin before a critical function
* clear the pin afterwards
* check the pin with a scope (best a digital scope with infinite view of the pulses)
(mind: any function may take longer time than usual when interrrupts cause additional delay)

Klaus
Or I'll use a nice digital filter. When I count 1 millisecond or microsecond in the processor itself, I always get the same result. But when I apply an external signal I see changes in the count. How can I prevent this?
 

Hi,

your post gives no information ... rather leads to more questions:
* How and what did you cont?
* What external signal?
* changes like +/-1 LSB or like overflow?

**
To me it´s still unclear what you want to achieve.
Draw a sketch where we clearly can see what you are after. Maybe add examples (values).

Klaus
 
Hello!

Explains video signal interaction more clearly.

Yes, at least in your head.

I actually have a fixed frequency signal.

If you look at the signal at 0:00 and at 0:01, it looks like the frequency doubles. Or like you have changed
the scope's timebase, but something like that happened.
Basically your signal looks like a kind of PWM, with 2 low pulses. Let's call these 2 pulses "pattern".
- The pattern seems to be indeed at regular intervals
- The 2 pulses of each pattern look equal.
I made something like that in the past (see method above). The statistical approach works.

Or I'll use a nice digital filter. When I count 1 millisecond or microsecond in the processor itself, I always get the same result. But when I apply an external signal I see changes in the count. How can I prevent this?

If you count with some clock which is not synchronous to your processor's clock, there is no way to prevent
this.

The following is a bit off-topic...

I have to disagree to this "general" statement.

That's why I said it's not necessarily true for all platforms.

* set pin before a critical function
* clear the pin afterwards
* check the pin with a scope (best a digital scope with infinite view of the pulses)

That's exactly what I did. Or sometimes just toggle the pin, for example:
while(1) {
P1OUT ^= 0x01;
}
and check the period in asm and C. This ends in the exact same result.

Using an interrupt: set one probe on the pin itself, and make a pulse with GPIO in the interrupt
itself. No difference whatsoever. There is some jitter (less than 1 clock) because it depends when
the button hardware signal happens vs the clock. But it's the same for asm or C.
And the time corresponds exactly to the number of clocks needed for interruption + the number
of clocks to set a GPIO. In both cases. (values that you find in the instructions list of the processor doc)

Calling a function is indeed longer because an extra jump is needed, and also a few push / pop
depending on the parameters. But the time again is exactly the same.

NB: I have measured that on MSP430 using IAR development environment when I had a license.

I made a few measurements with C/C++ and again it's the same. It may happen that you loose one
clock if you call an object's method, (ie func() is one clock faster than obj.func()) on MSP430 if I remember
it correctly. But in C if you call a function pointer which belongs to a structure, you get basically an object.
What ever the nature of obj (be it a structure or a C++ object), obj->func() takes the same
time. Again, verified on MSP430 only.

Dora.
 
Hi,
Calling a function is indeed longer because an extra jump is needed, and also a few push / pop
depending on the parameters. But the time again is exactly the same.
Since the topic is " timing related with microcontrollers" .. I think the ASM/C/... speed discussion isn´t off topic.
.. At least some good side information.

I´m not a specialist in C. But I always find it hard to find out what is a true called function and what is compiled as in inline code (not in the meaning of inline assembler within a C file).

Controlling a single pin usually is not the problem. Most compilers do this rather good. Doing the same wihtin a function increases the overhead. And doing the same within an ISR increases the overhead and may add some delay for times when the interrupt is blocked.

My overall worst case experience was: I told my software engineer to "debug" a variable(byte) in an ISR and write it´s HEX representation via UART. The UART had a software buffer (no overflow, no blocking function), thus I thought nothing timing problematic about this. But this debugging code killed the whole application.
It turned out that the used "sprintf" to transform a byte into HEX (2 ASCII bytes + delimiter byte) took several milliseconds...while I expected a few microseconds.

I was raised with assembler, microcontrollers, and my software usually is timing critical (ADC sampling, real time data processing..) ..thus my thinking is way different than of most software developers.

This doesn´t mean I don´t like C. But in opposite to ASM - where I exactly know which instruction gets processed and how long it takes - I need to check the timing thoroughly when coded via C.

And for sure it depnds on what type of microcontroler and what libraries, what variables you use.
On STM32F1xx there are several methods on how to access to periferal interfaces:
UART can be accessed directly (blocking) , via interrupt (using software buffer) or via DMA. Each has it´s benefits and drawbacks. And from the (name of a) function I often don´t see which method is used.

So we both recommend the same: check timing of the application.


Klaus
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top