Например TDA7294

Форум РадиоКот • Просмотр темы - АЦП AD7730
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Чт июл 31, 2025 05:53:34

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: АЦП AD7730
СообщениеДобавлено: Вт окт 11, 2011 13:37:33 
Родился
Аватар пользователя

Зарегистрирован: Вт окт 11, 2011 13:17:43
Сообщений: 7
Откуда: г. Томск
Рейтинг сообщения: 0
Доброго всем времени суток.
Прошу помочь с одной проблемой. Нужно получить оцифрованный сигнал с АЦП AD7730 на МК ATmega8. Когда использовал встроенный в МК АЦП проблем почти не было, но был большой минус - мало разрядов. Поэтому поставил 24-х разрядный AD7730. Развел согласно даташиту. Кварц 2,4576 МГц шкворчит. Сигнал с тензомоста (2 мВ/В при питании 12 В) усиливаю ОУ ОР275 примерно в 850 раз (если будет сильно шуметь, уменьшу усиление, пока не суть). На ноге CS АЦП, соединенной с PB2/SS МК логический 0. АЦП подключен к аппаратному SPI ATmega. Вся проблема в написании программы записи/чтения регистров АЦП и получению/отправке данных по SPI. В интернете, к сожалению, конкретного ответа или хотя бы совета не нашел. Даташиты перепрочитал, но вот как именно это реализуется в программной среде Си, где записываются регистры АЦП (в основной программе или в прерывании), как потом считать байт пришедший с DOUT, не знаю.
Инициализирую SPI:
SPCR=0xDB; //прерывание по SPI разрешено, активация SPI, первым передается старший разряд байта данных,
//MSTR=1 - МК ведущий, импульсы отриц.полярности, выборка по спадающему фронту,
//обработка данных по переднему фронту SCK, деление частоты на 128
SPSR=0x00; //
Вызываю прерывание:
interrupt [SPI_STC] void spi_isr(void)
{
data=SPDR;
}
Прошу помочь кодом (очень сильно желательно на Си) или советом.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Вт окт 11, 2011 20:07:01 
Держит паяльник хвостом
Аватар пользователя

Карма: 9
Рейтинг сообщений: 40
Зарегистрирован: Сб апр 02, 2011 17:59:22
Сообщений: 995
Откуда: Город-герой Севастополь
Рейтинг сообщения: 0
Все, по идее, достаточно несложно.
Для работы используем описанные в Атмеловском аппноуте151 (кажется) функции работы с SPI:
Код:
#define DDR_SPI DDRB
#define DD_MOSI 3
#define DD_MISO 4
#define DD_SCK 5
#define SPE 6
#define MSTR 4
#define SPR0 0
#define SPIF 7

//функция передачи байта
void SPI_MasterTransmit(char cData)
{
SPDR = cData;                                 //начинаем передачу
while(!(SPSR & (1<<SPIF)));             //ждем пока передача завершится
return;
}

функции инициализации МК ведомым и функция приема байта
void SPI_SlaveInit()
{
DDR_SPI = (1<<DD_MISO);             //настраиваем на выход MISO, остальные на вход
SPCR = (1<<SPE);                           //включаем SPI
}
//функция приема байта
char SPI_SlaveReceive()
{
while(!(SPSR & (1<<SPIF)));              //ждем если занят
return SPDR;                                    //возвращаем байт данных
}


После приема каждого байта измеренных данных лепим из восьмиразрядных переменных двадцатичетырехразрядную:
Код:
long int ADC_data;
ADC_data=ADC_data<<8;
ADC_data |= SPDR;

Все это дело повторяем три раза (можно в цикл встроить, тут уж разберетесь).
После этого с данными уже можно будет работать.
По поводу работы с регистрами АЦП. Все там делается через Communications register, доступ к которому получаем сразу же после подачи питания. Естественно, нам нужно полностью его инициализировать - выбрать режим, выбрать канал измерений, и т.д., и т.п. (все это подробно описано в даташите, повторяться не буду).
Для получения доступа к тому или иному регистру мы должны передать определенные значения битов RS2,RS1,RS0. К примеру, настроим регистр Mode register, используя функции, приведенные выше:
Код:
SPI_MasterTransmit(0x02);              //пишем 0b00000010 в Status register, получая доступ к Mode Register
SPI_MasterTransmit(0x4F);              //передаем старший байт настроек регистра
SPI_MasterTransmit(0xB0);             //передаем младший байт настроек регистра

