Calculating a frequency offset using a PIC

  • Thread starter Thread starter Bryan_S
  • Start date Start date
  • Tags Tags
    Frequency
AI Thread Summary
The discussion revolves around calculating a frequency offset for an AD9851 controlled by a PIC microcontroller, focusing on achieving accurate calibration despite limited floating-point capabilities. The standard calibration procedure involves setting the AD9851 to 10 MHz and measuring the output against this frequency, with any discrepancies needing to be factored into the PIC as a calibration constant. The user struggles with maintaining precision due to the 7 significant digit limit in calculations, particularly when offsets are introduced. Suggestions include using fixed-point arithmetic to improve precision without exceeding the significant digit constraints. The conversation emphasizes the need for a reliable method to accurately calculate the offset while adhering to the limitations of the PIC microcontroller.
Bryan_S
Messages
1
Reaction score
0
I am working with an analog devices AD9851 which is controlled by a Pic microcontroller. I need to calculate an offset frequency for calibrating the AD9851. Typical calibration procedure is to set output of the AD9851 to exactly 10Mhz out. Output is then measured with a frequency counter. Any difference between the set frequency and measured frequency needs to be entered into the Pic as a calibration factor when other frequencies are chosen.

Formula for calculating the proper control code for the AD9851 is as follows.

