View previous topic :: View next topic |
Author |
Message |
azny
Joined: 25 Aug 2008 Posts: 36 Location: usa
|
Posted: Sun May 04, 2014 3:22 am Post subject: Challenge #1: frequency counter code module |
|
|
Hi All;
I am looking for a stand alone subroutine that will simply measure the frequency of an incoming square wave. Currently i use an external counter and simply port in the digital word. I would like to migrate to the internal timer/counter of the ATmega 164p or the ATtiny 44. However, there are too many confusing posts in the forum with bits and pieces of snippet code, all tweaked for various parameters, some of which are contradictory as well as confusing.
Yes, i can wade through all the posts, delve into the intracacies of registers, flags and interrupts-- but business is booming and i can't afford to take a week to do this-- I'm being honest and straight forward here.
Surely, there are those experts in the community that can develop this subroutine, and document it in a clear understanding manner, in a matter of hours, even might have one in their back pocket already. I'm simply looking for a drop in self contained routine module
I'd be more than willing to trade/barter/pay someone for this subroutine-- just name your favorite case of beer, wine, chocolate covered mints-- motor oil, whatever floats your boat.
Any takers??
BTW, i have many other of these short module projects-- with the right expert this could be the beginning of a beautiful relationship
Thanks in advance
(BASCOM-AVR version : 2.0.7.1 , Latest : 2.0.7.7 ) |
|
Back to top |
|
|
sidknox
Joined: 30 Apr 2006 Posts: 29 Location: NorthEast Oklahoma USA
|
Posted: Sun May 04, 2014 5:39 am Post subject: |
|
|
Expecting a "universal" freq counter code module seems unreasonable to me. The coding of the Subroutine or Function will be dependent upon:
1) input frequency
2) count resolution
3) capability of the chosen uP
4) maybe other things....
$0.02
Sid
Oklahoma _________________ SidK
Oklahoma
USA |
|
Back to top |
|
|
bzijlstra
Joined: 30 Dec 2004 Posts: 1179 Location: Tilburg - Netherlands
|
Posted: Sun May 04, 2014 7:01 am Post subject: frequency counter up to 1 Mhz |
|
|
Have edited my first post, the routine is not for the 89c2051 but for an atmega88.
Got a routine for a finished frequency counter up to 1 Mhz. Written for an atmega88.
Will try to find it and post it here.
Have fun
Ben Zijlstra
Last edited by bzijlstra on Sun May 04, 2014 7:27 am; edited 1 time in total |
|
Back to top |
|
|
Visovian
Joined: 31 Oct 2007 Posts: 584 Location: Czech
|
Posted: Sun May 04, 2014 7:21 am Post subject: |
|
|
I agree with sidknox.
Frequency measuring mostly involves using timers and interrupt service routines.
I doubt it can be done in a stand alone function.
Note that an AVR itself can measure the frequency only up to cca 45% of '$crystal'.
I think the code is quite simple. You surely need not to pay for it.
You either measure number of pulses in a fix time or time of a periode.
An example to show the principle:
Frequency from 0 to 65 kHz with resolution 1 Hz
Code: | 'measure frequency on pin T1
dim freq as word
Config timer1 = counter
Do
timer1 = 0
waitms 1000
freq = timer1
print freq ; " Hz"
Loop |
You can experiment with 'waitms' line.
If you change to waitms 100, you get range to 650 kHz with resolution 10 Hz. And so on.
Last edited by Visovian on Sun May 04, 2014 9:43 am; edited 1 time in total |
|
Back to top |
|
|
bzijlstra
Joined: 30 Dec 2004 Posts: 1179 Location: Tilburg - Netherlands
|
Posted: Sun May 04, 2014 8:53 am Post subject: Already published... |
|
|
Did a search and have seen that Paulvk already published the 1 Mhz Frequency Counter code...
Have fun
Ben Zijlstra |
|
Back to top |
|
|
azny
Joined: 25 Aug 2008 Posts: 36 Location: usa
|
Posted: Sun May 04, 2014 1:53 pm Post subject: further refinement |
|
|
I also agree with sidknox-- i didn't knpw what kind of a response i would get from the community, so here are some of the parameters to chew over:
(1) input frequency: up to 6.5MHz
(2) count resolution: 16-bit
if you can use the timer/counter to 45% xtal than the clock freq would be ~14.445 MHz, well within the 20MHz range of the ATmega 164p and the ATtiny44-- so i'll choose a convenient 14.7456MHz xtal to insure all baud rates with 0% error.
anything else i need to specify?? |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Sun May 04, 2014 2:27 pm Post subject: |
|
|
All the frequency counters I own (I have 4) use a 10Mhz crystal , they all use a divider in their front end. They use the 10Mhz crystal for accuracy as its a standard you can get good stable crystal at a low price , they use the divider because there are ICs made for the exact job even some 74 series. It is easy to divide the incoming signal you can even get the AVR to change division rates if it over flows the counter. You need to get as many counts as you can but not overflow the counter so you get more decimal places to your count.
These are the basic things I have looked at when I built conventional counters in the past.
Regards Paul |
|
Back to top |
|
|
azny
Joined: 25 Aug 2008 Posts: 36 Location: usa
|
Posted: Sun May 04, 2014 6:25 pm Post subject: |
|
|
Hi Paul;
if i have to use an external divider i might as well stick with my external 32-bit counter (TI '8154) which is going to give me better resolution than anything an 8051 can do internally that i'm aware of. I bring over the 4X8 bit words and viola, i have a 32-bit resolution counter that works up to 40MHz like a piece of cake-- yes i have to dedicate a port for the word (i.e. A0-7), but it's well worth it for the resolution
my goal here is to elliminate any extrenal counting components-- yes, i'll sacrifice some resolution, but i'll save the PCB real estate and cost of external components. 16-bit accuracy in this configuration is more than adequate for what i want to measure.
So, back to my original question-- is there a relatively simple, straigh forward stand alone subroutine that will use the uP's internal timer/counter that would avoid using external components such as divider, scalers, and counters?? |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
|
Back to top |
|
|
Neill
Joined: 08 Dec 2008 Posts: 50
|
Posted: Tue May 06, 2014 3:50 am Post subject: |
|
|
I'm with Sidknox on this, post #2.
What is the specification fro this counter?
I typically use one of two methods depending on the frequency being measured, basically whether or not a 16 bit timer can be expected to overflow or not.
In order for this routine to be efficient we need to know the specifications/requirements, see post #2 |
|
Back to top |
|
|
azny
Joined: 25 Aug 2008 Posts: 36 Location: usa
|
Posted: Tue May 06, 2014 1:30 pm Post subject: |
|
|
Hi Neill;
see my reply at post #6-- this should get you started; any other requirements just ask |
|
Back to top |
|
|
azny
Joined: 25 Aug 2008 Posts: 36 Location: usa
|
Posted: Tue May 06, 2014 1:41 pm Post subject: |
|
|
Hi Paul;
must be a mistake-- the thread you sent is simply using a 1 second gate generated by the ATtiny and then a simple internal increment from the Atmega 8, all he's doing is a simple C=C+1 for the duration of the ATtiny pulse-- that's not counting an external frequency; that's just seeing how much time an internal command takes; can't seem to find anywhere in his post how he's using the timer/counter function-- maybe i missed something, can you point me in the right direction? thanx |
|
Back to top |
|
|
jodank
Joined: 22 Apr 2014 Posts: 49
|
Posted: Sun May 18, 2014 9:08 pm Post subject: |
|
|
Azny:
here is an old project which I made long time ago. It should measure input frequecy and print to the lcd.
I finished the project and it is working.
If you wish I can search on my old hdd for the finished code.
here is the code on some point when I was on the project:
Code: |
$regfile = "m16def.dat"
$crystal = 8000000
Config Portb.1 = Input
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Config Timer0 = Timer , Prescale = 64
Config Timer1 = Counter , Edge = Rising
Dim Count As Integer
Dim Timer0_counter As Integer
Cls
Cursor Off
Load Timer0 , 125
Enable Timer0
Enable Timer1
Start Timer0
Start Timer1
Enable Interrupts
On Ovf0 Timer0_isr
Count = 0
Timer0_counter = 0
Do
Locate 1 , 1
Lcd Timer0_counter
Loop
Timer0_isr:
Incr Count
If Count = 1000 Then
Incr Timer0_counter
Count = 0
End If
Return
|
Feel free to use, modify and use it for what you want to need... |
|
Back to top |
|
|
|