AD 9832 DDS

General discussion on mikroBasic.
Author
Message
neomodo
Posts: 28
Joined: 06 May 2007 20:07

What is this project do?

#16 Post by neomodo » 13 May 2007 20:57

What is a DS9832 and what is the porpouse of this code?

Freq Generator? FM reciver?

Regards
Neomodo

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

#17 Post by Copy'nPaste » 14 May 2007 06:02

Hi Neomodo.
DDS stands for Direct Digital Synthesiser.
In certain applications it can replace a PLL oscillator.
The code is to make it work!
"Copy'nPaste"

neomodo
Posts: 28
Joined: 06 May 2007 20:07

Connection diagram?

#18 Post by neomodo » 14 May 2007 19:03

I will be usefull for rest users to get the conection diagram to this device.

Regards.
Neomodo

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

#19 Post by xor » 14 May 2007 20:34

The datasheet doesn't have one?
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]

neomodo
Posts: 28
Joined: 06 May 2007 20:07

No.

#20 Post by neomodo » 14 May 2007 20:43

The datasheet have the schematic of a evaluation board.

I dont know what he is doing when he sets to low pin 1 of PortC.

I dont know what is FSync Pin and if it's connected to Pic.

I'm trying to make this device works :(

neomodo
Posts: 28
Joined: 06 May 2007 20:07

Finally worked.

#21 Post by neomodo » 14 May 2007 23:44

Hi again.

I found the problem.

If anybody is interested, I have schematic. MP me.

This IC is very usefull. For example, we can bulid a Digitally controled sine wave generator. :D

This IC works fine from 0 to 5 Mhz. At output we get a sine wave, 1v.p.p. and with 1 v. offset from gnd.

Thanks for the info.

Regards.
Neomodo

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

#22 Post by Copy'nPaste » 15 May 2007 06:18

"Copy'nPaste"

neomodo
Posts: 28
Joined: 06 May 2007 20:07

#23 Post by neomodo » 15 May 2007 23:36

Copy'nPaste wrote:neomodo, try this link?

http://f1.grp.yahoofs.com/v1/UD5JRgefiS ... 070430.zip
Link don't work :(

But finally I make the IC runs correctly. I have problems with IC Power supply.

I'm going to make an amplifier to make a sine generator for PIC's. When done, I will post SCH and code for it, regarding you and Xor your help.

Thanks again !!!

Regards
Neomodo

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

#24 Post by Copy'nPaste » 26 Feb 2008 06:20

Oops, it seems I never did post the code for the AD9851 DDS, here goes.... :oops:

Code: Select all

program meBasicAD9851_DDS01
' Author Copy'nPaste, kuhng@vodamail.co.za
' A simple program to enable KeyPad control of an AD9851 DDS
' DDS circuit from www.amqrp.org/kits/dds60
' Generate any frequency up to about 80 MHz, 1Hz steps ! (Specs 60 MHz)
' 16X2 Lcd on Port D, DDS on Port C, KeyPad on Port B
' Default startup values in eeprom, 1 MHz out, for 180 MHz Clock
' Standard Pic 16F877A, EasyPic4 connections apply
' 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
' Port B KeyPad, pins pulled LOW !
' MANY thanks to Sorcerer, Xor, Florin Medrea and LvZ, who freely gives
' of their code and time ....

        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, byte_s as byte
        dim myvar as string[11]
        
        const KeyPad as byte[16] = (49, 50, 51, 65,  'Map 4*4 KeyPad to ascii
                                    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,4,"AD-9851 DDS")
    For I = 0 to 3
    Delay500
    Next I
    lcd_cmd(lcd_clear)   ' Message Ends
end sub

' Read frequency value stored in eeprom
sub function eread01(dim eeprom_addr, offset as byte) as longint
    For offset = 0 to 3
    FSR = @ frequency + offset
    INDF = EEPROM_READ(eeprom_addr + offset)
    Next offset
    result = frequency
    delay50
