Страница 1 из 1

ЦАП AD5620 + Atmega32

Добавлено: Пт мар 15, 2013 17:31:01
zigler
Доброго времени суток.
Уже долгое время не получается запустить ЦАП AD5620. Разрядность 12 бит, управление по SPI, данные считываются по спадающему фронту, первый MSB, нужно 16 бит для программирования.

Модели в Proteus'e нет, поэтому для моделирования использовал AD5621 (по управлению практически аналог - тоже 12 бит, SPI по спаду, первый MSB и 16 бит число). Причем даже структура числа для управления идентичная: 2 нуля(норм режим), 12 бит данные, 2 нуля(не важно).

софт написан на C в AVR Studio 5 + WinAVR. так вот, модель в протеусе работает, на плате нет.

скрин из протеус
Изображение

схема платы
Изображение

Проверьте, пожалуйста, схему, всё ли в порядке? В даташите нет примера схемы для AD5620, поэтому могут быть ошибки.

Код такой:

Код: Выделить всё

#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"

void SPI_WRITE_16(unsigned short data) 
{
    unsigned char MSdata = ((data >>8) & 0x00FF);
    unsigned char LSdata = (data & 0x00FF);

    SPDR = MSdata; 
    while(!(SPSR & (1<<SPIF)));
    SPDR = LSdata;
    while(!(SPSR & (1<<SPIF)));
}

int main(void)
{
	//LED
	DDRC = 0x02; //set C.1 as out - led
	PORTC = 0x02;
	
	//SPI
	uint16_t data[5] = {0x0000, 0x0FA0, 0x1F40, 0x2EE0, 0x3FFC};
	//uint16_t data[0] = 0x0000; //0 - min, 2 first 00...., 2 last ...00
	//uint16_t data[1] = 0x0FA0; //1000, 2 first 00...., 2 last ...00
	//uint16_t data[2] = 0x1F40; //2000, 2 first 00...., 2 last ...00
	//uint16_t data[3] = 0x2EE0; //3000, 2 first 00...., 2 last ...00
	//uint16_t data[4] = 0x3FFC; //4095 - max, 2 first 00...., 2 last ...00
	DDRB = (1<<PORTB0)|(1<<PORTB5)|(1<<PORTB7);//SS, MOSI, SCK
	SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL);
	
	//LCD
	DDRD = 0xFF;
	int i,j; 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 (5.0)
	prints("LCD");
	_delay_ms(500);
	gotoXy(0,1); // goto (0.1)
	prints("LCD_ATMEGA32");
	_delay_ms(500);
	
	while(1)
	{

		for (j = 0; j<=5; j++)
		{
			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);
			PORTB &= 0 << PORTB0;
			SPI_WRITE_16(data[j]);
			PORTB |= 1 << PORTB0;
			PORTC |= (1<<PORTC1);
			_delay_ms(2000);
		}

	}
}

Скачать проект в AVR Studio 5 и Proteus 7.10:
http://zalil.ru/34350292

Даташиты:
AD5620 http://www.analog.com/static/imported-f ... 0_5660.pdf
AD5621 http://www.analog.com/static/imported-f ... 1_5621.pdf

Огромное спасибо всем откликнувшимся!

Re: ЦАП AD5620 + Atmega32

Добавлено: Сб мар 16, 2013 23:52:49
zigler
Переписал код, теперь вроде правильно, всё равно на плате 0 реакции. В протеусе работает.

Может у кого есть аппарат Tektronix dpo 4054, подскажите как увидеть на нем SPI импульсы.
Что-то вроде такого изображения:
Изображение

как я понимаю, внизу те же 4 канала, но с анализатором SPI. или все же после триггера? и как поймать именно этот момент отправки информации? спасибо.

Re: ЦАП AD5620 + Atmega32

Добавлено: Вт мар 19, 2013 19:35:36
zigler
ЦАП заработал, выдает что нужно. Вот код:

Код: Выделить всё

#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

void SPI_WRITE_16(unsigned short data) 
{
    unsigned char MSdata = ((data >>8) & 0x00FF);
    unsigned char LSdata = (data & 0x00FF);

    SPDR = MSdata; 
    while(!(SPSR & (1<<SPIF)));
    SPDR = LSdata;
    while(!(SPSR & (1<<SPIF)));
}

int main(void)
{
	//LED
	DDRC = 0x02; //set C.1 as out - led
	PORTC = 0x02;
	
	//SPI
	uint16_t data[5] = {0x0000, 0x03E8, 0x07D0, 0x0BB8, 0x0FA0};
	//uint16_t data[0] = 0x0000; //0//0 - min, 2 first 00...., 2 last ...00
	//uint16_t data[1] = 0x03E8; //0.33//250, 2 first 00...., 2 last ...00
	//uint16_t data[2] = 0x07D0; //0.66//500, 2 first 00...., 2 last ...00
	//uint16_t data[3] = 0x0BB8; //0.99//750, 2 first 00...., 2 last ...00
	//uint16_t data[4] = 0x0FA0; //1.22//1000, 2 first 00...., 2 last ...00
	DDRB |= (1<<PORTB4)|(1<<PORTB5)|(1<<PORTB7);//SS, MOSI, SCK
	SPCR |= (1<<SPE)|(1<<MSTR)|(1<<CPOL);
	
	int i,j; i = 0;

	while(1)
	{
		for (j = 0; j<5; j++, i++)
		{
			PORTB &= ~(1 << PORTB4); //B4 = 0;
			SPI_WRITE_16(data[j]);
			PORTB |= (1<<PORTB4); //B4 = 1;
			PORTC |= (1<<PORTC1);
			_delay_ms(1000);
		}

	}
}			
вот скрин скопа:
Изображение

Только одна проблема, с "выбором чипа" кроме как на пине B.4 (у атмега32 стандартный пин SS у SPI) работать отказывается.
В чем проблема не могу понять... почему на другом пине даже не реагирует на команды?
Причем заметил что у меня со всеми устройствами на SPI такая проблема, работает только на стандартном пине SS. что не так?

просто таких ЦАПов много на 1 МК, и хотелось бы 1 SPI на все использовать...
возможно получиться такую схему реализовать, но желательно стандартно, по пину SS в мастере на каждый слейв
Изображение