Calculate tuning value for the AD9850 DDS.


Closed Thread
Results 1 to 17 of 17

Hybrid View

  1. #1
    Join Date
    May 2013
    Location
    australia
    Posts
    2,644


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    mike you may find this interesting
    www.picbasic.co.uk/forum/showthread.php?t=12433
    Warning I'm not a teacher

  2. #2
    Join Date
    Sep 2009
    Posts
    755


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    Mike,
    It can be almost copy/paste in PBP. I can try to sort details to work in PBP. But I don't understand what is calcFTW@c,@f,@n... Is it just variables declared in function?
    Can you explain?
    Last edited by pedja089; - 19th July 2018 at 09:14.

  3. #3
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    Yes, in XC8 that's how you would address the "local" variables (c, f, and n) using assembly language.

  4. #4
    Join Date
    Sep 2009
    Posts
    755


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    Here it is. It wasn't tested...
    Code:
    ftw var long ; unsigned long ftw;      // 32-bit Frequency Tuning Word
    f var long
    
    ;/************************************************************************
    ; *  Calculate AD9850 'FTW' (Frequency Tuning Word)      Mike McLaren    *
    ; *                                                                      *
    ; *  The 32-bit 'f' input is frequency*100 (0.01-Hz resolution) which    *
    ; *  allows scaling the DDS constant up to 32-bits.  Multiply the two    *
    ; *  32-bit terms and divide the 64-bit product by 2^32.  The 32-bit     *
    ; *  result is the frequency tuning word in the 'ftw' variable.          *
    ; *                                                                      *
    ; *  FTW * 2^32 = freq*100 * 2^32/RefClk*2^32/100                        *
    ; *  FTW * 2^32 = freq*100 * 1475739526                                  *
    ; *                                                                      *
    ; *  Fitting the frequency*100 value into a 32-bit variable makes our    *
    ; *  upper frequency limit ~42,949,672.95-Hz.                            *
    ; *                                                                      *
    ; *  --- target --  ---- ftw ----  --- actual --                         *
    ; *  42,949,672.00  1,475,739,493  42,949,672.00                         *
    ; *  37,000,000.00  1,271,310,320  37,000,000.01                         *
    ; *  25,000,000.00    858,993,459  24,999,999.99                         *
    ; *  10,000,000.00    343,597,384  10,000,000.01                         *
    ; *   1,000,000.00     34,359,738     999,999.99                         *
    ; *     125,000.00      4,294,967     124,999.99                         *
    ; *      10,000.00        343,597       9,999.99                         *
    ; *                                                                      *
    ; *  XC8 example                        (42 words, 665 cycles)           *
    ; ************************************************************************/
    
    calcFTW: ;   void calcFTW(unsigned long f)    // calculate AD9850 32-bit "FTW"
    ;   { long c = 1475739526;           // the "constant" term
    ;     unsigned char n = 32;          //
    	c VAR LONG : C=1475739526    
    	n VAR BYTE : n=32
    ; /*                                                                     *
    ;  *  multiply 32-bit freq*100 value by our 32-bit "constant" and use    *
    ;  *  the upper 32-bits ('ftw') of the 64-bit result                     *
    ;  *                                                                     */
    ASM
    mult32x32:            ; //
     BCF STATUS,C ; clrc                  ; //                                  |00
     btfss   _c+0,0 ; //                                  |00
     bra     nextbit       ; //                                  |00
     movf    _f+0,W ; // frequency lo                     |00
     addwf   _ftw+0,F      ; //                                  |00
     movf    _f+1,W ; // frequency hi                     |00
     addwfc  _ftw+1,F      ; //                                  |00
     movf    _f+2,W ; // frequency ul                     |00
     addwfc  _ftw+2,F      ; //                                  |00
     movf    _f+3,W ; // frequency uh                     |00
     addwfc  _ftw+3,F      ; //                                  |00
    nextbit:              ; //                                  |00
     RRCF      _ftw+3,F      ; //                                  |00
     RRCF      _ftw+2,F      ; //                                  |00
     RRCF      _ftw+1,F      ; //                                  |00
     RRCF      _ftw+0,F      ; //                                  |00
     RRCF      _c+3,F ; //                                  |00
     RRCF      _c+2,F ; //                                  |00
     RRCF      _c+1,F ; //                                  |00
     RRCF      _c+0,F ; //                                  |00
     decfsz  _n,F   ; // done? yes, skip, else            |00
     bra     mult32x32     ; //                                  |00
     movlw   0x80          ; // rounding...                      |00
     addwf   _c+3,W ; //  "                               |00
     movlw   0             ; //  "                               |00
     addwfc  _ftw+0,F      ; //  "                               |00
     addwfc  _ftw+1,F      ; //  "                               |00
     addwfc  _ftw+2,F      ; //  "                               |00
     addwfc  _ftw+3,F      ; //  "                               |00
     ENDASM;   }
    Return
    clrc and rrf are pseudo instruction from XC8. So I replaced it with real instruction.

    Usage:

    F=123 : Call calcFTW
    result is in ftw

  5. #5
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    Very interesting. Thank you. I'm not a PBP user so I had no idea inserting an assembly code function into a PBP program was that easy.

    I suspect you're coding for an 18F which has RRCF and RRNCF instructions where my example was for an "enhanced mid-range" 16F1823 device which has slightly different RRF, ASRF, and LSRF instructions. Hopefully, those 16F instructions are supported in PBP. Also, when using assembly language, careful attention to banking is required. I found XC8 assigned the 'ftw' variable in Bank 0 RAM and the other variables were assigned in the "common" 0x70..0x7F area.

    One might conclude that implementing an assembly language method in a program could save hundreds of words of program memory and thousands of instruction cycles processing time but it also requires careful attention to detail and environment.

    Hopefully, someone may be able to take advantage of a similar method in their PBP AD9850/AD9851 or Si5351 Digital VFO project.

    Cheerful regards, Mike, K8LH
    Last edited by Mike, K8LH; - 20th July 2018 at 16:53.

  6. #6
    Join Date
    Sep 2009
    Posts
    755


    Did you find this post helpful? Yes | No

    Default Re: Calculate tuning value for the AD9850 DDS.

    I use 18F for 99% of my project. So by default i go to 18F ASM. Also pbp for 16F doesn't support long variables(because of large overhead, but in my opinion it should).

    You are right, but I put all variables used in ASM into BANKA. So you dont need banking, at all. I forgot to do that here.
    Here is corrected version.
    Code:
    ftw var long ; unsigned long ftw;      // 32-bit Frequency Tuning Word
    f var long BANKA
    
    ;/************************************************************************
    ; *  Calculate AD9850 'FTW' (Frequency Tuning Word)      Mike McLaren    *
    ; *                                                                      *
    ; *  The 32-bit 'f' input is frequency*100 (0.01-Hz resolution) which    *
    ; *  allows scaling the DDS constant up to 32-bits.  Multiply the two    *
    ; *  32-bit terms and divide the 64-bit product by 2^32.  The 32-bit     *
    ; *  result is the frequency tuning word in the 'ftw' variable.          *
    ; *                                                                      *
    ; *  FTW * 2^32 = freq*100 * 2^32/RefClk*2^32/100                        *
    ; *  FTW * 2^32 = freq*100 * 1475739526                                  *
    ; *                                                                      *
    ; *  Fitting the frequency*100 value into a 32-bit variable makes our    *
    ; *  upper frequency limit ~42,949,672.95-Hz.                            *
    ; *                                                                      *
    ; *  --- target --  ---- ftw ----  --- actual --                         *
    ; *  42,949,672.00  1,475,739,493  42,949,672.00                         *
    ; *  37,000,000.00  1,271,310,320  37,000,000.01                         *
    ; *  25,000,000.00    858,993,459  24,999,999.99                         *
    ; *  10,000,000.00    343,597,384  10,000,000.01                         *
    ; *   1,000,000.00     34,359,738     999,999.99                         *
    ; *     125,000.00      4,294,967     124,999.99                         *
    ; *      10,000.00        343,597       9,999.99                         *
    ; *                                                                      *
    ; *  XC8 example                        (42 words, 665 cycles)           *
    ; ************************************************************************/
    
    calcFTW: ;   void calcFTW(unsigned long f)    // calculate AD9850 32-bit "FTW"
    ;   { long c = 1475739526;           // the "constant" term
    ;     unsigned char n = 32;          //
    	c VAR LONG BANKA : C=1475739526    
    	n VAR BYTE BANKA : n=32
    ; /*                                                                     *
    ;  *  multiply 32-bit freq*100 value by our 32-bit "constant" and use    *
    ;  *  the upper 32-bits ('ftw') of the 64-bit result                     *
    ;  *                                                                     */
    ASM
    mult32x32:            ; //
     BCF STATUS,C ; clrc                  ; //                                  |00
     btfss   _c+0,0 ; //                                  |00
     bra     nextbit       ; //                                  |00
     movf    _f+0,W ; // frequency lo                     |00
     addwf   _ftw+0,F      ; //                                  |00
     movf    _f+1,W ; // frequency hi                     |00
     addwfc  _ftw+1,F      ; //                                  |00
     movf    _f+2,W ; // frequency ul                     |00
     addwfc  _ftw+2,F      ; //                                  |00
     movf    _f+3,W ; // frequency uh                     |00
     addwfc  _ftw+3,F      ; //                                  |00
    nextbit:              ; //                                  |00
     RRCF      _ftw+3,F      ; //                                  |00
     RRCF      _ftw+2,F      ; //                                  |00
     RRCF      _ftw+1,F      ; //                                  |00
     RRCF      _ftw+0,F      ; //                                  |00
     RRCF      _c+3,F ; //                                  |00
     RRCF      _c+2,F ; //                                  |00
     RRCF      _c+1,F ; //                                  |00
     RRCF      _c+0,F ; //                                  |00
     decfsz  _n,F   ; // done? yes, skip, else            |00
     bra     mult32x32     ; //                                  |00
     movlw   0x80          ; // rounding...                      |00
     addwf   _c+3,W ; //  "                               |00
     movlw   0             ; //  "                               |00
     addwfc  _ftw+0,F      ; //  "                               |00
     addwfc  _ftw+1,F      ; //  "                               |00
     addwfc  _ftw+2,F      ; //  "                               |00
     addwfc  _ftw+3,F      ; //  "                               |00
     ENDASM;   }
    Return

Similar Threads

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