Attached is my program for calculating the frequency divisor words for the FEI
FE-5650A and FE-5680A rubidium oscillators with the AD9830A based DDS board.
It compensates for the difference between the R=reference freq that the 'S'
command returns (the minimum C-field value) and the frequency that the
oscillator was actually shipped tuned to.
The program does not actually read and write the serial port directly (would be
a nice mod though). You will need to recompile it with the values returned by
your oscillator 'S' command. There are two #defines at the start of the
program.
Usage is:
freq 10 (for 10Hz)
freq 10 K (for 10KHz)
freq 10 M (for 10MHz)
_________________________________________________________________
Now you can invite friends from Facebook and other groups to join you on
Windows Liveā¢ Messenger. Add now.
https://www.invite2messenger.net/im/?source=TXT_EML_WLH_AddNow_Now
#include "stdio.h"
#include "math.h"
#include "string.h"
// This program calculates the Analog Devices 9830A DDS frequency divisor
// values for programming the FEI FE-5650A and FE-5680A rubidium oscillator
// units.
//
// This program was written by Mark S Sims May 2008. It is relased to the
// public domain. Use it in peace. Plase share with others what you do
// with it.
//
// These are the reference freq and divisors returned by the FEI "S" command
// They vary from unit to unit. Change these to whatever your unit returns (or
// modify this program to interrogate the unit with the "S" command. While you
// are at it, modify this program to send the divisor word to the oscillator.
//
#define R 50255055.011982
#define F 0x2ABB5050L
#define FF ((double) 8388608.0) // the freq the module was calibrated for
#define M ((double) 4294967296.0) // 2^32
double r=R; // working reference frequency
double f=FF; // working DDS divisor word
void lll(double x)
{ // print divisor as a 64 bit hex value
char s[20];
int i;
for(i=0; i<16; i++) s[i] = 0;
i = 0;
x = x * M * M;
while(x>0.99) {
s[i++] = fmod(x, 16);
if(i > 16) break;
x = x / 16.0;
}
for(i=15; i>=0; i--) {
printf("%X", s[i]);
if(i == 8) printf(":");
}
printf("\n\n");
}
main(int argc, char *argv[])
{
double d;
double x;
if(argc > 1) { // get desired freq from command line
sscanf(argv[1], "%lf", &f);
if(argc > 2) { // if more than one command line arg, freq is in MHz or
KHz
if(toupper(argv[2][0]) == 'K') f *= (double) 1000.0;
else if(toupper(argv[2][0]) == 'H') f *= (double) 1.0;
else f *= (double) 1000000.0;
}
else if(strchr(argv[1], 'K')) f *= (double) 1000.0;
else if(strchr(argv[1], 'k')) f *= (double) 1000.0;
else if(strchr(argv[1], 'M')) f *= (double) 1000000.0;
else if(strchr(argv[1], 'm')) f *= (double) 1000000.0;
}
// print input data values
printf("\nR=%19.10lf F=%08lX (f=%lf)\n\n", R,F,FF);
// calculate what freq the R= and F= values returned from the
// oscillator would produce
d = ((double) F) / M;
d *= r;
printf("R*F/(2^32)=%19.10lf ref_scale=%.14lf\n", d, FF/d);
// scale the R= reference freq by that value to get the actual
// oscillator reference freq
r = r * FF / d;
printf("actual ref=%.10lf\n\n", r);
// show what the 64 bit DDS divisor should be
printf("freq=%.10lf\n\n", f);
d = f / r;
printf("freq/ref=%.19lf\n", d);
printf("full divisor=");
lll(d);
// calculate the closest 32 bit divisor that the AD9830A DDS chip
// will actually use
d *= M;
d = (double) (unsigned long) (d+0.5);
// now show the actual generated frequency and the two closest ones
x = r * (long) (d-1);
x /= M;
printf("freq(%08lX) = %.10lf err=%13.10lf (%.3lg)\n", (long)d-1, x, x-f,
(x-f)/f);
x = r * (long) d;
x /= M;
printf("freq(%08lX) = %.10lf err=%13.10lf (%.3lg)\n", (long)d, x, x-f,
(x-f)/f);
x = r * (long) (d+1);
x /= M;
printf("freq(%08lX) = %.10lf err=%13.10lf (%.3lg)\n", (long)d+1, x, x-f,
(x-f)/f);
printf("\n");
printf("nearest divisor=%08lX\n", (unsigned long) d);
}
_______________________________________________
time-nuts mailing list -- time-nuts@febo.com
To unsubscribe, go to https://www.febo.com/cgi-bin/mailman/listinfo/time-nuts
and follow the instructions there.