Ну вот примерно как-то так, думается мне.
Если не нужно постоянно менять каналы и настройки АЦП, то достаточно единожды произвести инициализацию АЦП, и спокойненько себе работать. Но в прерывание не стоит ничего подобного пихать. Прерывание должно быть максимально кратким.

_________________
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )
Изображение


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Ср окт 12, 2011 04:55:49 
Родился
Аватар пользователя

Зарегистрирован: Вт окт 11, 2011 13:17:43
Сообщений: 7
Откуда: г. Томск
Рейтинг сообщения: 0
SubDia, спасибо. Буду пробовать.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Ср окт 12, 2011 13:33:05 
Родился
Аватар пользователя

Зарегистрирован: Вт окт 11, 2011 13:17:43
Сообщений: 7
Откуда: г. Томск
Рейтинг сообщения: 0
Что-то пока совсем не то, что нужно.
В основной программе void main инициализирую передачу и получение даных в и из регистров:
SPI_MasterInit();
SPI_MasterTransmit(0x02); //доступ в mode register
SPI_MasterTransmit(0x31); //старший байт: непрерывное преобразование,
//униполярный размах входн.напряж, передавать 24 бита данных,

SPI_MasterTransmit(0x90); //младший байт: опорное напр.=5В, диапазон вход.напр.=от 0 до 20мВ,
//вкл.внеш.резонатор, выкл.перегорание контактов, канал AIN1(+) AIN1(-)


SPI_MasterTransmit(0x21); //непрерывное считывание из регистра DATA
SPI_SlaveInit();

Прерыванием от таймера Т0 задаю тактирующие импульсы на ноге SCK:

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0xB2; //раз в 0,01 сек
PORTB^=(0x1<<5);
delay_ms ( 5 );
}

В прерывании от SPI считываю из SPDR:
interrupt [SPI_STC] void spi_isr(void)
{
SPI_SlaveReceive();
}

Прерыванием от Т1 мигаю светодиодом, считываю данные из SPDR и передаю на экран LCD:
interrupt [TIM1_OVF] void timer1_ovf_isr(void) //процедура прерывания от таймера Т1
{
TCNT1H=0xFC; //установить начальное //раз в 0,1 сек
TCNT1L=0xF2; //состояние таймера Т1
PORTB^=(0x01); //мигает светодиод
ADC_data = SPDR; //считываю из регистра данных
lcd_clear();
lcd_gotoxy( 0,0 );
sprintf( lcd_buffer,"U= %u",ADC_data );
lcd_gotoxy( 0,0 );
lcd_puts( lcd_buffer );

delay_ms( 10 );
return;
}

В итоге у меня на экране LCD чаще всего ноль, либо десятиричное 33 (это шестнадцитиричное 21, которое должно было задать непрерывное считывание) либо переполенный байт 255.
Где ошибся в коде?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Ср окт 12, 2011 13:52:53 
Друг Кота
Аватар пользователя

Карма: 32
Рейтинг сообщений: 235
Зарегистрирован: Пт янв 29, 2010 10:27:40
Сообщений: 3863
Откуда: Москва
Рейтинг сообщения: 0
Линия CS опускается в 0 во время передачи данных по SPI?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Ср окт 12, 2011 16:58:04 
Держит паяльник хвостом
Аватар пользователя

Карма: 9
Рейтинг сообщений: 40
Зарегистрирован: Сб апр 02, 2011 17:59:22
Сообщений: 995
Откуда: Город-герой Севастополь
Рейтинг сообщения: 0
Chipselect - это раз, и еще что-то не вижу, как Вы обрабатываете принятые данные.
Ведь у Вас переменная, приходящая от АЦП - 24-битная. То есть Вам нужно три раза принять восьмиразрядную посылку, приходящую от АЦП, и из этих посылок получить истинное число в двоичном виде. Может, в данной случае это и не столь критично, но все же внимание на это обратите.

_________________
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )
Изображение


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Чт окт 13, 2011 05:10:16 
Родился
Аватар пользователя

