AD9833 problem

Please check the frequently asked questions before posting to the forum.
Post Reply
Author
Message
taherian
Posts: 1
Joined: 01 Jun 2010 11:04

AD9833 problem

#1 Post by taherian » 01 Jun 2010 11:12

Hi all,

I am using AD9833 (DDS) and I have designed my own board similar to the developer board schematic which is available at the end of datasheet.
I am using ATMEGA32L as an interface microprocessor for SPI communication. I have sent the below sequence of data to the DDS. Reset words act correctly. But by choosing sinusoidal signal for the output, the resulted waveform at the output is something like Amplitude Modulation (AM). Its envelope is something near to the wave form which we needed.

2100 6DC6 40D1 8000 8000 C200 E000 2000

Can anyone help me in this problem?
Thanks.

Aleksander83
Posts: 1
Joined: 09 Jul 2010 06:47

Re: AD9833 problem

#2 Post by Aleksander83 » 09 Jul 2010 08:54

I found similar, when I set the frequency to 250kHz, I found the is AM modulated signal with frequency 60Hz. Do you notice the same?

amfortas
Posts: 212
Joined: 18 Feb 2010 18:10

Re: AD9833 problem

#3 Post by amfortas » 14 Feb 2011 16:19

THE AD9833 IS EASY TO CONTROL UNDER mikroPascalPro



Fig. 1. Simple AD9833 TEST JIG.

The Analog Devices DDS AD9833 can be controlled from a PIC16F877 with great ease using the library SPI routines.

The fundamental task is to send instructions from the PIC to the AD8933 registers wrapped up in 16 bit containers with the MS bits 15 and 14 carrying the code which informs the AD9833 where the data is to end up. With the PIC16F877 hardware provision of SPI output the compiler overhead is absolutely minimal and where speed is required, the mikroPascal compiler is the perfect tool for easy and fast program development.

Fig.1. shows an AD9833 and 20mHz clock assembled to test out the PIC SPI operation. RC1 has been chosen to serve as the CHIP_SELECT pin which provides the FSYNC function. This is an important output since the concatenation of two 8 bit instructions into the desired 16 bit instruction is accomplished by keeping this line LOW until both bytes have been sent. The bit stream is entirely controlled by the PIC SPI CLK. The SPI is in master mode and there is no return data to watch out for. The 8 bit stream of clock pulses flows from RC3 and the data flows from RC5. The AD9833 simply does what it is told.

A simple mikroPascalPro routine is listed below. The program sets up a 30kHz sine wave signal and then ramps it up over a range of about 4kHz. The example handles the packaging of the FREQREG 32 bit LSB-MSB SEND as two 14 bits of data with bits 15 and 14 set at 01 to cause the data to be sent to the 28bit FREQREG.

EXAMPLE PROGRAM

Code: Select all

{    *16F877 processor with 20MHz clock. AD9833 chip clock 20MHz
Evaluation jig for AMCAL Project assembled on  Reynolds FLASHLAB 77 prototype
board.

The AD9833 is a digitally programmable oscillator which together with a 20mHz clock can provide accurate frequency sine waves under instruction from a PIC 16F877 processor connected over an SPI link.

This program simply enables the AD9833 to be functionally assessed..
}

program Cow_Door;  Org $08;                //ORG  $08  re-locates the
                                           //prog for use with a boot loader

var Chip_Select:sbit at RC1_bit;           //RC1 is set as the FSync SPI output
    Chip_Select_Direction:sbit at TRISC1_bit;
    Value1,Value2,Value3,Value4:byte;
    fdata,incrementer:dword;
    i:word;
    
Procedure  Pack_AD9833(fdata:dWord);
{fdata contains calculated FreqReg as 28 bit data without destination
codes. It is required to set bits 15 and 14 to 01 and bits 31 and 30
to 01. The result can conveniently be the four Value1 to Value 4 bytes
which will be sent to the AD9833.}

