![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
I have a 10Mhz Rubidium Frequency Standard. I'm thinking of building a 100Mhz PIC-based frequency counter using that as the time base. Should I use the 10Mhz as the PIC oscillator (assuming a 20MHz PIC)? What is the best way of generating counting periods of 0.01, 0.1, 1, and 10 seconds? (some combination of Timer 0, 2 and software?) I will use an external modulo 256 high-speed counter to prescale the 100 MHz so that the highest frequency counted directly by the PIC will be 390KHz. That requires using a CCP (Timer 1) module and software to accumulate the counts? The idea would be to gate the prescaler with the PIC derived counting period, and then be able to read the prescaler counter value into a port so that it can be concatenated with the count accumulated inside the PIC. The result would get converted to decimal and displayed on an LCD as Hz. If a port pin is set high and then low for the duration of the counting period, will that produce a sufficiently accurate gating of the signal being counted? (different delay of the port pin going high compared to going low?) Or should I use an external high-speed toggle flip-flop so that the external gating period could be the time between two successive up-edges? Anybody have any other suggestions.
__________________ Mike ML. | |
| |
| | #2 |
|
Where did you get the Rubidium freq standard?? And how much? I want one. ![]() Yep I would use the 10Mhz standard as the PIC osc. You can forget any gating system if you want accuracy. You need to use free running timers and design the period measuring software so the entry error is statistically equal to the exit error, then average over sufficient samples to cancel the errors. | |
| |
| | #3 | |
| Quote:
| ||
| |
| | #4 | |
| Quote:
__________________ Mike ML. | ||
| |
| | #5 |
|
I was thinking about gating the signal into the prescaler, so that I could get 8 digit precision. That means stopping the count in the prescaler, and then reading the value in the prescaler and using it to extend the count to ~24 bits. The gating accuracy would have to be about 5 ns. That's why I'm thinking that an external toggle flip-flop which times between two successive up edges might work better.
__________________ Mike ML. | |
| |
| | #6 |
|
Nice unit. Does it need to be calibrated like many of the Rubidium modules? I just looked at a few datasheets and most have a "freq adjust" input. Still going with the gating idea? | |
| |
| | #7 |
|
Hi MikeMl, Just wondering why you decided on 100-MHz? You might consider using Timer 0 with its 1:256 prescaler for a 50-MHz counter and using a high speed divide-by-two counter on the T0CKI input to realize a 100-MHz top end. You don't need any fancy "gate" hardware to turn the counter on and off. Just toggle the T0CKI pin from an output to an input to start the counter and after a precise period toggle it back to an output to stop the counter. Use a 1000 ohm resistor between signal source and T0CKI pin to absorb the input signal while T0CKI is configured as an output. Timer 0 is an 8-bit counter on most PICs so you would use TMR0 register value for the middle 8 bits of your 24 bit result and use Timer 0 overflows for the upper 8 bits of the 24 bit result. With a 50-MHz input signal you could expect a Timer 0 overflow approximately every 1.3-msecs so it's important to check for overflow at least that often while counting. Capturing the 1:256 prescaler value and using it for the least significant 8-bits of the 24-bit count is pretty well documented and shown below. Here's an example excerpt of the most significant portion of a 50-MHz counter program. I hope it gives you some new ideas. Kind regards, Mike Code: NewCount
clrf TMR0 ; clear TMR0 and prescaler |B0
bcf INTCON,T0IF ; clear T0IF interrupt flag |B0
clrf CountL ; clear 24 bit counter registers |B0
clrf CountH ; |B0
clrf CountU ; |B0
movlw 200 ; |B0
movwf msctr ; gate timer = 200 msecs |B0
movlw TRISIO ; |B0
movwf FSR ; setup TRISIO indirect access |B0
bsf INDF,2 ; counter "on" (T0CKI = input) |B0
;
; count pulses on the T0CKI input for precisely 200-msecs
;
GateOn setz ; set Z = 1 |B0
btfsc INTCON,T0IF ; TMR0 overflow? no, skip, else |B0
incf CountU,F ; bump CountU, Z = 0 |B0
skpz ; TMR0 overflow? no, skip, else |B0
bcf INTCON,T0IF ; clear T0IF interrupt flag |B0
DelayCy(1*msecs-8) ; delay 1 msec minus 8 cycles |B0
decfsz msctr,F ; 200 msecs? yes, skip, else |B0
goto GateOn ; loop again |B0
bcf INDF,2 ; counter "off" (T0CKI = output) |B0
btfsc INTCON,T0IF ; TMR0 overflow? no, skip, else |B0
incf CountU,F ; bump CountU |B0
bcf INTCON,T0IF ; clear T0IF interrupt flag |B0
;
; collect 1:256 prescaler value
;
movf TMR0,W ; |B0
movwf CountH ; save TMR0 value |B0
Flush bsf STATUS,RP0 ; bank 1 |B1
bcf OPTION_REG,T0SE ; clock on rising edge |B1
bsf OPTION_REG,T0SE ; clock on falling edge |B1
bcf STATUS,RP0 ; bank 0 |B0
decf CountL,F ; decrement counter LSB |B0
movf TMR0,W ; |B0
xorwf CountH,W ; prescaler overflow into TMR0? |B0
bz Flush ; no, clock it again |B0
;
; do something with the 24-bit (frequency/5) count
;
Last edited by Mike, K8LH; 29th October 2009 at 10:15 AM. | |
| |
| | #8 | |||
| I want to go to 1GHz with a decade prescaler, so 100MHz without it. I want 1Hz resolution at 100MHz (more on this later); 10Hz resolution when using the prescaler. Quote:
Quote:
Quote:
After thinking about it some more, since I have a time base which is good to about 10^-9, I would like to have 1Hz resolution at 100MHz, which because I will be dividing by 2 to begin with, means I will have to count for 2sec. That means I will have to implement counting to at least 27 bits, i.e. 32 bit arithmetic. To avoid a 32 bit division, is it best to generate counting intervals of 0.02, 0.2, or 2 sec?
__________________ Mike ML. | ||||
| |
| | #9 | |
| Quote:
Your 16F873 and 16F874 can read the 1:256 prescaler by toggling the T0SE edge select bit as described in my previous post. With a 32 bit count the upper 16 bits (upper two bytes) would accumulate the Timer 0 overflows. The 32 bit math isn't much different from 24 bit math. Mostly bit shift and add operations. The binary-to-bcd or binary-to-ascii routine is probably more involved. Good luck on your project. Mike, K8LH | ||
| |
| | #10 |
|
You might wish to have a look at the Silicon Chip 50MHz frequency meter. It uses no external dividers and gates the signal using an IO pin. Apparently it can read up to 64MHz (this may be a limitation due to the transition time of the 74HC132 gates and not the PIC). It also uses the obsolete 'F84, so it may be possible to read an even higher frequency directly with a newer PIC model. Circuit diagram may be seen here: A Low-Cost 50MHz Frequency Meter Last edited by dougy83; 29th October 2009 at 08:10 AM. | |
| |
| | #11 | |
| Quote:
Regards, Mike Last edited by Mike, K8LH; 29th October 2009 at 09:27 AM. | ||
| |
| | #12 |
|
Just be aware of the entry error caused by using the TMR1 for external count. That's why I suggested using free running timers capturing the value and averaging over N samples.
| |
| |
| | #13 |
|
I've experienced a funny first count anomaly using Timer 1 as an asynchronous counter before. Is that what you're referring to, Roman?
| |
| |
| | #14 |
|
No it's to do with measuring a frequency within a period. Let's say you can use the PIC to generate an exact 1 second period. The frequency is asynch to that period. So if you measure the / adge of the freq, the worst neg case is if the two (first and last) / edges are JUST outside the start and end of the period. So the frequency will measure as -1. The worst positive case is if the two / edges are JUST within the start and end of the period, that gives a freq error of +1; So for that system of measurement the error of the freq you measure will be +/- 1 count. You can live with that as the entry and exit error have the same staistical chance of occuring so after a long period of time sampling and averaging will give a zero error reading. But the PIC TMR1 / edge count only counts the first / edge after it detects a \ edge, so you get an "entry" error at the start of the period which is not balanced at the end of the period. You can get around it by leaving the TMR1 counter as free running (never stopping or starting it) which is closer to the solution I mentioned because at least it balances the entry and exit error. There is still an issue because you might be measuring a frequency that occurs at a beat of the period. Going one better is to use 2 free running systems. If you manually poll the period in a PIC btfss loop it takes 3 instructions, then grab the free running TMR1 counter value, then manually poll for the end of the second and grab the TMR1 counter value. Now you have 2 sets of entry and exit errors, each set is self cancelling so combined accumulated error is zero, but the big advantage comes from the beat frequency being forced to be random (and repeating) by the manual polling loops that take 3 PIC instructions at each end of the period. It's a case where you are deliberately introducing more error of a short term cyclic nature so the accumulated average measurement will be a lot more accurate. | |
| |
| | #15 | |
| Quote:
__________________ Mike ML. | ||
| |
|
| Tags |
| 100mhz, counter, frequency, frequency counter |
| Thread Tools | |
| Display Modes | |
| |
Similar | ||||
| Title | Starter | Forum | Replies | Latest |
| Frequency Counter | Powzoom | Electronic Projects Design/Ideas/Reviews | 1 | 30th January 2009 11:21 PM |
| 100mhz oscillator circuit | gray5596 | Electronic Projects Design/Ideas/Reviews | 6 | 9th May 2008 02:59 PM |
| Frequency counter | yasser11 | Electronic Projects Design/Ideas/Reviews | 2 | 5th April 2006 04:49 PM |
| Frequency Counter | Gregory | Electronic Projects Design/Ideas/Reviews | 4 | 28th January 2006 03:16 PM |
| frequency counter | samcheetah | Electronic Projects Design/Ideas/Reviews | 4 | 5th May 2004 11:42 PM |