Зарегистрирован: Вт окт 11, 2011 13:17:43
Сообщений: 7
Откуда: г. Томск
Рейтинг сообщения: 0
Всем спасибо за ответы.
CS постоянно в логическом нуле. АЦП один и постоянно выбирать его нет смысла. Однажды его инициализировал CS в ноль и всё. По крайней мере так я понял из даташита.
Немного изменил прием 24-х битного значения:
interrupt [TIM1_OVF] void timer1_ovf_isr(void) //процедура прерывания от таймера Т1
{
TCNT1H=0xFC; //установить начальное
TCNT1L=0xF2; //состояние таймера Т1
PORTB^=(0x01);
b++; //инкремент
ADC_data=ADC_data<<8; //сразу сдвигаю на 8 разрядов влево
ADC_data = SPDR; //в младшие записываю данные
if (b==3) //проверяю условие трех отсчетов
{
lcd_clear();
lcd_gotoxy( 0,0 );
sprintf( lcd_buffer,"U= %u",ADC_data );
lcd_gotoxy( 0,0 );
lcd_puts( lcd_buffer );
b=0;
}
return;
}

Громоздко конечно для прерывания, но пока ничего лучше не придумал.
Теперь разбираюсь с тактирующим импульсом с ноги МК SCK на ногу АЦП SCLK. Может за 0,01 сек он отправлять не успевает.
Пока результат тот же, т.е. на экране чушь.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Чт окт 13, 2011 08:45:39 
Друг Кота
Аватар пользователя

Карма: 32
Рейтинг сообщений: 235
Зарегистрирован: Пт янв 29, 2010 10:27:40
Сообщений: 3863
Откуда: Москва
Рейтинг сообщения: 0
Lotus13 писал(а):
CS постоянно в логическом нуле. АЦП один и постоянно выбирать его нет смысла. Однажды его инициализировал CS в ноль и всё.

Тогда есть смысл его вообще заземлить, но раз есть возможность управлять, лучше ее использовать.
Lotus13 писал(а):
Теперь разбираюсь с тактирующим импульсом с ноги МК SCK на ногу АЦП SCLK. Может за 0,01 сек он отправлять не успевает.

Если используется RC-генератор на 8 МГц, и делитель на 128, получается тактовая SPI: 8МГц/128=62500Гц, для передачи 4х байт (1 байт команда чтения+3байта данных) нужно: 62500^-1*8*4=0.0005с


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Чт окт 13, 2011 09:16:04 
Родился
Аватар пользователя

Зарегистрирован: Вт окт 11, 2011 13:17:43
Сообщений: 7
Откуда: г. Томск
Рейтинг сообщения: 0
Резонатор на МК внешний, 8МГц. С ним проблем нет. Выяснил, что сигналы с RDY от АЦП должны показывать микроконтроллеру, идет передача, калибровка или как раз передача завершена. У меня же на RDY постоянно 5В, т.е. лог.1, либо он так долго этот бит передает, либо калибруется. RDY не переводится в 0. На МК эта нога подходит к PD2/INT0, внеш прерывания разрешил, настроил на прерывание по пришедшему низкому уровню. Само собой они не срабатывают (проверил).
Кто знаком с AD7730. Подскажите, почему RDY может не выдавать низкого уровня?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Пт окт 28, 2011 04:44:49 
Родился
Аватар пользователя

Зарегистрирован: Вт окт 11, 2011 13:17:43
Сообщений: 7
Откуда: г. Томск
Рейтинг сообщения: 0
Всем спасибо. Всё заработало. Главной проблемой была инициализация АЦП. А именно правильно установить фронты тактирующих импульсов с ведущего МК, установить полярность и фазу этих импульсов и соответственно полярность считывания импульсов ведомым АЦП. Всего восемь вариантов получилось. Тут главное не методом подбора, а всё таки почитать. Регистры записываются, данные читаются.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Вт окт 16, 2012 15:18:42 
Родился

