PDA

View Full Version : programming DDS core



harryweb
- 19th October 2010, 15:57
Hi,

I would like to program a DDS (AD9951).
The frequency tuning word (FTW) must be calculated to have a good frequency output (Fo).
Using also the frequency of DDS clock (Fs)
My DDS clock is 360MHz = 360^6

Fo = (FTW)(Fs)/2^32 (given by Analog device)

- As I want to send FTW to the DDS for 10MHz (Fo)
FTW = (2^32x10^6)/360^6 (this is true ?)

but I don't know how to calc these big numbers... (with long ?)
thanks for helping

harryweb
- 19th October 2010, 20:09
Oh... it seems that formula is not good...

The good formula:
FTW = 2E32 x (Fo/Fs)

Same pb with 2E32...
Any idea ?

mackrackit
- 19th October 2010, 23:31
PicBasic code will work with that part?

Mike, K8LH
- 20th October 2010, 03:48
Not sure if this will help but please consider;

Fr (frequency resolution) = 360000000/2^32 = 0.08381903171539306640625 Hz

FTW = INT(Fo / Fr)
FTW = INT(10000000 / 0.08381903171539306640625) = 119304647

or using reciprocal multiplication (with a constant 1 / Fr = 11.9304647);

FTW = INT(Fo * (1 / Fr))
FTW = INT(10000000 * (11.930464711111111111111111111111)) = 119304647

Good luck on your project...

Cheerful regards, Mike, K8LH

Darrel Taylor
- 20th October 2010, 05:25
PBP doesn't have decimals, and (2^32 * 10e6) takes more than 32-bit LONGs.

But using some 64-bit math works out pretty good.
With the N-Bit_Math module from ... http://www.picbasic.co.uk/forum/showthread.php?t=12433

<font color="#000000"><b>PRECISION </b><font color="#008000"><b>CON </b></font><font color="#800000"><b>8 </b></font><b>SYSTEM </b><font color="#0000FF"><b><i>' 8 bytes = 64-bit
</i></b></font><font color="#008000"><b>INCLUDE </b></font><font color="#FF0000">&quot;N-Bit_Math.pbp&quot;

</font><b>Base </b><font color="#008000"><b>VAR BYTE</b></font>[<b>PRECISION</b>]
<b>Fo </b><font color="#008000"><b>VAR BYTE</b></font>[<b>PRECISION</b>]
<b>Fs </b><font color="#008000"><b>VAR BYTE</b></font>[<b>PRECISION</b>]
<b>FTW </b><font color="#008000"><b>VAR BYTE</b></font>[<b>PRECISION</b>]

<font color="#008000"><b>ASM
</b></font><font color="#000080">MOVE?CP 4294967295, _Base </font><font color="#0000FF"><b><i>; 2^32 - 1
</i></b></font><font color="#000080">MOVE?CP 10000000, _Fo </font><font color="#0000FF"><b><i>; desired frequency out
</i></b></font><font color="#000080">MOVE?CP 360000000, _Fs </font><font color="#0000FF"><b><i>; DDS clock

</i></b></font><font color="#000080">MATH_MUL _Base, _Fo, _FTW </font><font color="#0000FF"><b><i>; 2^32 * Fo
</i></b></font><font color="#000080">MATH_DIV _FTW, _Fs, _FTW </font><font color="#0000FF"><b><i>; / Fs
</i></b></font><font color="#008000"><b>ENDASM

HSEROUT </b></font>[<font color="#FF0000">&quot; FTW=&quot;</font>,<font color="#008000"><b>HEX2 </b></font><b>FTW</b>(<font color="#800000"><b>3</b></font>),<font color="#008000"><b>HEX2 </b></font><b>FTW</b>(<font color="#800000"><b>2</b></font>),<font color="#008000"><b>HEX2 </b></font><b>FTW</b>(<font color="#800000"><b>1</b></font>),<font color="#008000"><b>HEX2 </b></font><b>FTW</b>(<font color="#800000"><b>0</b></font>),<font color="#800000"><b>13</b></font>,<font color="#800000"><b>10</b></font>]
<font color="#008000"><b>STOP
</b></font>
Which shows a result of ...

FTW=071C71C7

Which is the hex value for 119,304,647

The value is located in the lower 4 bytes of the FTW array and can be easily shifted out to the DDS.

HTH,

harryweb
- 20th October 2010, 08:30
WOW ! It works !

Thank You Darrel

harryweb
- 20th October 2010, 10:06
But... I have tried to use a variable for Frequency output and it doesn't work anymore...



PRECISION CON 8 SYSTEM ' 8 bytes = 64-bit
INCLUDE "N-Bit_Math.pbp"

define osc 4

FOUT var LONG
Base VAR BYTE[PRECISION]
Fo VAR BYTE[PRECISION]
Fs VAR BYTE[PRECISION]
FTW VAR BYTE[PRECISION]

high portc.6

FOUT = 1000000

ASM
MOVE?CP 4294967295, _Base ; 2^32 - 1
MOVE?CP _FOUT, _Fo ; desired frequency out
MOVE?CP 360000000, _Fs ; DDS clock

MATH_MUL _Base, _Fo, _FTW ; 2^32 * Fo
MATH_DIV _FTW, _Fs, _FTW ; / Fs
ENDASM

serout2 portc.6,84,[" FTW=",HEX2 FTW(3),HEX2 FTW(2),HEX2 FTW(1),HEX2 FTW(0),13,10]
STOP

Darrel Taylor
- 20th October 2010, 11:59
MOVE?CP is for constants.

Use MOVE?LP for LONG variables.

harryweb
- 20th October 2010, 12:06
Darrel... you're wonderful !
http://www.procrastin.fr/blog/images/alcool/biere%20(s).jpg

Darrel Taylor
- 20th October 2010, 12:19
ADDED:
Since you are using PBPL, you can also move the result back to a LONG...
PRECISION CON 8 SYSTEM ' 8 bytes = 64-bit
INCLUDE "N-Bit_Math.pbp"

FOUT var LONG
Base VAR BYTE[PRECISION]
Fo VAR BYTE[PRECISION]
Fs VAR BYTE[PRECISION]
FTW VAR BYTE[PRECISION]
FTWL VAR LONG

high portc.6

FOUT = 10000000

ASM
MOVE?CP 4294967295, _Base ; 2^32 - 1
MOVE?LP _FOUT, _Fo ; desired frequency out
MOVE?CP 360000000, _Fs ; DDS clock

MATH_MUL _Base, _Fo, _FTW ; 2^32 * Fo
MATH_DIV _FTW, _Fs, _FTW ; / Fs
MOVE?PL _FTW, _FTWL ; move result to a LONG var
ENDASM

serout2 portc.6,84,[" FTW=",HEX8 FTWL," = ",DEC FTWL,13,10]
STOP