Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Не получается запустить генератор AD9834 с ЦАП AD5620

Вс мар 03, 2013 13:16:56

Доброго времени суток.

Не получается запустить генератор AD9834 с ЦАП AD5620.
Схемку и печатную плату прикрепил, делал по даташитам, проверьте пожалуйста!

Сигналы с ножек MOSI, SCK и CS МК проверял на осциллографе, все ок. А вот чипы не воспринимают, программа в МК "виснет" на ожидании окончания передачи по SPI. В даташитах на AD9834 и AD5620 указано, что данные принимаются на спадающем фронте SCK, поэтому инициализировал SPI как
SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<SPR0);
или
SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<SPR0);
,т.е. пробовал по спад. фронту и с отрицательными сигналами SPI, не работает.
Проверял напряжение на ножках REF - как и должно быть, 1.2V. Значит ли это, что чип рабочий? Просто боюсь, что мог перегреть при паянии. Как еще можно проверить?
Сделал уже 2 платы, ни одна не работает :cry:

Микроконтроллер Atmega32 с кварцем 16 МГц, фьюзы изменял только для кварца.

Схема
Изображение

Печатная плата
Изображение

Даташит AD9834 http://www.analog.com/static/imported-files/data_sheets/AD9834.pdf
Даташит AD5620 http://www.analog.com/static/imported-files/data_sheets/AD5620_5640_5660.pdf
CN0156_Ampl_control_AD9834 http://www.analog.com/en/circuits-from-the-lab/CN0156/vc.html
AN-1070_programming_9834 http://www.analog.com/static/imported-files/application_notes/AN-1070.pdf

Вот мой код в AVR Studio 5.

Код:
#include <avr/io.h>
#include <stdio.h>
#define F_CPU 16000000UL  // 16 MHz
#ifndef ALIBC_OLD
#include <util/delay.h>
#else
#include <avr/delay.h>
#endif
#include "lcd16.h"


#define AD9834_CONTROL_PORT      PORTB
#define AD9834_CONTROL_DDR      DDRB
#define AD9834_CONTROL_MISO      PORTB6
#define AD9834_CONTROL_MOSI      PORTB5
#define AD9834_CONTROL_SCK      PORTB7

#define AD9834_CONTROL_CS_PORT   PORTB
#define AD9834_CONTROL_CS_DDR   DDRB
#define AD9834_CONTROL_CS      PORTB0

#define AD9834_CONTROL_RESET_PORT   PORTB
#define AD9834_CONTROL_RESET_DDR   DDRB
#define AD9834_CONTROL_RESET      PORTB1

// set CS to 0 = active
#define CSACTIVEAD9834 AD9834_CONTROL_CS_PORT &= ~(1<<AD9834_CONTROL_CS)
// set CS to 1 = passive
#define CSPASSIVEAD9834 AD9834_CONTROL_CS_PORT |= (1<<AD9834_CONTROL_CS)

///////////////////////////////////////////////////

#define AD5620_CONTROL_PORT   PORTB
#define AD5620_CONTROL_DDR    DDRB
#define AD5620_CONTROL_MISO PORTB6
#define AD5620_CONTROL_MOSI PORTB5
#define AD5620_CONTROL_SCK PORTB7

#define AD5620_CONTROL_CS_PORT   PORTB
#define AD5620_CONTROL_CS_DDR    DDRB
#define AD5620_CONTROL_CS     PORTB2

// set CS to 0 = active
#define CSACTIVEAD5620 AD5620_CONTROL_CS_PORT &= ~(1<<AD5620_CONTROL_CS)
// set CS to 1 = passive
#define CSPASSIVEAD5620 AD5620_CONTROL_CS_PORT |= (1<<AD5620_CONTROL_CS)

#define waitspi() while(!(SPSR & (1<<SPIF)))


void SPI_write16_AD9834 (unsigned short data)       //    send a 16bit word and use fsync
{

   unsigned char MSdata = ((data>>8) & 0x00FF);     //filter out MS
   unsigned char LSdata = (data & 0x00FF);         //filter out LS

   CSACTIVEAD9834;                        //    Fsync Low --> begin frame
   
   SPDR = MSdata;                     //    send First 8 MS of data
   waitspi();                        //   while busy

   SPDR = LSdata;                     //    send Last 8 LS of data
   waitspi();                        //   while busy

   CSPASSIVEAD9834;                        //    Fsync High --> End of frame
}

void SPI_write16_AD5620 (unsigned short data)       //    send a 16bit word and use fsync
{
   
   unsigned char MSdata = ((data>>8) & 0x00FF);     //filter out MS
   unsigned char LSdata = (data & 0x00FF);         //filter out LS

   CSACTIVEAD5620;                        //    Fsync Low --> begin frame
   
   //write data
   SPDR = MSdata;                        //    send First 8 MS of data
   waitspi();                           //   while busy

   SPDR = LSdata;                        //    send Last 8 LS of data
   waitspi();                           //   while busy

   CSPASSIVEAD5620;                     //    Fsync High --> End of frame
}

int main(void)
{
   //LED
   DDRC = 0x02; //set C.1 as out - led
   PORTC = 0x02;
   
   CSPASSIVEAD9834;
   CSPASSIVEAD5620;
   
   //SPI init   
   AD5620_CONTROL_DDR |= (1<<AD5620_CONTROL_MOSI)|(1<<AD5620_CONTROL_SCK);
   AD5620_CONTROL_CS_DDR |= (1<<AD5620_CONTROL_CS);
   AD9834_CONTROL_CS_DDR |= (1<<AD9834_CONTROL_CS);
   AD9834_CONTROL_RESET_DDR |= (1<<AD9834_CONTROL_RESET);
   // SPI Clock Phase: falling edge
    // SPI Data Order: MSB First
    // set clock rate fck/16
   SPCR |= (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<SPR0);
      
   //AD9834_init
   SPI_write16_AD9834(0x2100);      // control word, set output to mid value voltage
   SPI_write16_AD9834(0x429F);      // Freq0 registerdata LSB  = approx. 50 hz
   SPI_write16_AD9834(0x4000);      // Freq0 registerdata MSB  = approx. 50 hz
   //Freq_write (50,0);
   SPI_write16_AD9834(0x82C7);      // Freq1 registerdata LSB  = approx. 53 hz
   SPI_write16_AD9834(0x8000);    // Freq1 registerdata MSB  = approx. 53 hz
   //Freq_write (53,1);
   SPI_write16_AD9834(0xC000);      // Phase offset of Phase0 = 0
   //Phase_write(0,0);
   SPI_write16_AD9834(0xE155);      // Phase offset of Phase1 = 30_grad
   //Phase_write(30,1);
   SPI_write16_AD9834(0x2000);      // control word, set output = sine
   
   //AD5620_init
   SPI_write16_AD5620 (0x0000);
   
   
   //LCD
   DDRD = 0xFF;
   int i; i = 0;
   char lcd_buffer[33];
   lcdInit();   // init the LCD screen
   _delay_ms(50);
   lcdCmd(0x01); // clear lcd
   _delay_ms(50);
    gotoXy(5,0); // goto (0.0)
   prints("LCD");
   
   CSACTIVEAD9834;
   _delay_ms(2000);
   CSPASSIVEAD9834;
   
   CSACTIVEAD5620;
   _delay_ms(2000);
   CSPASSIVEAD5620;
   
   gotoXy(0,1); // goto (0.1)
   prints("LCD_ATMEGA32");
   _delay_ms(2000);

    while(1)
    {
      i = i+1;

      sprintf(lcd_buffer,"counter: %u",i);
      lcdCmd(0x01); // clear lcd
      gotoXy(0,0); // goto (0.0)
      prints(lcd_buffer);
      _delay_ms(100);
      SPI_write16_AD9834(0x2000);
      _delay_ms(100);
      PORTC &= ~(1<<PORTC1);
      SPI_write16_AD5620 (0x0000);
      _delay_ms(1000);
      
      sprintf(lcd_buffer,"counter: %u",i);
      lcdCmd(0x01); // clear lcd
      gotoXy(0,0); // goto (0.0)
      prints(lcd_buffer);
      _delay_ms(100);
      SPI_write16_AD9834(0x2800);
      _delay_ms(100);
      PORTC |= (1<<PORTC1);
      SPI_write16_AD5620 (0x03E8);
      _delay_ms(1000);
      
    }
}
Ответить