Guyzz
I have bought a 10.00000000000(Lots'o Zeroes) Mhz Rubidium Freq Reference (Ehh... Doesn't one have to have one ??).
The Rubidium Oscillates around 50Mhz , and there is an AD9830A DDS chip that can divide/adjust the output frequency.
The AD9830A is controlled by a ... "MCU who's name must not be mentioned" or we have to call for "Harry" & hope Leon doesn't read this :-).
Basically there is an RS-232 connection to the MCU , and you can put in a frequency divider word that the MCU writes to the DDS.
I'd like to build it into a box w. a keypad & a LCD, and use an AVR to calc the word and send it via rs232 to the "Dark MCU"
But if i can't get enough precision in the calculations , i'll loose a lot of the above "zeroes".
Some guy made this example in C , and he uses a lot of doubles. But i wonder if this can be made in Integer arithmetik on an AVR , or if i'll have to download another compiler and keep my fingers crossed that this fit's in an eval version.
I had to replace percent with paragraph § , or Freaks .. Freaked out :-(So the printf's are formatted funny
/* 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) */ #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); system("PAUSE"); return 0; }
/Bingo