Hey!!! ... this way works 130% (thanks Oliver Seitz)
I explain:
I use a PIC16F88, I set the isr routine for 1ms interrupt and counting
for 500ms, this is TMR0...
TMR1 is in pulse counter with prescaler 1:1, on overflow the interrupt
of TM1 increment a internal counter as a way of internal postcaler
Each 500ms the TMR1 and his internal postcaler is read & cleared.
Then the freq is computed, with a trick...
The pic is running XTAL at 20Mhz, so XTAL/4 is 5 Mhz (maximum freq to
measure), that is 5000000 pulses per seconds or 2500000 each 1/2 sec. or
38 * postcaler + remaining pulses... so postcaler is a byte var...
But the ISR of TMR0 & TMR1 puts a delay on the reading that depends on
the things the pic is doing in each cycle of the forever loop.
I adjust the delay as a percent of useful time on each postcaler cycle,
feeding the pic with almost full count before postcaler get incremented
and get by serial port the internal count, as I knows the freq I can say
how much pulses has to count for exact and how much pulses are the pic
counting...
For my experimentation the percent of adjust if in the order of 99%
(99.0298891% of the pic reading in my last calibration) and of course
this correction factor must be scaled to every postcaler count, normally
a postcaler count will be poscaller * 65536, but to adjust I compute
65536 * 99.0298891% so.
Freq = poscaler * (65536 * 99.0298891%)
Freq = Freq + (pulses * 99.0298891%)
As we want an accurate reading, we have to work wit decimal shifting the
decimal point and div then, so
Corr_postcaler_pulses = (65536 * 99029) /100000 -- this is a constant
Corr_pulses = (pulses * 9903) / 10000
Freq = (postcaler * Corr_postcaler_pulses) + Corr_pulses
And as I'm reading 1/2 sec
Freq = Freq * 2
This give me an accuracy of about +/- 10 Hz at 5Mhz (4.99M) in the
proteus simulation, I know that the stability of the 20Mhz XTAL and the
source under measure will mask this error, but nevertheless this is GOOD
accuracy..
This is the best method I have tried and the freq_meter is in his 4.0
version (aka 4th method)
Then with a external prescaler of 8 (5Mhz * 8) I can count up to 40
Mhz... the external prescaler can be a pair of 74hc74 (3 half in 3 bit
count = /8 this can work up to 60-80 Mhz range)
Here I can find a 250 Mhz /64 & /65 prescalers as well as 1Ghz /2 & /4 &
/8 external prescaler,
So, I can make it with 5 scales
1Ghz (/8 + /64 = out max 1.9Mhz, error max ~10Khz)
250Mhz (/64 = out max 3.9Mhz, error max ~1.2Khz)
40Mhz (/8 = out max 5.0Mhz, error max ~150hz)
5Mhz (direct, error max ~20hz)
500Khz (direct, error max ~2hz)
The core counting engine is working, I'm working on the lcd output
formatting, external prescaling & serial interface to externally adjust
for freq compensation via serial on the final hardware.
I'm thinking also in a abbreviated/full display option kind of
145.170051 Mhz => 145.170 Mhz
51.110402 Mhz => 51.1104 Mhz
For "masking" the error when full accuracy is not needed
And even a averaging of the last n readings for stable display numbers
and accurate readings on > 100 Mhz freqs when the error gets bigger
When I have a working piece of this functions I will post the example to
the list.
Thanks to all for the ideas and tips...
Cheers.
El 31/07/13 09:50, Oliver Seitz escribió:
My way would be:
On overflow, increment an additional upper counter, and just leave the
timer running until the time has passed. You can use variables as big as
you want in JAL. So there's no need for prescalers, as long as the timer
can keep up with the external frequency.
On 18F26K22 chips, for example, in asyncronous mode, the timers can
count 16MHz. Counting one second, the timer could overflow
(16000000/65536=) 244 times, so only an additional one-byte variable is
needed to count that frequency with 1Hz resolution.
To count hundreds of MHz, you need to start with a high setting on the
external prescaler, for you can't know if the frequency is too high for
the timer and it might miss pulses then.
A microcontroller can easily do thousands of interrupts per second
without "going crazy", don't worry. I've had programs where interrupts
occured only a few microseconds after another. This was on 64MHz, though.
Greets,
Kiste
------------------------------------------------------------------------
*Von:* Ing. Pavel Milanes Costa <[email protected]>
*An:* [email protected]
*Gesendet:* 14:46 Mittwoch, 31.Juli 2013
*Betreff:* Re: [jallib] Freq Counter? + break a _usec_delay()
instruction?
Hi to all...
Last night I was thinking on the bed before sleep... I think there is
another more elegant KISS solution...
On overflow, STOP the counting (unset TMR1ON), and then stop the
counting and the overflow process...
As simple as that...
I will try it in the afternoon, I will update to all about the progress
of this instrument...
Cheers...
El 30/07/13 23:44, Ing. Pavel Milanes Costa escribió:
> Hi all again.
>
> With your ideas and code I'm writing a frequency meter.
>
> From 0hz to 280 Mhz using various "prescalers" in conjunction
(variable
> time of sampling + internal prescaler of TM1 + external prescalers)
>
> The most interesting features is that it "will have" an "auto scale"
> feature, for make readings with the more exact method for the
freq being
> measured (aka. minimizing the error for that freq)
>
> But... (as always) I have a problem...
>
> I need to BREAK the counting of a running _usec_delay()
instruction from
> a interrupt routine...
>
> I explain (code attached):
>
> I start counting TMR1 pulses on RB6 for 1 sec time lapse, and with
> interrupts on the overflow of it I detect the need of jump on the
"range
> / scale", then I change any of the sampling period, internal
prescaler
> and/or external prescaler to suit the next scale and then you have a
> autorange freq. meter...
>
> The problem is found when I measure a freq that is much BIGGER
for the
> initial sampling period of 1s...
>
> Think on it and dive in the code....
>
> 7110khz (7110000 pulses in ONE second) is around 108 interrupts
in ONE
> second... so the autorange function goes crazy and get to the top of
> scale from overloaded interrupts per seconds...
>
> The obvious solution is breaking the _usec_delay() instruction
from the
> interrupt routine... that will require asm which I do not know... or
> another dirty trick...
>
> But, Hey!... I realize NOW that using another timer for setting the
> sampling period can be the solution... (GGGGGRRRRR somebody
suggest this
> before and I have not listen to it...)
>
> Yes, forcing the timer of the sampling period to timeout an thereof
> ending the sampling period will be the way...
>
> I will try that tomorrow, nevertheless, the code is attached,
comments,
> suggestions, etc, will be welcomed...
>
> I have the proteus project if anyone like to try it...
>
> Just ignore the lcd for now and attach a serial console at 38_400
bauds
> to the PIC and see the debug info...
>
> The code is a work in progress, no optimization or cleaning yet...
>
> Cheers... and enjoy it
>
> PS: Forgive my english if you found an error or two, I'm a spanish
> speaking person...
>
> El 27/07/13 22:41, Ing. Pavel Milanes Costa escribió:
>> Hi all.
>>
>> I'm here reading and searching but I can't find a way of counting
>> asynchronous TTL pulses with jal/jallib over a given time slot...
>>
>> It must be done with the timer module of the pic... (I think...)
>>
>> I explain:
>>
>> I want to make a frequency counter for zero to 250 Mhz, with 2
external
>> prescaler, using direct counting for low freq's, med prescaler
to about
>> 50 Mhz and a dedicated prescaler for above 50 Mhz - 250 Mhz+
>>
>> But I have not a clue how to use the timer1 as an asynconous 16 bit
>> pulse counter of the PIC16F88 I have for the project.
>>
>> Output will be to a cheap 4bit LCD or UART serial to a PC, click
will be
>> HS 20 Mhz XTAL...
>>
>> Other candidate is a PIC16F628 in my junkbox.
>>
>> Math is not a problem when I can say something like:
>>
>> <pseudo-code>
>> a = count(pin_b1,100) -- count pulses on pin B1 for 100ms
>> </pseudo-code>
>>
>> Any clue, sample code or tip is welcomed.
>>
>> 73 de CO7WT, Pavel in Cuba Island.
>>
>
--
You received this message because you are subscribed to the Google
Groups "jallib" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to [email protected].
<mailto:[email protected].>
To post to this group, send email to [email protected].
<mailto:[email protected].>
Visit this group at http://groups.google.com/group/jallib.
For more options, visit https://groups.google.com/groups/opt_out.
--
You received this message because you are subscribed to the Google
Groups "jallib" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/jallib.
For more options, visit https://groups.google.com/groups/opt_out.
--
You received this message because you are subscribed to the Google Groups
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/jallib.
For more options, visit https://groups.google.com/groups/opt_out.