begin
     Value1:=fdata;         //pick off LS byte
     Value2:=fdata shr 8;   //pick off next byte where bits 7 and 6 need
                            // to be set as 01;
     Value2:= Value2 AND $3F;  //clear bits 7 and 6
     Value2:= Value2 OR  $40;  //set bits 7 and 6 to 0 and 1 respectively.
     Value3:= fdata shr 14;    //pick off next byte beyond bit 13
     {Value4:=$40;}            //MSB never used in this application so fixed.
     Value4:= fdata shr 22;    //pick off MSB byte
     Value4:=Value4 AND $3F;   //Clear bits 7 and 7;
     Value4:=Value4 OR $40;    //Set bits 7 and 6 to 01;
end;
Procedure AD9833_SEND(Value1,Value2:byte);
{This procedure sends the 16 bit word required by the AD9833 data register
as two 8 bit bytes ordered MSB first(Value1) LSB second(Value2). The MSB byte
carries the address two bits. i.e. Value1 = (01XXXXXX) Value2 = (XXXXXXXX)  to
load the FREQ0 register. }

begin
     Chip_Select:=0;
     SPI1_Write(Value1);
     SPI1_Write(Value2);
     Chip_Select:=1;
end;

Procedure Ramp_Freq(Value1,Value2,Value3,Value4:byte);

begin
     Delay_uS(40);
     AD9833_SEND(Value2,Value1);   //Send LSB
     Delay_uS(40);
     AD9833_SEND(Value4,Value3);   //Send MSB
end;

Procedure InitMain();
{Initialisation  first sets up RSC1 as the Chip_Select output. Then the
SPI1_Init_Advanced library procedure sets the SPI to match the AD9833
SPI specifications. Finally the AD9833 chip is reset and set up to
receive two consecutive 16 bit instructions into the Freq0 register.The
$21 $00 srquence also selects a sine wave output.}
begin
     Chip_Select:=1;
     Chip_Select_Direction:=0;
     SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4,_SPI_DATA_SAMPLE_END,
     _SPI_CLK_IDLE_HIGH,_SPI_HIGH_2_LOW);
      Value1:=$21;
      Value2:=$00;
      AD9833_SEND(Value1,Value2);        //RESET BIT ACTIVE

end;
      
begin
  { Main program }
  InitMain();
  {First set up the PHASE0 data since the sine wave shape is constructed from
  the phase information.}
  Value1:=$C0;                  // Addresses  the PHASE0 register + 6 bits Data
  Value2:=$00;                      // Sets zero phase shift.
  AD9833_SEND(Value1,Value2);       // Sends Data

  {Next send the two 8 bit bytes for the LSB word to the FREQ0 register}
  Value1:=$66;                    // Addresses the FREQ0 register + 6 bits Data
  Value2:=$DD;                       // 8 bit Data
  AD9833_SEND(Value1,Value2);        // Sends Data

  
   {Next send the two 8 bit bytes for the MSB word to the FREQ0 register}
  Value1:=$40;                   // Addresses the FREQ0 register + 6 bits Data
  Value2:=$18;                      // 8 bit data
  AD9833_SEND(Value1,Value2);       // Sends Data
  
  {Finally un-reset the AD9833 in order to output the 115kHz sine wave
  specified by the data}
  Value1:=$20;
  Value2:=$00;
  AD9833_SEND(Value1,Value2);                  // Un-reset

  {Ramp FREQREG up 1000 increments of $56}
  fdata:=402653;
  for i:=1 to 1000 do
  begin
  Pack_AD9833(fdata);
  Ramp_Freq(Value1,Value2,Value3,Value4);
  fdata:=fdata+$56;
  end;
end.


The program starts with the linker directive $08 because a boot loader is used and this directive enables the program to leapfrog the bootloader vector.

The detail of the AD9833 instructions is best read from the AD9833 data sheet so need not be described here in any depth.

The INIT_MAIN procedure sets the scene.