Зарегистрирован: Вт окт 16, 2012 14:53:26
Сообщений: 2
Рейтинг сообщения: 0
Добрый день! Очень прошу вас помогите мне с запуском и конфигурацией.
Написал функции для записи и чтения всех регистров. Работают хорошо. Но прочитать данные с регистра данных никак не получается.
То отправляет FFFFFE, то выход AD7730 вовсе переходит в высокоимпедансное состояние.
Подскажите какая должна быть последовательность действий?
Код инициализации взял из datasheet
Код:
void AD7730_init()
{

      AD7730_CS=0;                    //Выбираю АЦП
      AD7730_write_8bit(0x03);     //Собираюсь писать в регистр фильтра
      AD7730_write_24bit(0x800010);      //Пишу в регистр фильтра
      AD7730_write_8bit(0x04);    //Собираюсь писать в регистр АЦП
      AD7730_write_8bit(0x23);       //Пишу в регистр  АЦП
      AD7730_write_8bit(0x02);         //Пишу в регистр MODE
      AD7730_write_16bit(0xB190);     //Пишу
             while(AD7730_RDY ==1)         //Жду когда на AD7730_RDY будет 0
            {
            Delay_ms(200);
            }
      AD7730_write_8bit(0x02);
      AD7730_write_16bit(0x9190);   //Internal Zero-Scale Calibration for 0 mV to +40 mV Input Range
            while(AD7730_RDY==1)   //Жду когда на AD7730_RDY будет 0
            {
            Delay_ms(200);
            }
      AD7730_write_8bit(0x02);
      AD7730_write_16bit(0x4190);   //Starting Continuous Conversions for 0 mV to +40 mV Input Range
            AD7730_write_8bit(0x21);   //Собираюсь читать 24 бит данных
            AD7730_SDO=0; //ошибки нет, опускаю выход МК(вход AD7730)

}



Дальше жду когда будет 0 на RDY и читаю
Код:
RX_24bit=AD7730_read_24bit();


Если видно явный баг то подскажите где он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Вс май 04, 2014 00:20:26 
Родился

Зарегистрирован: Сб май 03, 2014 20:11:44
Сообщений: 1
Рейтинг сообщения: 0
Помогите, не как ни получается адекватно заставить работать AD7730 и ATmeag32.
При Аппаратном SPI постоянно получаем 65535 (т.е. FF), при Программном SPI значения получаем и даже меняются в зависимости от нажима на тензодатчик, но через пару секунд AD7730 перестает выдавать данные (срыв чтения данных), тоже самое при сильном нажатии на датчик, только быстрее. Как добиться стабильной работы. Так же не понятно как убирать вес тары и калибровать тензодатчик под вес.
Буду очень благодарен за любую помощь.

_________________
Андрей (UB6AFB).


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Чт дек 25, 2014 18:09:47 
Родился

Зарегистрирован: Чт дек 25, 2014 17:52:31
Сообщений: 2
Рейтинг сообщения: 0
Как найти топикстартера?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Пт дек 26, 2014 04:24:03 
Родился
Аватар пользователя

Зарегистрирован: Вт окт 11, 2011 13:17:43
Сообщений: 7
Откуда: г. Томск
Рейтинг сообщения: 0
Тут я, однако помочь увы не могу. С тех пор перевелся на ПЛИС и скоростные параллельные АЦП. Про тот проект забыл окончательно, хотя и получил тогда удовлетворительные результаты. Все равно уже код проекта утерян, разве что сама плата где-то еще валяется. Больше, чем описывал я и те, кто мне помогал, в этой теме я сказать не смогу. АЦП удалось запустить, точность измерений составляла около 0,1 %, не удалось обнулять вес тары, как выразился DJCooler сообщением выше, не удалось стабилизировать показания на LCD. Но это в первую очередь связано с ФНЧ фильтром, который я тогда считать не умел, во вторую с тензодатчиком, в третью с кривой программой. Удачи, да прибудет с вами сила.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП AD7730
СообщениеДобавлено: Пт май 13, 2016 17:42:48 
Потрогал лапой паяльник

Карма: 4
Рейтинг сообщений: 26
Зарегистрирован: Вс авг 16, 2015 13:08:53
Сообщений: 333
Рейтинг сообщения: 0
Всем привет! Раз уж такая тема есть напишу здесь. Работаю с этим АЦП и на нем собрал амперметр. Запустил работает шустро но, в итоге при подаче тока на шунт через некоторое время он начинает плавать. Ноль стоит на месте. В качестве опорника стоит ref192. Напряжение с шунта подается на AIN1+ и AIN1-. Перед входом стоит RC фильтр. 2к2 резисторы и 5мкф кондеры. Может кто знает как мне его подключить чтоб он не плавал?


Вложения:
0.png [3.04 KiB]
Скачиваний: 800
Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y