I need to calculate time period of a frequency in the range of 30kHz-50kHz. using PIC microcontroller.
I have sampled frequency for 0.1 Sec. and have counts in register. How can I divide 1 by these count?
Can any one help me please.
Irfan
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]: PIC only [EE]: engineering [OT]: off topic [AD]: advertisements
T = 1 /f so if the frecuency range is 30kHz-50Khz then
time periody range is T = (1/30)ms-(1/50)ms or T=
(1000/30)us-(1000/50)us
so you need divided 1000/# counts for get a time periode in us
Francisco Armenta
"Muhammad Irfan(TECHNOMAN)" wrote:
>
> I need to calculate time period of a frequency in the range of 30kHz-50kHz. using PIC microcontroller.
> I have sampled frequency for 0.1 Sec. and have counts in register. How can I divide 1 by these count?
> Can any one help me please.
> Irfan
>
> --
> http://www.piclist.com hint: PICList Posts must start with ONE topic:
> [PIC]: PIC only [EE]: engineering [OT]: off topic [AD]: advertisements
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]: PIC only [EE]: engineering [OT]: off topic [AD]: advertisements
"Muhammad Irfan(TECHNOMAN)" wrote:
>
> I need to calculate time period of a frequency in the range of 30kHz-50kHz. using PIC microcontroller.
> I have sampled frequency for 0.1 Sec. and have counts in register. How can I divide 1 by these count?
> Can any one help me please.
> Irfan
>
> --
> http://www.piclist.com hint: PICList Posts must start with ONE topic:
> [PIC]: PIC only [EE]: engineering [OT]: off topic [AD]: advertisements
-- http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]: PIC only [EE]: engineering [OT]: off topic [AD]: advertisements
OK, let's say that you have 250 counts accumulated over .1 seconds. If you
multiply that by 10 you get 2,500 counts, which is the frequency.
1/2,500 = .0004
Note that 10,000/2,500 = 4
If we shift the decimal point four places to the left we get .0004, which
is the answer we are looking for.
Now, the count you have is in binary, not decimal, so we apply the same
trick, but from a binary perspective. We will multiply the 1 by some
convenient binary power such as 128 256 512 1024 2048, etc.
Since your maximum stored count is going to be 5,000 this
corresponds to a 1/x value of .0002 In reality, since the sample
gate time was .1 seconds, this corresponds to an ACTUAL period of
.00002 which is merely a matter of shifting the decimal point.
So here's one way to do it:
1) Load the Numerator with 10,000 expressed in binary/hex.
2) Divide the Numerator by the Denominator (x) using binary/hex division.
3) Convert the answer into Decimal form.
4) Pad to the left with zeros.
5) Place the decimal point at the proper location.
6) Display decimal result.
For example, if the frequency is 8.100 kHz, then the accumulator will
have a count of 810. (Note the loss of the last digit).
10,000/810=12 (Note the loss of all but the integer part of the answer).
.00012 is the displayed decimal answer, arrived at by placing the decimal
point 5 places to the left.
If you have a divide routine that can handle a 24 bit numerator, then
you could use 10,000,000 as the numerator. That would yield a final
answer of .00012345 You should realize that the last digit (5)
COULD be in error due to the .1 second sampling period, even though in this
particular example it happens to be right on. You will get a frequency
of 8.100 kHz even if the actual frequency is 8.109 kHz. While the
error is small at high frequencies, it is large at low frequencies. For
example, from 10 Hz to 19.9 Hz the perceived frquency will be 10 Hz.
When the frequency is low it is better to measure the period and
then calculate the frequency. Since p=1/f and f=1/p you can use the same
mathematical trick presented here to determine frequency from the period.
What accuracy are you looking for, how many bits. I'm wondering if the
binomial expansion might be usefull since it only consists of multiply and
add operations.
Muhammad, you will have to use a divide routine. You don't mention which pic
you are using, but a look at the application notes will sort you out. You
could even customise one of the divide routines to become a dedicated
inverting routine. I would use fixed point math with a 32/16 bit or 16/8
bit unsigned divide (you don't mention how bits store your count).
A better solution may be to use the capture module and measure the period of
the signal directly, possibly averaging that over say 64 or 128 readings.
See AN526 and/or AN544 for lots of unsigned divide routines.
part 1 3378 bytes content-type:text/plain; charset=us-ascii (decoded 7bit)
Here is absolutely crazy code that may help. I never wrote something
like this :)
Don't know how to explain its operation, but what it does is
approximate calculation of 32768/x using linear interpolation between
points where x=1,2,4,8,16,32,64,128,256.
The routine can be extended for other number of bits in x.
I attached MATLAB functions that allow to compare the approximated and
ideal functions.
;test
cblock
x, yh, yl
endc
clrf x
; movlw 129
; movwf x
again
call Reciprocal8
nop
incf x, f
goto again
;****************************************************
;
; Approximate calculation of 32768/x
; Input: x
; Output: y = 256 * yh + yl ~= 32768/x
;
; To calculate reciprocal, linear interpolation
; is used between points, where x=1,2,4,8,16,32,64,128
;
; Size: 19 instructions
; Execution speed(worst case including return):
; 6+4*8-1+4+4+2=47
;
; 4 Aug 2000 by Nikolai Golovchenko
;****************************************************
Reciprocal8
movf x, w
skpnz
retlw 1 ;error - division by zero
movwf yh
clrf yl
setc
Reciprocal8a
rrf yl, f
rlf yh, f
skpc
goto Reciprocal8a
clrc
rrf yh, w
clrf yh
subwf yh, f
Reciprocal8b
rrf yh, f
rrf yl, f
skpc
goto Reciprocal8b
retlw 0 ;ok
;****************************************************
Hope it helps,
Nikolai
On Thursday, August 03, 2000 Roland Andrag wrote: {Quote hidden}
> Muhammad, you will have to use a divide routine. You don't mention which pic
> you are using, but a look at the application notes will sort you out. You
> could even customise one of the divide routines to become a dedicated
> inverting routine. I would use fixed point math with a 32/16 bit or 16/8
> bit unsigned divide (you don't mention how bits store your count).
> A better solution may be to use the capture module and measure the period of
> the signal directly, possibly averaging that over say 64 or 128 readings.
> See AN526 and/or AN544 for lots of unsigned divide routines.
What accuracy are you looking for, how many bits. I'm wondering if the
binomial expansion might be usefull since it only consists of multiply and
add operations.
--- "Muhammad Irfan(TECHNOMAN)"
<spam_OUTtechnokhTakeThisOuTCYBER.NET.PK> wrote:
> I need to calculate time period of a frequency in
> the range of 30kHz-50kHz. using PIC microcontroller.
> I have sampled frequency for 0.1 Sec. and have
> counts in register. How can I divide 1 by these
> count?
> Can any one help me please.
> Irfan
>
> --
> http://www.piclist.com hint: PICList Posts must
> start with ONE topic:
> [PIC]: PIC only [EE]: engineering [OT]: off topic
> [AD]: advertisements
You can do this by using fixed point mathematic
routines AN617 from Microchip's Application Notes.
According to this what accuracy you want you should
select one of them (24/16 bits for example etc.).
Good look.
Emil
__________________________________________________
Do You Yahoo!?
Kick off your party with Yahoo! Invites. http://invites.yahoo.com/