end sub

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

' Write new frequency to LCD
sub procedure lcdwrite01(dim yy as longint)
    Lcd_Cmd(LCD_CLEAR)       ' Clear display
    Lcd_Cmd(LCD_CURSOR_OFF)  ' Cursor off
    print_dec(yy,"##.######",RJZ,myvar)
    Lcd_Out(1, 4, "gkSolutions")
    Lcd_Out(2,3,myvar)
    Lcd_Out(2,13,"MHz")
    delay500
end sub

' LvZ maths, calculate divisor value
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

' Florin Medrea's bit swap routine, forces SPI to TX LSB first
sub function swap_bits(dim data_b as byte) as byte
dim i,j as byte
  result = 0
  i = 0
  j = 7
  while i < 8
    if TestBit(data_b,i) = 1 then SetBit(result,j) end if
    inc(i)
    dec(j)
  wend
end sub

' Reset and fill DDS data register with zero values
sub procedure ddsclear
       ClearBit(PORTC,1)
       Soft_Spi_Write($00)
       Soft_Spi_Write($00)
       Soft_Spi_Write($00)
       Soft_Spi_Write($00)
       Soft_Spi_Write($00)
       SetBit(PortC,1)
end sub

' Write divisor and config values to DDS
sub procedure ddswrite(dim f as longint)      ' Soft SPI
    eread01(0, 0)                             ' Read eeprom for Freq
    delay50
    eread02(16, 0)                            ' Read eeprom for Clock
    delay50
    cfreq = CalcFreq(frequency, xtal)         ' Calculate divisor
    delay50
    TRISC = TRISC and $FD
    ClearBit(PORTC,1)                         'Sync low enable write
    byte_s = swap_bits(lo(f))                 ' Swap over and write LSB
    Soft_Spi_Write(byte_s)
    byte_s = swap_bits(hi(f))                 ' Swap over and write next byte
    Soft_Spi_Write(byte_s)
    byte_s = swap_bits(higher(f))             ' Swap over and write next byte
    Soft_Spi_Write(byte_s)
    byte_s = swap_bits(highest(f))            ' Swap over and write next byte
    Soft_Spi_Write(byte_s)
    byte_s = swap_bits($01)                   ' Swap over and write config byte
    Soft_Spi_Write(byte_s)
    SetBit(PORTC,1)                           ' Sync high disable write
    delay50
    lcdwrite01(frequency)                     ' Write new frequency to LCD
    delay50
end sub

' Write Freq value to eeprom
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

' Write Clock value to eeprom
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

'Original routine from Sorcerer, read Freq from keypad
sub Procedure Frequency_Input
      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)
      Lcd_cmd(LCD_CURSOR_OFF)
      Lcd_Out(2, 1,"                ")
      Lcd_Out(2, 4, myvar)
      delay50
    Wend
        ewrite(Keyinput)                     ' Store frequency value in eeprom
        delay50
        ddswrite(cfreq)                      ' Two writes to set registers ???
        ddswrite(cfreq)
end sub

' Original routine from Sorcerer, read Clock from KeyPad
' Adjust for different Clock, or Fine Tune
sub Procedure Clock_Input
      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)                   ' Store clock value in eeprom
        delay50
        ddswrite(cfreq)                     ' Two writes to set registers ???
        ddswrite(cfreq)
end sub

main:
       ADCON1 = 7
       trisa = %11111111
       trisc = 0
       Soft_Spi_Config(PortC,4, 2, 3)       ' Required for Soft_SPI
       Lcd_Init(PORTD)                      ' Init LCD on port D
       Keypad_Init(PORTB)                   ' Init KeyPad port B
       Welcome                              ' Display Welcome message
       ddsclear                             ' Write zero values to DDS buffer
       ddswrite(cfreq)                      ' Read stored values, write to DDS
       ddswrite(cfreq)                      ' Two writes to set registers ????
