AnsweredAssumed Answered

Problem with programming the AD9833

Question asked by George.Stefan on Jun 30, 2011
Latest reply on Oct 3, 2013 by musach

   Dear friends,

 

My name is Stefan and I'm trying to build a wave generator with AD9833 and programm it with PIC16F873.

I built the PIC pcb with the schematics below:

pic16f873.JPG

 

The AD9833 board and schematics like this:

schema DDS.JPG

 

cablaj DDS.JPG

 

And the Pascal code for the PIC :

 

program sintetizator_pic16f873;

 

var timp,rez:longint;
var pozitie:longint;
var tmp, viteza:word;
//var PORTC.1:sbit at RC1_bit;           //RC1 is set as the FSync SPI output
//    TRISC.1:sbit at TRISC1_bit;
var    Value1,Value2,Value3,Value4:byte;
    fdata,incrementer:dword;
    i:word;
var LCD_RS : sbit at RB7_bit;
var LCD_EN : sbit at RB6_bit;
var LCD_D4 : sbit at RB3_bit;
var LCD_D5 : sbit at RB2_bit;
var LCD_D6 : sbit at RB1_bit;
var LCD_D7 : sbit at RB0_bit;

 

var LCD_RS_Direction : sbit at TRISB4_bit;
var LCD_EN_Direction : sbit at TRISB5_bit;
var LCD_D4_Direction : sbit at TRISB3_bit;
var LCD_D5_Direction : sbit at TRISB2_bit;
var LCD_D6_Direction : sbit at TRISB1_bit;
var LCD_D7_Direction : sbit at TRISB0_bit;
// End Lcd module connections

 

//...
//Lcd_Init()
   
   
       //     define
   // sbit
label bucla;

 

 

{    *16F873 processor with 4MHz 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 16F873 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

 


//*****************************************************************************
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
     PORTC.6:=0;
     delay_us(10);
     SPI1_Write(Value1);
     SPI1_Write(Value2);
     delay_us(10);
     PORTC.6:=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 PORTC.1 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
     PORTC.6:=1;
     TRISC.6:=0;
    // SPI_Init_Advanced(MASTER_OSC_DIV4,DATA_SAMPLE_END,
    // CLK_IDLE_HIGH,HIGH_2_LOW);

 

     //SPI_Init_Advanced(MASTER_OSC_DIV4,DATA_SAMPLE_MIDDLE,
   //  CLK_IDLE_HIGH,HIGH_2_LOW);

 

    //  SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16,
     //                   _SPI_DATA_SAMPLE_MIDDLE,
       //                 _SPI_CLK_IDLE_HIGH,
         //               _SPI_HIGH_2_LOW);

 

      // Spi1_Init_Advanced(_SPI_MASTER, _SPI_16_BIT, _SPI_PRESCALE_SEC_1, _SPI_PRESCALE_PRI_1,
    //                 _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH,
     //               _SPI_IDLE_2_ACTIVE);
     SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4,_SPI_DATA_SAMPLE_MIDDLE,
     _SPI_CLK_IDLE_HIGH,_SPI_HIGH_2_LOW);

 

      delay_us(10);
      Value1:=$21;
      Value2:=$00;
      AD9833_SEND(Value1,Value2);        //RESET BIT ACTIVE
      delay_us(10);
      Value1:=$20;
      Value2:=$02;
      AD9833_SEND(Value1,Value2);

 

end;

 

begin

 


      TRISB:=0;// initializare PORTB ca port de iesire.
                  //Prin portul B se face comunicatie cu displayul
      TRISA.1:=1;  // se seteaza RA1 ca port de intrare
      TRISA.2:=1;  // se seteaza RA2 ca port de intrare
      TRISA.3:=1;  // se seteaza RA3 ca port de intrare

 

       TRISA.5:=0; // se seteaza RA5 ca iesire
      TRISC.3:=0;
      TRISC.5:=0;
      TRISC.6:=0;
      PORTC.3:=0;
      PORTC.5:=0;
      PORTC.6:=0;
      //TRISC:=%00000100;  // se seteaza portulC ca port de iesire
      //ADCON1:=$8E;
      ADCON1:=$07;

 

     //  OPTION_REG:=%11010111;
     // INTCON:=%11100000;

 

       //Lcd_Config (PORTB,0,1,2,3,PORTB,7,5,6);
      Lcd_Init();
      Lcd_Cmd(_LCD_CURSOR_OFF);
      delay_ms(100);
      Lcd_Cmd(_LCD_CLEAR); // se sterge displayul
      delay_ms(500);
      LCD_Out(1,1,'   SINTETIZOR DE    ');
      LCD_Out(2,1,'     FRECVENTA      ');
      delay_ms(2000);
      T1CON:=%00000001;

 

       { Main program }
  InitMain();
  {First set up the PHASE0 data since the sine wave shape is constructed from
  the phase information.}

 

   delay_us(10); //adaugat D

 

{

 

   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

 

  }

 

bucla:

 

   Value1:=$21;
  Value2:=$00;
  AD9833_SEND(Value1,Value2);

 

   delay_us(10);

 

   Value1:=$48;
  Value2:=$63;
  AD9833_SEND(Value1,Value2);
  delay_us(10);

 

   Value1:=$40;
  Value2:=$00;
  AD9833_SEND(Value1,Value2);
  delay_us(10);

 

   Value1:=$80;
  Value2:=$00;
  AD9833_SEND(Value1,Value2);
  delay_us(10);

 

   Value1:=$80;
  Value2:=$00;
  AD9833_SEND(Value1,Value2);
  delay_us(10);

 

   Value1:=$C0;
  Value2:=$00;
  AD9833_SEND(Value1,Value2);

 

   Value1:=$E0;
  Value2:=$00;
  AD9833_SEND(Value1,Value2);
  delay_us(10);

 

   Value1:=$20;
  Value2:=$00;
  AD9833_SEND(Value1,Value2);
  delay_us(10);

 

 

{
   //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;
}

 

 

//bucla:
      //viteza sunetului - calibrare
   //   tmp:= ADC_Read(0);
  //    rez:=(tmp*5000)/1024;
  //    rez:=rez/50;
  //    rez:=(rez*10)/16;
  //    viteza:=(331+rez)/2;

 


goto bucla;
end.

 

 

My problem is that even tough the program works, it's loaded into pic, it does sends something through the spi, the AD933 shows nothing on the output pin. I removed the R1 resistor from the MCLK line because the signal from the  20 MHz oscilator didn't get to the DDS because of it. I measured all the circuit lines, it's all working, DGND and AGND are tied togheter beneath the AD9833 directly, with no 0 Ohm resistor or coil.  The filter used at the output pin is 7 pole, 1.5 MHz from Coilcraft. I think there is a problem with the AD9833 board. I'm in a hurry to finish this project so I'm asking you kindly to suggest me some ideas to get this done. If the pictures are non-distinctive, i attached them to view them better. Thx a lot.


Attachments

Outcomes