AD 9832 DDS

General discussion on mikroBasic.
Author
Message
Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

AD 9832 DDS

#1 Post by Copy'nPaste » 22 Jan 2007 21:27

Has anyone have a snippet of code for me on how to speak to this device?
I just can't seem to get my head around this concept :oops:
It has a serial interface, looks more like I2C to me, or SPI :?
"Copy'nPaste"

xor
Posts: 5465
Joined: 18 May 2005 00:59
Location: NYC
Contact:

#2 Post by xor » 23 Jan 2007 04:45

SPI will work. You only need to write using SCLK and SDO on the PIC. You will need a 3rd pin of the PIC to operate FSYNC, which informs the device that data is being clocked in. The serial timing diagrams are pretty good to show the order and sequence of highs/lows to get commands and data into the device.
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#3 Post by Copy'nPaste » 23 Jan 2007 13:39

Still no luck, and it looked so simple to use :oops:
"Copy'nPaste"

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#4 Post by Copy'nPaste » 23 Jan 2007 18:08

Don't ya just hate it when a manufacturer is unable to admit that someone else got it right, and they didn't?
So why didn't Analogue Devices just go with something like I2C?
It seems I'm going to need some bit banging waaay beyond my abilities to speak to this damn AD9832, if I use mikroElektronika Basic.
What might just work is the "Shift Out" function in Pic Basic Pro,
Why?, well the high/low transition relationship between the clock pulse and data byte seems to be important :-(, and in PBP I can change it, hint, hint :-)
I'd be really gratefull to be shown I'm wrong here, or that I've blown up the DDS somehow.
And I so wanted not ever to use PBP again :-(
"Copy'nPaste"

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#5 Post by Copy'nPaste » 24 Jan 2007 05:42

Ok, with Spi_Init_Advanced, I can change a few parameters, but now for the next question, how do I shift in six blocks of 16bit data?
"Copy'nPaste"

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#6 Post by Copy'nPaste » 24 Jan 2007 18:58

Nobody used these devices before?
I'm close to believing I might have blown uo the DDS, scoping out the data lines, the digital side seems in order.
The only pic code I find is assembler :evil:
"Copy'nPaste"

xor
Posts: 5465
Joined: 18 May 2005 00:59
Location: NYC
Contact:

#7 Post by xor » 25 Jan 2007 04:50

GroundPounder wrote:Ok, with Spi_Init_Advanced, I can change a few parameters, but now for the next question, how do I shift in six blocks of 16bit data?
I have no doubt that a PIC and mikroBasic can make it work....believe me.... :D

Are you sure about 6 x 16 bits? If so, you can do SPI_Write() 12 times in a row, or 12 x 8 bits. You can also set up a subroutine with data arguments to take care of this.

Code: Select all

dim data as word[6]

sub procedure DDS_Write(dim byref data0 as word[6])
dim temp as byte
   For temp = 0 to 5
      SPI_WRITE(Hi(data0[temp])
      SPI_WRITE(data0[temp])
   Next temp
end sub
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#8 Post by Copy'nPaste » 25 Jan 2007 07:10

Yep, it requires a 32 bit word for frequency, 8 bits at a time, and then 2 x 16 bit control words, 8 bits at a time.
Rather challenging for me at this point, but I'm getting something out at this point, just not what I thought I told it to do.
"Copy'nPaste"

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#9 Post by Copy'nPaste » 25 Jan 2007 09:31

So simple :oops:
For those that need a basic :) building block.....


Code: Select all

program meBasicAD9832ver1

        dim hmsb, hlsb, lmsb, llsb as byte

        sub procedure ddswrite
        TRISC = TRISC and $FD
            Spi_Init
            ClearBit(PORTC,1)             'Sync low enable write
            Spi_Write($F8)                'Setup AD9832 for writing
            Spi_Write($00)                'Just padding.......
            Spi_Write($33)                'Write High MSB into register $33
            Spi_Write(hmsb)
            Spi_Write($22)                'Write Low MSB into register $22
            Spi_Write(hlsb)
            Spi_Write($31)                'Write High LSB into register $31
            Spi_Write(lmsb)
            Spi_Write($20)                'Write Low LSB into register $20
            Spi_Write(llsb)
            Spi_Write($C0)                'Enable AD9832 for transmit
            Spi_Write($00)'               'Just padding.......
            SetBit(PORTC,1)               'Sync high disable write
            end sub
main:
'     while true
     
        hmsb = 4
        hlsb = 0
        lmsb = 0
        llsb = 0
        
        ddswrite

'        wend
  end.
"Copy'nPaste"

xor
Posts: 5465
Joined: 18 May 2005 00:59
Location: NYC
Contact:

#10 Post by xor » 25 Jan 2007 13:33

As a suggestion, you only need to do SPI_INIT once in your program, in the beginning at startup would be fine.
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#11 Post by Copy'nPaste » 25 Jan 2007 14:54

Warren, don't you ever sleep? :)
"Copy'nPaste"

xor
Posts: 5465
Joined: 18 May 2005 00:59
Location: NYC
Contact:

#12 Post by xor » 25 Jan 2007 15:05

Only when I'm not awake... :shock:
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#13 Post by Copy'nPaste » 01 Feb 2007 18:24

Haven't done much on this project lately, just confirmed I'm an idiot :(
SPI is WAY faster than I2C.
Sorry Analogue Devices :oops:

Anyone else played lately ?
"Copy'nPaste"

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#14 Post by Copy'nPaste » 05 Mar 2007 20:04

Thanks to Sorcerer, and Xor, in alphabetical order :) ,
I have made this project work :D
Crude, but it works.
Thanks guys!
"Copy'nPaste"

Copy'nPaste
Posts: 573
Joined: 25 Apr 2006 15:39
Location: Cape Town, South Africa

#15 Post by Copy'nPaste » 13 Mar 2007 20:30

Refined this a bit, thanks a mil to those, knowingly and unknowingly, that pointed me in the right direction.
If this does help, please drop me a note?

Code: Select all

' A simple program to enable KeyPad control of an AD9832/9835 DDS
' 16X2 Lcd on Port B, DDS on Port C, KeyPad on Port D
' Default startup values in eeprom, 1 MHz out, for 24 MHz Clock
' Standard mikroElektronika connections as per EasyPic3 Board apply,
' using Pic 16F877A.
' RA0 switches display to frequency entry, RA1 changes clock value
' Both pins are normally pulled high, switches when pulled low
' KeyPad "*" deletes last keypress only, "#" writes new values to eeprom
' DDS PSEL0, PSEL1, FSELECT GROUNDED
' Hardware SPI function of Pic used
'
' MANY thanks to Sorcerer and Xor, who freely gives of their code....

program meBasicAD9832ver1
include "Print_Dec_16"      ' Xor's lcd print utility

        symbol delay50  = Delay_ms(50)
        symbol delay500 = Delay_ms(500)
        
        Dim frequency, xtal, cfreq, KeyInput,KeyInputOld as longint
        dim Key,Key1 as byte
        dim myvar as string[11]
        
        'Map 4*4 KeyPad to ascii
        const KeyPad as byte[16] = (49, 50, 51, 65,
                                    52, 53, 54, 66,
                                    55, 56, 57, 67,
                                    42, 48, 35, 68)
sub procedure Welcome  ' Welcome Message
    dim I as byte
    lcd_cmd(LCD_CURSOR_OFF)
    lcd_cmd(lcd_clear)
    lcd_out(1, 4, "gkSolutions")
    lcd_out(2,2,"DDS Synthesizer")
    For I = 0 to 3
    Delay500
    Next I
    lcd_cmd(lcd_clear)         ' Message Ends
end sub

sub function eread01(dim eeprom_addr, offset as byte) as longint
'    eeprom_addr = 0                'Is this nessary?
    For offset = 0 to 3
    FSR = @ frequency + offset
    INDF = EEPROM_READ(eeprom_addr + offset)
    Next offset
    result = frequency
    delay50
end sub

sub function eread02(dim eeprom_addr, offset as byte) as longint
'    eeprom_addr = 16
    For offset = 0 to 3
    FSR = @ xtal + offset
    INDF = EEPROM_READ(eeprom_addr + offset)
    Next offset
    result = xtal
    delay50
end sub

sub procedure lcdwrite01(dim yy as longint)
    Lcd_Cmd(LCD_CLEAR)       ' Clear display
    Lcd_Cmd(LCD_CURSOR_OFF)  ' Cursor off
'    print_dec(yy*16,"###.######",RJZ,myvar)         ' For FM Version
    print_dec(yy,"##.######",RJZ,myvar)            ' For Straight Version
     Lcd_Out(1, 4, "gkSolutions")
    Lcd_Out(2,3,myvar)
    Lcd_Out(2,13,"MHz")
    delay500
end sub

sub function CalcFreq(dim f, x as longint) as longint
    dim g as float
    g = ( f / x ) * $7FFFFFFF
    result = longint(g) * 2
    delay50
end sub

'sub procedure ddswrite(dim f as longint)     ' Hardware SPI, I HAD to play !
'    eread01(0, 0)
'    delay50
'    eread02(16, 0)
'    delay50
'    cfreq = CalcFreq(frequency, xtal)
'    delay50
'    TRISC = TRISC and $FD
'    ClearBit(PORTC,1)             'Sync low enable write
'    Spi_Write($F8)                'Setup AD9832 for writing
'    Spi_Write($00)                'Just padding.......
'    Spi_Write($33)                'Write High MSB into register $33
'    Spi_Write(highest(f))
'    Spi_Write($22)                'Write Low MSB into register $22
'    Spi_Write(higher(f))
'    Spi_Write($31)                'Write High LSB into register $31
'    Spi_Write(hi(f))
'    Spi_Write($20)                'Write Low LSB into register $20
'    Spi_Write(lo(f))
'    Spi_Write($C0)                'Enable AD9832 for transmit
'    Spi_Write($00)                'Just padding.......
'    SetBit(PORTC,1)               'Sync high disable write
'    delay50
'    lcdwrite01(frequency)
'    delay50
'end sub

sub procedure ddswrite(dim f as longint)      ' Soft SPI, ditto :-)
    eread01(0, 0)
    delay50
    eread02(16, 0)
    delay50
    cfreq = CalcFreq(frequency, xtal)
    delay50
    TRISC = TRISC and $FD
    ClearBit(PORTC,1)                  'Sync low enable write
    Soft_Spi_Write($F8)                'Setup AD9832 for writing
    Soft_Spi_Write($00)                'Just padding.......
    Soft_Spi_Write($33)                'Write High MSB into register $33
    Soft_Spi_Write(highest(f))
    Soft_Spi_Write($22)                'Write Low MSB into register $22
    Soft_Spi_Write(higher(f))
    Soft_Spi_Write($31)                'Write High LSB into register $31
    Soft_Spi_Write(hi(f))
    Soft_Spi_Write($20)                'Write Low LSB into register $20
    Soft_Spi_Write(lo(f))
    Soft_Spi_Write($C0)                'Enable AD9832 for transmit
    Soft_Spi_Write($00)                'Just padding.......
    SetBit(PORTC,1)                    'Sync high disable write
    delay50
    lcdwrite01(frequency)
    delay50
end sub

sub procedure ewrite(dim xx as longint)
    Eeprom_Write(0, lo(xx))
    delay50
    Eeprom_Write(1, hi(xx))
    delay50
    Eeprom_Write(2, higher(xx))
    delay50
    Eeprom_Write(3, highest(xx))
    delay50
end sub

sub procedure ewrite2(dim xx as longint)
    Eeprom_Write(16, lo(xx))
    delay50
    Eeprom_Write(17, hi(xx))
    delay50
    Eeprom_Write(18, higher(xx))
    delay50
    Eeprom_Write(19, highest(xx))
    delay50
end sub

sub Procedure Need_Input01       'Original routine from Sorcerer
      Lcd_cmd(lcd_clear)
      Lcd_Out(1, 4, "Freq in MHz")
      Lcd_Out(2, 3, "Enter with #")
      Key1 = 0
      KeyInput=0
      KeyInputOld=0
    While Key1<>35                           ' Exit on #
      Key=0
      while Key = 0
      Key = Keypad_Released
      Wend
      Key1=KeyPad[Key-1]
      If Key1=42 Then                        '* = delete (last input only!)
      KeyInput=KeyInputOld
      End If
      If (Key1 > 47) and (Key1 < 58) then    '0-9 are added in, anything else ignored
      KeyInputOld = KeyInput
      KeyInput = KeyInput * 10
      KeyInput = KeyInput + Key1 - 48
      End If
'      print_dec(keyinput,"###.######",RJZ,myvar)    ' For FM Version
      print_dec(keyinput,"##.######",RJZ,myvar)    ' For Straight Version
      Lcd_cmd(LCD_CURSOR_OFF)
      Lcd_Out(2, 1,"                ")
      Lcd_Out(2, 4, myvar)
      delay50
    Wend
'        KeyInput = KeyInput div 16              ' Only For FM Version
        ewrite(Keyinput)
        delay50
        ddswrite(cfreq)          ' Can't explain why it needs TWO writes ?
        delay50
        ddswrite(cfreq)
        delay50
end sub

sub Procedure Need_Input02                       ' Fine Tune xtal Osc
      Lcd_cmd(lcd_clear)
      Lcd_Out(1, 1, "Xtal Freq in MHz")
      Lcd_Out(2, 3, "Enter with #")
      Key1 = 0
      KeyInput=0
      KeyInputOld=0
    While Key1<>35                           ' Exit on #
      Key=0
      while Key = 0
      Key = Keypad_Released
      Wend
      Key1=KeyPad[Key-1]
      If Key1=42 Then                        '* = delete (last input only!)
      KeyInput=KeyInputOld
      End If
      If (Key1 > 47) and (Key1 < 58) then    '0-9 are added in, anything else ignored
      KeyInputOld = KeyInput
      KeyInput = KeyInput * 10
      KeyInput = KeyInput + Key1 - 48
      End If
      print_dec(keyinput,"##.######",RJZ,myvar)
      Lcd_cmd(LCD_CURSOR_OFF)
      Lcd_Out(2, 1,"                ")         ' Cleans Line for next display
      Lcd_Out(2, 4, myvar)
      delay50
    Wend
        ewrite2(Keyinput)
        delay50
        ddswrite(Cfreq)             ' Can't explain why it needs TWO writes ?
        delay50
        ddswrite(Cfreq)
        delay50
end sub

main:
       ADCON1 = 7
       trisa = %11111111
'       Spi_Init                            ' Required for Hardware SPI
       Soft_Spi_Config(PortC,4, 5, 3)       ' Required for Soft_SPI
       Lcd_Init(PORTB)
       Keypad_Init(PORTD)
       Welcome
       ddswrite (cfreq)
       delay50
       ddswrite(cfreq)
       delay50
eloop:
       if porta.0 = 0 then
       Need_Input01
       end if
       if porta.1 = 0 then
       Need_Input02
       end if
goto eloop
end.
"Copy'nPaste"

Post Reply

Return to “mikroBasic General”