eloop:
       if porta.0 = 0 then                  ' Key for frequency change
       Frequency_Input                      ' Jump to frequency keypad routine
       end if
       if porta.1 = 0 then                  ' Key for Clock change
       Clock_Input                          ' Jump to clock keypad routine
       end if
goto eloop
end.
"Copy'nPaste"

oliverb
Posts: 570
Joined: 24 May 2007 15:09

Re: AD 9832 DDS

#25 Post by oliverb » 15 Feb 2011 22:03

Firstly I should apologise for digging up an old thread, but I've just obtained and built one of the DDS-60 kits and I was keen to find some sample code, that hopefully would just run as-is.

First I tried updating the program into MB-Pro, but I cannot get the Print_Dec_16 routine to work properly, indications are it loops infinitely though I'm not certain.

Then I tried MB 7.0.0.2 and it seems to compile and run but I'm having problems with the numeric keypad code, it looks as if it isn't scanning but it behaves the same in both versions, so I may simply be misunderstanding its function.

Actually the keypad issue is probably just that for the MB key lib I need pull DOWN resistors, going against all PIC traditions.

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

Re: AD 9832 DDS

#26 Post by Copy'nPaste » 16 Feb 2011 09:48

Try this :-)
I'm a bit rusty, but the keypad routine definately works.

Code: Select all

module Print_Dec_16_Pro
'***********************************************************************************************
'* *
'* PRINT_DEC() by Warren Schroeder - September 23, 2006
'* Compiled with mikroBASIC 5.0.0.1 and tested with 16F876A
'* *
'* PRINT_DEC is a routine that accepts any unsigned number up to 32 bits and converts
'* it to a string of decimal numbers which can also include a user-inserted decimal point.
'* The maximum size of the string is 11 characters: 10 decimal integers + a decimal point.
'* *
'* The result string can be formatted (including an optional decimal point)
'* based on a #'s template and the following justification codes:
'* RJ = Right-Justified with Leading Blank Spaces
'* RJZ = Right-Justified with Leading Zeroes
'* *
'* This is the prototype of the function:
'* Print_Dec(_number as longint,_format as string[11],_justify as byte,_target as string[11])
'* *
'* Examples: *
'* print_dec(123456789, "#####.#####", RJ, mystr)
'* Printed Result in mystr: " 1234.56789" *
'* print_dec(mynumber, "#.######", RJZ, mystr) where mynumber = 64321
'* Printed Result in mystr: "0.064321"
'*
'* 14 Nov 2009
'*   Modified to Compile for the mikroElectronika PRO Basic with the assistance of Durango and Janni
'*   Janni. Compiled with Basic PRO v3.2 and verified on EasyPIC4 board using 16F88.
'***********************************************************************************************

Const RJ as byte = 1
Const RJZ as byte = 2
dim dcnt as byte
dim bcnt as byte
dim FARG_print_dec as byte   ' ***Added this ***

'*******************************************************************8
' Need to place this here above implements

sub procedure Print_Dec(dim _number as longint,
dim byref _format as string[11],
dim _justify as byte,
dim byref _target as string[11])

'********************************************************************

implements

sub procedure Print_Dec(dim _number as longint,
dim byref _format as string[11],
dim _justify as byte,
dim byref _target as string[11])

dim tmp0, tmp1, flen, start, ascii as byte

dim doff as short            ' ***Dim'ed doff as a short because it is
                             ' given a value of -1 a few lines down. ***

tmp0 = 0
flen = 0
doff = -1

FSR = byte(@_target)       ' location for final string
While tmp0 <> 11
      INDF = 0
      inc(tmp0)
      inc(FSR)
Wend

FSR = byte(@_format)        ' location of formatting scheme'
While INDF <> 0
      If INDF = 46 Then doff = flen End If ' get decimal position
      inc(FSR) ' move to next memory position
      inc(flen)
Wend

bcnt = 32
asm
   b32:
end asm
dcnt = 10
FSR = byte(@_target + 10)
asm
   rlf FARG_Print_Dec__number,F      ; Changes here by Janni
    rlf FARG_Print_Dec__number+1,F
    rlf FARG_Print_Dec__number+2,F
    rlf FARG_Print_Dec__number+3,F

   inloop:
   rlf INDF,1
       movlw 246
       addwf INDF,0
       btfsc STATUS,0
       'movwf INDF,1          ' ***Changed this line ***
       movwf INDF             ' ***to this line from above***
       decf FSR, 1
       decfsz _dcnt,1
       goto inloop
       decfsz _bcnt,1
       goto b32
end asm
start = 12 - flen
tmp1 = 0
FSR = byte(@_target)
While tmp1 < flen
      ascii = 48
      If tmp1 = doff Then
         INDF = 46
         dec(start)
      Else
          FSR = FSR + start
          tmp0 = INDF
          If tmp0 = 0 Then
             If _justify = RJ Then
                If tmp1 < doff Then ascii = 32 End If
             End If
          End If
          FSR = FSR - start
       INDF = tmp0 + ascii
    End If
inc(FSR)
inc(tmp1)
Wend
INDF = 0
end sub
end.
"Copy'nPaste"

oliverb
Posts: 570
Joined: 24 May 2007 15:09

Re: AD 9832 DDS

#27 Post by oliverb » 16 Feb 2011 16:01

Thanks, that's probably it. Figured the name change OK. I'd tried making everything short, I don't think that worked. I tried setting doff to $ff instead of -1 but that didn't work.

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

Re: AD 9832 DDS

#28 Post by Copy'nPaste » 16 Feb 2011 17:51

Mmm, what doesn't work?
This is code that does work on my EP 6

Code: Select all

' **********************************************************************************
' * Project name: COG_PrintDec16Pro
' * Demo of COG use and XOR's PrintDec Routine
' * Read value of ADC 0, 1 and scale to read 0 to 150
' * MCU: PIC16F887
' * Dev.Board:       EasyPIC6
' * Oscillator:      HS, 8.0000 MHz
' * Ext. Modules:    Print_Dec_16-pro
' * SW:              mikroBasic PRO for PIC
' * NOTES:
' * Turn on Port Expander switches SW6.1, SW6.2, SW6.3, SW6.4 and SW6.5.
' * Turn on COG LCD 2x16 switches SW10.1, SW10.2, SW10.3, SW10.4, SW10.5 and SW10.6.
' ************************************************************************************
' * PRINT_DEC() by Warren Schroeder - September 23, 2006
' * Compiled with mikroBASIC 5.0.0.1 and tested with 16F876A
' * PRINT_DEC is a routine that accepts any unsigned number up to 32 bits and converts
' * it to a string of decimal numbers which can also include a user-inserted decimal point.
' * The maximum size of the string is 11 characters: 10 decimal integers + a decimal point.
' * The result string can be formatted (including an optional decimal point)
' * based on a #'s template and the following justification codes:
' * RJ = Right-Justified with Leading Blank Spaces
' * RJZ = Right-Justified with Leading Zeroes
' * This is the prototype of the function:
' * Print_Dec(_number as longint,_format as string[11],_justify as byte,_target as string[11])
' ********************************************************************************************
' * Examples:
' * print_dec(123456789, "#####.#####", RJ, mystr)
' * Printed Result in mystr: " 1234.56789" *
' * print_dec(mynumber, "#.######", RJZ, mystr) where mynumber = 64321
' * Printed Result in mystr: "0.064321"
' ********************************************************************************************
' * Modified to Compile for the mikroElectronika PRO Basic with the assistance of Durango
' * and Janni. Compiled with Basic PRO v3.2 and verified on EasyPIC6 board using 16F887.
' ********************************************************************************************

program COG_PrintDec16Pro
include Print_Dec_16_Pro