Code = freq*(2^32/(180E6 + offset)

(freq) in Mhz to set the output of the AD9851
(offset) is in hz
(180E6) is the actual clock frequency. A crystal at 30Mhz with a 6 times multiplier is used.

an example is 238609294 = 10E6*(2^32/180E6 + 0) no offset here

another one 238606908 = 10E6*(2^32/180E6 + 1800) offset is 1800 because at 10 Mhz
an offset of 100 hz was measured
so we multiply 100 hz by 18

Both examples would provide correct control codes to the AD9851.

My problem is performing these calculations with limited floating point routines in a Pic microcontroller. I can only use 7 significant digits within any calculations.


So, I tried it this way. Let's take my second example.
I need to output a code to the AD9851 of 238606908.

2^32 = 4294967296 //I divide this by two to make it smaller to work with.
4294967296/2 = 2147483648
2147483648/180001800 = 11.9303454 //div it by clock freq+offset
11.9303454 * 2 = 23.8606908 // mult it back up by 2
10E6 * 23.8606908 = 238606908 // mult by freq set by unit is correct here


Still this will not work within the confines of my Pic microcontroller code because it exceeds 7significant digits in many places.
For example 11.9303454 is 9 significant digits I cannot use it a 32bit floating point representation of it. 238606908 is a long integer so it is OK to use. Only floating point numbers can be used with other floating point numbers. I cannot use integers with floating point numbers when performing calculations such as + - / or * for example. These are the rules I have to use. So, I thought of doing it another way. Which works but only if I don't have an offset frequency to add to 180E3. This is where I think I need some help. Here is what I did. How I initially set the frequency to the AD9851 is by using two constants. One is 11 and the other is .9304647 together it is 11.9304647.

If I multiply 11 by 10mhz and then .9304647 and add them together I get
110000000 + 9304647 = 119304647
119304647 * 2 = 238609294 <-- correct code for 10mhz output.

I make 11 a float and also .9304647 after multiplying them they remain floats because 110000000 has only 2 siginificant digits and is actually 11E7 and 9304647 contains 7 significant digits. All good there.
Seeing I am going to be working with small values for offset frequencies for example like
116 hz I figured all I really need to work with is just the decimal portion of the number
like .9304647 and leave the 11 out of the calculation till end will I will just add it back.

Well it works but only for frequencies with no offsets. Once I add an offset to the calculation I get incorrect results. Here is what I did hope it makes some sense.
The result of this is to get a constant I can use that represents an offset in my crystal or clock driving the AD9851.

2^32/2 = 2147483648
Next I try to eliminate 11 out of this by
11 * 180E6 = 198E7
subtract above value from 2147483648 (This I know is where my problem is)
2147483648 - 198E7 = 167483648

The following is performed by a Pic microcontroller
5E6 represents 1/36 of clock frequency 180mhz

167E6/5E6 = 33.4
33.4/36 = .9277777

483E3/5E6 = .0966
.0966/36 = .0026833

648/5E6 = .0001296
.0001296/36 = .0000036

lets add them all up

.9277777
.0026833
.0000036 +
---------
0.9304646

now we add 11 back
11.9304646
we are off by 1 due to rounding but it is acceptable should be 11.9304647

11.9304646 * 2 = 23.8609292
23.8609292 * 10E6 (10Mhz) = 238609292 good but off value by two but still acceptable. Should be 238609294.

Well this isn't bad until I try to add an offset to the calculation.
For example. A measured offset of 100 hz at 10Mhz will be 50Hz at 5Mhz. This is the way it is with this device and it's clock. So we have.

167E6/(5E6 + 50) = 33.39966
33.39966/36 = 0.9277683

483E3/(5E6 + 50) = 0.096599
0.096599/36 = .0026833

648/5E6 = .0001295
.0001295/36 = .0000036

add them up it is
0.9304552
Add 11 to make it
11.9304552
then we mult it by 2
23.8609104
then mult it by 10E6
238609104 is incorrect should be 238606908

This is incorrect because of doing this I believe as posted above.

2^32/2 = 2147483648
Next I try to eliminate 11 out of this by
11 * 180E6 = 198E7
subtract above value from 2147483648 (This I know is where my problem is)
2147483648 - 198E7 = 167483648

Would greatly appreciate it if anyone has any idea how I can do this correctly. I'm not a wizard at something like this. Just have to keep in mind using only 7 significant digits when the Pic has to perform any floating point calculations. 32bit long integers can be used also but you cannot combine the two types in any operation. I can convert long integers into floats and back the other way. Again the objective is to arrive at a decimal constant like
.9304646 that will represent the value of frequency offset of the clock.

Thanks again for any help it is greatly appreciated.

Bryan_S
 
Engineering news on Phys.org
Sorry, I don't have the brain cells left to follow all your arithmetic, but if the range of your result is fairly small perhaps you can consider using Fixed Point arithmetic instead of Floating Point. With Fixed Point you multiply everything by some factor before doing regular integer operations and then divide the result by the same factor. In binary the multiply/divide can be done with bit shifts and are quite efficient. For instance, shifting everything up by 4 bits gives you a precision of 1/16. You do have to have 4 bits of headroom on your values however...
 
Did a quick google and found Microchips floating-point library for PIC16/17:

http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en010961
 
Last edited by a moderator:
Hi all I have some confusion about piezoelectrical sensors combination. If i have three acoustic piezoelectrical sensors (with same receive sensitivity in dB ref V/1uPa) placed at specific distance, these sensors receive acoustic signal from a sound source placed at far field distance (Plane Wave) and from broadside. I receive output of these sensors through individual preamplifiers, add them through hardware like summer circuit adder or in software after digitization and in this way got an...
I have recently moved into a new (rather ancient) house and had a few trips of my Residual Current breaker. I dug out my old Socket tester which tell me the three pins are correct. But then the Red warning light tells me my socket(s) fail the loop test. I never had this before but my last house had an overhead supply with no Earth from the company. The tester said "get this checked" and the man said the (high but not ridiculous) earth resistance was acceptable. I stuck a new copper earth...
Thread 'Beauty of old electrical and measuring things, etc.'
Even as a kid, I saw beauty in old devices. That made me want to understand how they worked. I had lots of old things that I keep and now reviving. Old things need to work to see the beauty. Here's what I've done so far. Two views of the gadgets shelves and my small work space: Here's a close up look at the meters, gauges and other measuring things: This is what I think of as surface-mount electrical components and wiring. The components are very old and shows how...
Back
Top