AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
15.03.2013, 18:18
|
|
Прописка
Регистрация: 25.10.2012
Сообщений: 112
Сказал спасибо: 50
Сказали Спасибо 1 раз в 1 сообщении
|
ЦАП AD5620 + Atmega32
Доброго времени суток.
Уже долгое время не получается запустить ЦАП 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://www.analog.com/static/importe..._5640_5660.pdf
http://www.analog.com/static/importe..._5611_5621.pdf
Огромное спасибо всем откликнувшимся!
Последний раз редактировалось pavned; 15.03.2013 в 18:26.
|
|
|
|
15.03.2013, 19:12
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: ЦАП AD5620 + Atmega32
SPIF вроде как надо программно сбрасывать, если не используется прерывание
|
|
|
|
15.03.2013, 20:02
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: ЦАП AD5620 + Atmega32
Занятная строка PORTB &= 0 ‹‹ PORTB0
Весь порт обнуляет.
|
|
|
|
15.03.2013, 23:15
|
|
Гражданин KAZUS.RU
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
|
Re: ЦАП AD5620 + Atmega32
Сообщение от niXto
|
SPIF вроде как надо программно сбрасывать, если не используется прерывание
|
Не надо сбрасывать.
|
|
|
|
16.03.2013, 17:00
|
|
Прописка
Регистрация: 25.10.2012
Сообщений: 112
Сказал спасибо: 50
Сказали Спасибо 1 раз в 1 сообщении
|
Re: ЦАП AD5620 + Atmega32
Сообщение от Boba_spb
|
Занятная строка PORTB &= 0 ‹‹ PORTB0
Весь порт обнуляет.
|
почему? например такая строка обнуляет только нужный пин?
PORTB &= ~(1 ‹‹ PORTB0);
ну или так:
PORTB &= ~_BV(0);
Последний раз редактировалось pavned; 16.03.2013 в 17:03.
|
|
|
|
16.03.2013, 20:01
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: ЦАП AD5620 + Atmega32
Сообщение от pavned
|
почему?
|
А что до этого в PORTB записано?
0h xxxx xxxx
&
0h 0000 0000
=?
Сообщение от pavned
|
ну или так:
|
~_BV(0) = ~0h 0000 0001 = 0h 1111 1110
0h xxxx xxxx
&
0h 1111 1110
=
0h xxxx xxx0
|
|
|
|
16.03.2013, 20:37
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: ЦАП AD5620 + Atmega32
Сообщение от pavned
|
почему? например такая строка обнуляет только нужный пин?
PORTB &= ~(1 ‹‹ PORTB0);
ну или так:
PORTB &= ~_BV(0);
|
Потому что скоко 0 не двигай будет 0!!
и PortB &=0 Эквивалентно PortB=0;
Что делать - арихметика такая .
А вот это вот PORTB &= ~(1 ‹‹ PORTB0);
1‹‹Portb = 1‹‹0 = 0b00000001
~ - вот это вот из 0b00000001 делает 0b11111110
и наконец Portb &= 0b11111110 - сбрасывет только нулевой бит.
|
|
|
|
16.03.2013, 22:56
|
|
Прописка
Регистрация: 25.10.2012
Сообщений: 112
Сказал спасибо: 50
Сказали Спасибо 1 раз в 1 сообщении
|
Re: ЦАП AD5620 + Atmega32
Сообщение от omercury
|
А что до этого в PORTB записано?
0h xxxx xxxx
&
0h 0000 0000
=?
0h xxxx xxxx
&
0h 1111 1110
=
0h xxxx xxx0
|
по-моему 0h - это шестнадцатеричное число, а двоичное 0b.
спасибо, идею уловил
Сообщение от Boba_spb
|
Потому что скоко 0 не двигай будет 0!!
и PortB &=0 Эквивалентно PortB=0;
Что делать - арихметика такая .
А вот это вот PORTB &= ~(1 ‹‹ PORTB0);
1‹‹Portb = 1‹‹0 = 0b00000001
~ - вот это вот из 0b00000001 делает 0b11111110
и наконец Portb &= 0b11111110 - сбрасывет только нулевой бит.
|
Спасибо конечно за столь подробное объяснение. Что такое ~ я знаю конечно))
Я чего-то думал, что команда PORTB &= (0 ‹‹ PORTB0); присвоит 0 только PORTB0, а все остальное трогать не будет... ну теперь точно понял разницу между |= и &=
Хотя написал правильно, всё равно на плате 0 реакции. В протеусе работает.
Может у кого есть аппарат Tektronix dpo 4054, подскажите как увидеть на нем SPI импульсы.
Что-то вроде такого изображения:
как я понимаю, внизу те же 4 канала, но с анализатором SPI. или все же после триггера? и как поймать именно этот момент отправки информации? спасибо.
Последний раз редактировалось pavned; 16.03.2013 в 23:18.
|
|
|
|
19.03.2013, 20:42
|
|
Прописка
Регистрация: 25.10.2012
Сообщений: 112
Сказал спасибо: 50
Сказали Спасибо 1 раз в 1 сообщении
|
Re: ЦАП AD5620 + Atmega32
ЦАП заработал, выдает что нужно. Вот код:
Код:
|
#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 в мастере на каждый слейв
Последний раз редактировалось pavned; 19.03.2013 в 20:57.
|
|
|
|
19.03.2013, 20:53
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: ЦАП AD5620 + Atmega32
СПИ переведен принудительно в режим мастера?
Попробуй посадить ножку SS на землю, если после этого заработает на других ножках - копай код
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 03:28.
|
|