dim text as string[16]
dim adcval as word
dim Temp1 as float
dim Temp2 as float
dim var01 as string[11]
dim var02 as string[11]


' Port Expander module connections
dim
SPExpanderCS as sbit at RA2_bit
SPExpanderRST as sbit at RA3_bit
SPExpanderCS_Direction as sbit at TRISA2_bit
SPExpanderRST_Direction as sbit at TRISA3_bit
' End Port Expander module connections


sub procedure ReadTemp1()
  CM1CON0 = 0            ' Disable comparators
  CM2CON0 = 0
  ANSEL  = 0x00           ' Configure AN0 pin as analog
  TRISA  = 0xFF           ' PORTA is input
  ANSELH = 0              ' Configure other AN pins as digital I/O
  adcval = ADC_Read(0)    ' get ADC value from 1st channel
  delay_us (500)
  Temp1 = adcval * 15000 / 1023
  print_dec(temp1,"###.##",RJZ,var01)

end sub

sub procedure ReadTemp2()
  CM1CON0 = 0            ' Disable comparators
  CM2CON0 = 0
  ANSEL  = 0x00           ' Configure AN0 pin as analog
'  ansel =  0x01          ' Configure AN1 pin as analog
  TRISA  = 0xFF           ' PORTA is input
  ANSELH = 0              ' Configure other AN pins as digital I/O
  adcval = ADC_Read(1)    ' get ADC value from 2nd channel
  delay_us (500)
  Temp2 = adcval * 15000 / 1023
  print_dec(temp2,"###.##",RJZ,var02)
end sub

sub procedure DisplayVal
  ANSEL  = 0                          ' Configure AN pins as digital
  ANSELH = 0
  C1ON_bit = 0                        ' Disable comparators
  C2ON_bit = 0
  SPI1_Init()                         ' Initialize SPI module used with PortExpander
  SPI_Lcd_Config(0)                   ' Initialize Lcd over SPI interface
  SPI_Lcd_Cmd(_LCD_CLEAR)             ' Clear display
  SPI_Lcd_Cmd(_LCD_CURSOR_OFF)        ' Turn cursor off
  SPI_Lcd_Out(1,1, "Temp1")           ' Print text to Lcd, 1st row, 1st column

  SPI_Lcd_Out(2,1, "Temp2")           ' Print text to Lcd, 2nd row, 1st column
  spi_lcd_out(1,7, var01)             ' Write variable 1 to COG
      if  Temp1 <  9999 then SPI_Lcd_Out(1,7, " ") ' Blanks out leading 0
      end if
  spi_lcd_out(2,7, var02)             ' Write variable 2 to COG
      if  Temp2 <  9999 then SPI_Lcd_Out(2,7, " ") ' Blanks out leading 0
      end if
end sub

main:
while true
' Call Subroutines
  ReadTemp1()
  ReadTemp2()
  DisplayVal()
  Delay_ms(2000)
wend

end.
"Copy'nPaste"

oliverb
Posts: 570
Joined: 24 May 2007 15:09

Re: AD 9832 DDS

#29 Post by oliverb » 16 Feb 2011 20:31

Well it doesn't matter as I still have a MB V7 install so I can just use the version as posted. Updating to Pro would have been a bonus.

On pro it seems to "crash" when its time to display a number, I think the FSR-fu in the optimised routine may be causing memory trashing. If I put an "exit" at the beginning of that code it runs.

Once I can verify that the DDS works and demo it I'll try patching it into my own application.

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

Re: AD 9832 DDS

#30 Post by Copy'nPaste » 16 Feb 2011 21:17

Sorry I can't be of more help :(
The modified print code from xor does work, I just haven't had any need to re write the complete program to Pro.
Damm, do I miss Warren, not only for his wit, and code, but also for his pointed "jab in the ribs", to make you look at the bigger picture, but always with a very subtle hint, where to look :(
I miss you Warren, really :(
"Copy'nPaste"

Post Reply

Return to “mikroBasic General”