The CHIP_SELECT line is set high to de-select the device and is defined as an output. SPI1_Init from the library tells the PIC how the SPI hardware is to behave.
It is necessary to RESET the AD9833 which in this case is accomplished by sending 14 bits of instruction preceded by the code 00 in bits 15 and 14. This is a major programming requirement to maintain the integrity of bits 15 and 14 in all transmissions to the AD9833 to make certain data goes to where it is intended. 00 describes the CONTROL REGISTER, 11 describes the Phase Register and 01 describes the Frequency Register (There are secondary phase and frequency registers to facilitate FSK modulation). Use is made of the procedure AD9833_Send to despatch the bytes $21 $00 to accomplish the reset and chose a sine wave output. Additionally the AD9833 is told to expect two consecutive words to set the FREQREG.

The phase register cannot be ignored since the sine waveshape uses phase information even although no phase shift is called for. This could have been included in the INIT_MAIN but the AD9833 PHASEREG instruction follows next in the main program.

AD9833_SEND enables the AD9833 input register by lowering the chip select, then sends the two bytes of data and then terminated the instruction by raising the CHIP_SELECT line to let the AD9833 know that the message is complete. It can then examine bits 15 and 14 and send the instruction to wherever it is intended.

The PHASEREG is sent the instruction $CO which sets the phase shift to zero degrees.
So far things have been simplified by manual assembly of the AD9833 register commands. The first setting of frequency sends two words, $66 $DD and $40 $18 to result in a 30kKz output. These have been manually constructed. In use this simplicity is unlikely to be available and the packaging of the two frequency commands must be accomplished in the program.

This is accomplished by procedure Pack_AD9833(fdata:dWord);

The data sheet tells us that frequency is set as 28 bits of data which must be sent into the 16 bit input register as an LSB word followed by an MSP word. Each 16 bit word must have the destination code in bits 15 and 14. The constituent bytes require to be fed into the input register MSB first, LSB second.

The FREQREG does not contain a numerical frequency but data derived from a scaling of the 28 bits fed to the AD9833 DAC by the PIC Clock frequency.

using a 20mHz clock.

In our case the 30kHz specification results in a FREQREG number of 402635 which is placed in a dWord container. In this form any arithmetic operation can be carried out such as the adding of an increment to ramp up the frequency. But having done this the 32 bit dWord needs encapsulated in the four 8 bit bytes which each MSP carrying the 01 code.

This is accomplished by Pack_AD9833 by taking advantage of the fact that a PascalPro byte type will sweep up the LSB of a larger structure such as a dWord. By progressively using shr, the required bytes can be placed in values1 to 4. However each 16 bytes only contain 14 bytes of data and 2 bytes of code(01). It is necessary clear the bits 7 and 6 of both MSBs and then replace them with 01 and ensuring that the lost data is shunted into the next byte. Value2 and Value 4 carry the 01 code and the shift 14 and 22 enable the erased bytes to be re-established to complete the 28 bytes of data and 4 bytes of register specification code.


So using these routines the instructions to the FREQREG can be automatically assembled from the raw FREQREG data and deposited there successfully. This task is realised in the RAMP_AD9833 procedure.

Of course none of this is rocket science but reading the AD9833 take some effort. This is no excuse to avoid reading the AD9833 data sheet which is very detailed and must be assimilated if the potential of this highly useful device is to be realised. The DDS is however not to be feared and the above routines enable a quick assessment to be made and the learning curve accelerated.

Dr. Colin Watson. Edinburgh.

User avatar
zristic
mikroElektronika team
Posts: 6608
Joined: 03 Aug 2004 12:59
Contact:

Re: AD9833 problem

#4 Post by zristic » 15 Feb 2011 22:13

amfortas, great post indeed!
Thank you.

thelegr
Posts: 6
Joined: 14 Jan 2011 19:19

Re: AD9833 problem

#5 Post by thelegr » 09 Jun 2012 18:47

amfortas i need your help!

what i want to do is creating a dds with ad9851 which will contains sine,triangle,square waves option, and a sweep with a max 5 hours sweep cycle (i need it for a rife machine for cancer's treatment)... i did not understood your project, not because of your explanation but because my insufficient knowledge.... i have only some lcd/glcd experience adc and buttons... so i know neither SPI technology... I wish you can help me! you or anyone who can and wants to!

Thank you very much in advance

Post Reply

Return to “mikroPascal FAQ”