Calculate tuning value for the AD9850 DDS.


Closed Thread
Results 1 to 17 of 17

Hybrid View

  1. #1
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,518

    Default Calculate tuning value for the AD9850 DDS.

    Hi,
    I've written an article in the Wiki which shows two possible ways to calculate the 32bit tuning value for the AD9850 DDS chip from Analog Devices.

    This thread is intended for discussions and questions regarding the article.

    /Henrik.

  2. #2
    Join Date
    Dec 2011
    Location
    IO93ok
    Posts
    190


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    Very interesting Henrik.

    I have only skimped through the wiki just now and will read properly offline.

    I'm currently using one of the cheap ebay modules on a board i designed and a 16f628 to produce a tunable signal generator dds, this is other peoples code in asm though. One other code is a sweep generator/signal generator with decade digit selection by rotary encoder.

    I had been trying to do the maths (Nowhere near my capability) to use a rotary encoder in pbp. I did achieve an incrementing counter in pbp with it but got no further to convert to the tuning word.
    I was also able to get it to any frequency by inserting the byte sequence for the tuning word into the code. I had all the amateur bands set up as subs and using a pushbutton could step through them.

    I wanted to do the dds in pbp so I could add further features such as keypad freq entry, vfo a and vfo b, along with band switching outputs for a ham radio transceiver I'm building.

    Below is some sample code. I did move on much further but then got into a jam with ideas.

    Regards,
    Rob


    Code:
    '****************************************************************
    '*  Name    : DDS Frequency Generator                           *
    '*  Author  :                                    *                               *
    '*  Date    : 10/29/2012                                        *
    '*  Version : 1.0                                               *
    '*  Notes   : Uses ebay DDS board and rotary encoder            *
    '*          :                                                   *
    '****************************************************************
    
    '
    ;  16f628a
    ;  __config _CP_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_OFF&_WDT_OFF&_INTRC_OSC_NOCLKOUT
    ; 
    '       
    '
            '
            '       LCD Display
            '       -----------
            '      
            '
    Define LCD_DREG PORTB          ' Port for LCD Data
    Define LCD_DBIT 0              ' Use lower 4 bits of Port
    Define LCD_RSREG PORTB         ' Port for RegisterSelect (RS) bit
    Define LCD_RSBIT 6             ' Port Pin for RS bit
    Define LCD_RWBIT 5             ' Port Pin for RS bit
    Define LCD_EREG PORTB          ' Port for Enable (E) bit
    Define LCD_EBIT 4              ' Port Pin for E bit
    Define LCB_BITS 4              ' Using 4-bit bus
    Define LCD_LINES 2             ' Using 2 line Display
    Define LCD_COMMANDUS 1200      ' Command Delay (uS)
    DEFINE LCD_DATAUS 50           ' Data Delay (uS)
            '
            '      Control Buttons/Lines
            '      ---------------------
    PB_1 var PortA.4              ' Take this pin low momentarily to change step
    PB_2 var PortA.3              ' Take this pin low momentarily to change band
    PB_3 var PortA.2              ' Take this pin low momentarily to RESET
    EncoderRight var PortA.1       ' rotary encoder pin
    EncoderLeft var PortA.0      ' rotary encoder pin
    
    
    ddsload var PortB.7           ' dds control word pin
    ddsdata var PortB.3           ' dds data input
    ddsclock var PortB.2          ' dds clock input
    
    
    
    fStep var byte
    fcount var byte
    Counter var word
    
    
        CMCON=7      'sets 16f628 comparator pins to digital
        TRISA=%00011111       'Button & encoder inputs
    
    Counter = 0
    fcount = 0
    fstep = 1     ;start at 1 digit count
    
        LOW DDSLOAD
    
    'CONFIGURE DISPLAY
        pause 1000
        LCDOUT $FE,1    ' Clear screen
        pause 10
        lcdout $fe,$c0,dec5 counter        ; reset to zero on start
    
    
    ddstart:
        shiftout ddsdata,ddsclock,0,[ $07,$2B,$02,$0C ]   ;start value
        toggle ddsload
        pause 100
    
    ;Rotary Encoder Code################################################
    
    mainloop1:
    
        if EncoderRight=0 then                 'here is switch 2 of the rotary encoder
            counter=counter+1
            gosub up
            gosub dds
            gosub lcd
        endif
    
    'IF PB_1=0 THEN inc_step
    
        if EncoderLeft=0 then                 'here is switch 1 of the rotary encoder
            counter = counter-1
            gosub down
            gosub dds
            gosub lcd
        endif
    
        goto mainloop1
        
    lcd:
        lcdout $fe,$c0,dec5 counter
        while (EncoderLeft=0 or EncoderRight=0):pause 10:wend
        return
    
    
    inc_step:
        fcount=fcount+1
        if fcount=2 then fstep=100
        if fcount=1 then fstep=10
        fcount=1
        return
    
    dds:
        shiftout ddsdata,ddsclock,0,[counter]
        toggle ddsload
        return
    
    up:
    
        counter[0]=counter[0]+1
        if counter[0]>99 then
            counter[0]=0
            counter[1]=counter[1]+1
            if counter[1]>99 then
                counter[1]=0
                counter[2]=counter[2]+1
                if counter[2]>99 then
                    counter[2]=0
                    counter[3]=counter[3]+1
                    if counter[3]>99 then
                        counter[3]=0     ;reset to zero
                    endif
                endif
            endif
        endif
    return
    
    down:
    
        counter[0]=counter[0]-1
        if counter[0]<1 then
            counter[0]=0
            counter[1]=counter[1]-1
            if counter[1]<1 then
                counter[1]=99
                counter[2]=counter[2]-1
                if counter[2]<1 then
                    counter[2]=99
                    counter[3]=counter[3]-1
                    if counter[3]<1 then
                        counter[3]=99
                    endif
                endif
            endif
        endif
    return
    
    end
    Last edited by tasmod; - 6th January 2013 at 17:26.

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,518


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    Hi Rob,
    Yes, I remember the problem with your up/down counter not working properly....
    You're still having that Counter variable declared as a WORD but treating it as a 4 byte array in your UP/DOWN subrouitines. That's a crash waiting to happen since the up/down routines writing to the array will write to memory "outside" of the declared variable corrupting what ever is there. I thought we covered that...

    When setting the frequency you need to shift 40 bits (32bits tuning value + 8bits control) into the AD9850 and then pulse the Update Frequency pin. Looking at your code I see two main issues (appart from the Counter variable discussed above):
    A) In your DDS subroutine that shifts out the tuning value you're only shifting out 8 bits. Even if Counter is declared as a WORD (which it shouldn't be anyway) it will only shift 8 bits when written like that.
    B) You're not pulsing the Update Frequency pin, you're toggling it. The AD9850 updates the frequency on the rising edge of that signal so by toggling it like you're doing every second update would fail.

    /Henrik.

  4. #4
    Join Date
    Dec 2011
    Location
    IO93ok
    Posts
    190


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    Hmm yes. I posted the first version i worked as i was on the wrong pc.
    I did move on quite a bit.
    The toggle was changed later.
    The 40 bit control word has the 32 bit then next 8 bit as zero. So this can be set as a constant to be addaed at end of the word.

    Sorry if this is messy its from my mobile.

  5. #5
    Join Date
    Jun 2008
    Location
    Varese , Italy
    Posts
    326


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    Hi to all in this forum.
    I am using the magic number to control my AD9850 DDS and it worked very well for years.
    Now I am going to use the AD9912 DDS and I will like to calculate or to have the magic number to control it : the ref clock is 100 MHz internally multiplied by 10 so the real ref should be 1 GHz. I am using PBP 2.50 and longs.
    I understand that the 9912 has a 48 bit tuning word (FTW): what will be the limitations in this case ?
    Thanks in advance for any assistance .
    regards,
    Ambrogio
    iw2fvo

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,518


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    Hi,
    The AD9912 datasheet says: FTW = 2^48 * (fdds / 1GHz) where fdds is the desired frequency and 1GHz is the reference clock.
    As per the Wiki example for the AD9850, but with these numbers instead, you calculate 2^48/1GHz=281475 which is what I believe is the "magic number" you're referring to.

    So, FTW = fdds * 281475 which we can verify against the example in the datasheet:
    19,440,000 * 281475 = 5471874000000 which in reality would result in a frequency 1.6085Hz higher than ideal due to 2^48/1GHz not being exactly 281475. Does it matter? That's up to you.

    Now, LONGS are "only" 32 bits so what's the highest frequency possible? Well, 2^32/281475=15258.788Hz.

    Since the ** operator, when used with LONGs, results in an 48bit wide intermediate result I would guess we could use some trickery and retrieve all 48 bits directly but I don't have time to play around with that right now.

    /Henrik.

Similar Threads

  1. OSCTUNE Tuning range
    By MikeBZH in forum Schematics
    Replies: 3
    Last Post: - 8th June 2009, 06:54
  2. Need help in controlling DDS AD9850/51
    By vu2iia in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 7th March 2007, 13:40
  3. RF video reciever - digital tuning
    By RYTECH in forum Schematics
    Replies: 13
    Last Post: - 15th September 2006, 01:05
  4. calculate with date
    By Pedro Pinto in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 14th October 2005, 17:49
  5. iButton CRC-8 Calculate
    By Pesa in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 4th May 2005, 10:05

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts