ЦАП AD5620 + Atmega32

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Открыл глаза
Сообщения: 49
Зарегистрирован: Чт окт 25, 2012 15:46:44

Сообщение 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

Огромное спасибо всем откликнувшимся!
Реклама
Открыл глаза
Сообщения: 49
Зарегистрирован: Чт окт 25, 2012 15:46:44

Сообщение zigler »

Переписал код, теперь вроде правильно, всё равно на плате 0 реакции. В протеусе работает.

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

как я понимаю, внизу те же 4 канала, но с анализатором SPI. или все же после триггера? и как поймать именно этот момент отправки информации? спасибо.
Реклама
Открыл глаза
Сообщения: 49
Зарегистрирован: Чт окт 25, 2012 15:46:44

Сообщение 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 в мастере на каждый слейв
Изображение
Ответить

Вернуться в «Периферия»