Например TDA7294

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



Текущее время: Сб дек 16, 2017 20:30:29



Часовой пояс: UTC + 3 часа [ Летнее время ]


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



Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Внешний АЦП AD7091R
СообщениеДобавлено: Вт дек 05, 2017 18:37:10 
Первый раз сказал Мяу!

Зарегистрирован: Ср мар 26, 2014 18:33:08
Сообщений: 38
Рейтинг сообщения: 0
Доброго дня, коллеги! Подскажите пожалуйста, знающие люди, по поводу внешнего АЦП AD7091R-2. Не подружить мне его через SPI c stm32... Он работает, но только с одним каналом, а мне нужно с двумя. Ну и к самой сути вопроса.

В качестве, основного микроконтроллера, выбрал STM32F3DISCOVERY... Сама stm'ka подключена к АЦП, через SPI изолятор ADUM3154, соответственно плата DISCOVERY питается своим напряжением от USB, а АЦП питается от отдельного источника 5 вольт. Так же у AD7091R-2, предусмотрен вывод CONVST для управления, не относящийся к SPI, что бы и его развязать, пришлось установить оптопару...

Изображение

Ну и собственно инициализация SPI1:

Код:
void AD7091_Init_GPIO()
{
   GPIO_InitTypeDef gpio_def;
   SPI_InitTypeDef spi_def;

   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

   GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_5);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_5);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_5);

        // GPIO для SPI1
   gpio_def.GPIO_Mode = GPIO_Mode_AF;
   gpio_def.GPIO_OType = GPIO_OType_PP;
   gpio_def.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
   gpio_def.GPIO_PuPd = GPIO_PuPd_NOPULL;
   gpio_def.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOA, &gpio_def);

        // GPIO для CS - ручное управление
   gpio_def.GPIO_Mode = GPIO_Mode_OUT;
   gpio_def.GPIO_OType = GPIO_OType_PP;
   gpio_def.GPIO_Pin = GPIO_Pin_4;
   gpio_def.GPIO_PuPd = GPIO_PuPd_UP;
   gpio_def.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOA, &gpio_def);

         // GPIO для CONVST
   gpio_def.GPIO_Mode = GPIO_Mode_OUT;
   gpio_def.GPIO_OType = GPIO_OType_PP;
   gpio_def.GPIO_Pin = GPIO_Pin_14;
   gpio_def.GPIO_PuPd = GPIO_PuPd_DOWN;
   gpio_def.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOD, &gpio_def);

   GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);
   GPIO_WriteBit(GPIOD, GPIO_Pin_14, Bit_SET);

   spi_def.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
   spi_def.SPI_Mode = SPI_Mode_Master;
   spi_def.SPI_DataSize = SPI_DataSize_16b;
   spi_def.SPI_CPOL = SPI_CPOL_High;
   spi_def.SPI_CPHA = SPI_CPHA_2Edge;
   spi_def.SPI_NSS = SPI_NSS_Soft;
   spi_def.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
   spi_def.SPI_FirstBit = SPI_FirstBit_MSB;
   spi_def.SPI_CRCPolynomial = 0x7;
   SPI_Init(SPI1, &spi_def);

   SPI_Cmd(SPI1, ENABLE);   
}


Дальше идет инициализация АЦП по SPI:
Код:
#define AD7091_CONFIG            0x14C0

#define CH0_LO         0x2400
#define CH0_HI                 0x2DFF
#define CH0_HY         0x35FF

#define CH1_LO         0x3C00
#define CH1_HI                 0x45FF
#define CH1_HY         0x4DFF

#define CONVERT_OFF      0x0000
#define CONVERT_ON      0x0001

uint16_t AD7091_WtiteData(int convert, uint16_t data)
{
   uint16_t result = 0x0;

   if(convert == CONVERT_ON)
   {
      GPIO_WriteBit(GPIOD, GPIO_Pin_14, Bit_RESET);
      GPIO_WriteBit(GPIOD, GPIO_Pin_14, Bit_SET);
   }

   while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
   GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);
   SPI_I2S_SendData16(SPI1, data);
   while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
   result = SPI_I2S_ReceiveData16(SPI1);
   GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);

   return result;
}

uint16_t AD7091_ReadData(uint16_t data)
{
   uint16_t result = 0x0;

   AD7091_WtiteData(CONVERT_OFF, data);
   result = AD7091_WtiteData(CONVERT_OFF, 0x00);

   return result;
}

void AD7091_Init()
{
   uint16_t result = 0x00;

   AD7091_Init_GPIO();

   for(int i = 0; i < 0x42; i++)
   {
      GPIO_WriteBit(GPIOD, GPIO_Pin_14, Bit_RESET);
      GPIO_WriteBit(GPIOD, GPIO_Pin_14, Bit_SET);
   }

   AD7091_WtiteData(CONVERT_OFF, AD7091_CONFIG);
   AD7091_WtiteData(CONVERT_OFF, CH0_LO);
   AD7091_WtiteData(CONVERT_OFF, CH0_HI);
   AD7091_WtiteData(CONVERT_OFF, CH0_HY);
   AD7091_WtiteData(CONVERT_OFF, CH1_LO);
   AD7091_WtiteData(CONVERT_OFF, CH1_HI);
   AD7091_WtiteData(CONVERT_OFF, CH1_HY);

   result = AD7091_ReadData(0x800);
   result = AD7091_ReadData(0x1000);
   result = AD7091_ReadData(0x2000);
   result = AD7091_ReadData(0x2800);
   result = AD7091_ReadData(0x3000);
   result = AD7091_ReadData(0x3800);
   result = AD7091_ReadData(0x4000);
   result = AD7091_ReadData(0x4800);
}


То есть, для проверки, сначала данные записали, а потом эти же данные и прочитали. Тут уже таится первый подвох, почему то в регистор CH0_HI и CH1_HI записываю значения 0x1FF, а читается 0xFFF... Не знаю почему так... Хотя SPI работает четко, как надо...

Изображение

Вот, на скине, раньше в регистор CONFIG записал 0xC0, вот он и прочитал 0xC0, то что нужно.

Считываю данные с АЦП вот таким методом:

Код:
uint16_t AD7091_GetData()
{
   uint16_t adc[4];
   uint16_t result = 0x00;

   adc[0] = AD7091_WtiteData(CONVERT_ON, 0x00);
   
   return result;
}


Изображение

Значения похожи на правду, но это на 0 канале

А дальше трабола, если не трогать регистор Channel, то он всегда автоматом считывает на 0 канале.
Мне нужно считать данные сначала на 0 канале, а потом на 1 канале. Делаю все как в даташите указано

Изображение

Сначала, записываю данные в регистор Channel, про 0 канал, потом про 1 канал и потом на 3 и 4 обмен данными, должны прийти результаты с этих двух каналов...

Код:
uint16_t AD7091_GetData()
{
   uint16_t adc[4];
   uint16_t result = 0x00;

   adc[0] = AD7091_WtiteData(CONVERT_ON, 0xC01);
   adc[1] = AD7091_WtiteData(CONVERT_ON, 0xC02);
   adc[2] = AD7091_WtiteData(CONVERT_ON, 0x000);
   adc[3] = AD7091_WtiteData(CONVERT_ON, 0x000);

   return result;
}


Изображение

А они не приходят, вернее приходят данный, но какой то бред.
Подскажи пожалуйста, где собака порылась....


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Чт дек 07, 2017 13:59:52 
Встал на лапы

Зарегистрирован: Вс авг 16, 2015 14:08:53
Сообщений: 103
Рейтинг сообщения: 0
Код:
#define AD7091_CONFIG            0x14C0
Откуда взяли значение 0x14C0?


Вернуться наверх
 Профиль  
 
JLCPCB Prototype, Бесплатная доставка первого заказа + $2 на прототип ПП!

Крупнейший производитель печатных плат в Китае, 290,000+ заказчиков, 8,000+ он-лайн заказов в день.

Цена за 10 плат: $2 за 2-х слойную, $15 за 4-х слойную, $74 за 6-ти слойную.

LCSC Parts: Экономия до 50%, большой выбор компонентов в наличии, отправка заказа в день оплаты.

Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Чт дек 07, 2017 23:59:04 
Первый раз сказал Мяу!

Зарегистрирован: Ср мар 26, 2014 18:33:08
Сообщений: 38
Рейтинг сообщения: 0
Бубоник писал(а):
Код:
#define AD7091_CONFIG            0x14C0
Откуда взяли значение 0x14C0?


Собственно, команда записи данных в регистр выглядит вот так вот:

Изображение

с 0 по 9 бит - это сами данные
10 бит - это бит записи (1 - запись, 0 - чтение)
с 11 по 15 биты - это адрес регистра

адрес регистра configuration: 0x2

Изображение

Ну и сами данные регистра:

Изображение

И насколько, я понял из даташита, все финтифлюшки с ALERT и BUSY используются, только для 4 и 8 канальных ацп, т. е. в моем варианте этого нет...

Исходя из вышеперечисленного получается: 00010 1 0011000000 => 0x14C0
Так же пробовал менять биты 0 и 1 это Power-down mode, результатов не дало...


Вернуться наверх
 Профиль  
 

Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Пт дек 08, 2017 15:23:00 
Встал на лапы

Зарегистрирован: Вс авг 16, 2015 14:08:53
Сообщений: 103
Рейтинг сообщения: 0
А где у вас записываются данные в конфигурационный регистр?


Вернуться наверх
 Профиль  
 

Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Пт дек 08, 2017 17:36:31 
Первый раз сказал Мяу!

Зарегистрирован: Ср мар 26, 2014 18:33:08
Сообщений: 38
Рейтинг сообщения: 0
Бубоник писал(а):
А где у вас записываются данные в конфигурационный регистр?


Вот, в коде инициализации:

Код:
void AD7091_Init()
{
   uint16_t result = 0x00;

   AD7091_Init_GPIO();

   for(int i = 0; i < 0x42; i++)
   {
      GPIO_WriteBit(GPIOD, GPIO_Pin_14, Bit_RESET);
      GPIO_WriteBit(GPIOD, GPIO_Pin_14, Bit_SET);
   }

   AD7091_WtiteData(CONVERT_OFF, AD7091_CONFIG);
   AD7091_WtiteData(CONVERT_OFF, CH0_LO);
   AD7091_WtiteData(CONVERT_OFF, CH0_HI);
   AD7091_WtiteData(CONVERT_OFF, CH0_HY);
   AD7091_WtiteData(CONVERT_OFF, CH1_LO);
   AD7091_WtiteData(CONVERT_OFF, CH1_HI);
   AD7091_WtiteData(CONVERT_OFF, CH1_HY);

   result = AD7091_ReadData(0x800);
   result = AD7091_ReadData(0x1000);
   result = AD7091_ReadData(0x2000);
   result = AD7091_ReadData(0x2800);
   result = AD7091_ReadData(0x3000);
   result = AD7091_ReadData(0x3800);
   result = AD7091_ReadData(0x4000);
   result = AD7091_ReadData(0x4800);
}


Функцией AD7091_WtiteData(), самая первая запись


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Пт дек 08, 2017 20:21:19 
Встал на лапы

Зарегистрирован: Вс авг 16, 2015 14:08:53
Сообщений: 103
Рейтинг сообщения: 0
Если вот эта строка,
Код:
AD7091_WtiteData(CONVERT_OFF, AD7091_CONFIG);
то желательно отправлять 0x16C0, так как в инициализации указанно про soft reset.

Добавлено after 1 hour 33 minutes 41 second:
И еще кое что.
Код:
result = AD7091_ReadData(0x800);
Здесь случаем не должно ли быть значение 0x801?.


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Вс дек 10, 2017 07:59:58 
Модератор
Аватар пользователя

Карма: 129
Зарегистрирован: Сб авг 14, 2010 16:05:51
Сообщений: 12825
Откуда: г. Озерск, Челябинская обл.
Рейтинг сообщения: 0
при подаче питание уже произошел reset. повторно его делать не надо.

_________________
Мудрость приходит вместе с импотенцией...


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Вс дек 10, 2017 20:59:35 
Первый раз сказал Мяу!

Зарегистрирован: Ср мар 26, 2014 18:33:08
Сообщений: 38
Рейтинг сообщения: 0
Хоть убейте, не работает и все...


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Вс дек 10, 2017 21:21:35 
Встал на лапы

Зарегистрирован: Вс авг 16, 2015 14:08:53
Сообщений: 103
Рейтинг сообщения: 0
А какие он данные присылает после команды 0x800?


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Вт дек 12, 2017 18:34:44 
Первый раз сказал Мяу!

Зарегистрирован: Ср мар 26, 2014 18:33:08
Сообщений: 38
Рейтинг сообщения: 0
Бубоник писал(а):
А какие он данные присылает после команды 0x800?


Для начала, решил никаких данных не писать, а просто прочитать значения регистров. В таблице 10, есть колонка Default, вроде, это значения по дефолту, которые должны быть там... Вот что получилось:

Код:
        //Channel
   result = AD7091_ReadData(0x800);   //0

   //Configuration
   result = AD7091_ReadData(0x1000);   //192

   //Channel 0 low limit
   result = AD7091_ReadData(0x2000);   //0

   //Channel 0 high limit
   result = AD7091_ReadData(0x2800);   //4095

   //Channel 0 hysteresis
   result = AD7091_ReadData(0x3000);   //511

   //Channel 1 low limit
   result = AD7091_ReadData(0x3800);   //0

   //Channel 1 high limit
   result = AD7091_ReadData(0x4000);   //4095

   //Channel 1 hysteresis
   result = AD7091_ReadData(0x4800);   //511


Все совпадает со значениями по дефолту, кроме двух параметров: Channel 0 high limit и Channel 1 high limit... По дефолту должны быть значение 0x1FF, а он почему то отправляет 0xFFF...

Дальше, записываем данные. По сути, я обновляю значение, только одного регистра, а именно: Configuration. А все остальные значения, дублирую по дефолту...

Код:
//---------------------------------------------------------------------

   //Configuration
   AD7091_WtiteData(CONVERT_ON, 0x16C0);

   //Channel 0 low limit
   AD7091_WtiteData(CONVERT_ON, 0x2400);

   //Channel 0 high limit
   AD7091_WtiteData(CONVERT_ON, 0x2DFF);

   //Channel 0 hysteresis
   AD7091_WtiteData(CONVERT_ON, 0x35FF);

   //Channel 1 low limit
   AD7091_WtiteData(CONVERT_ON, 0x3C00);

   //Channel 1 high limit
   AD7091_WtiteData(CONVERT_ON, 0x45FF);

   //Channel 1 hysteresis
   AD7091_WtiteData(CONVERT_ON, 0x4DFF);

   //---------------------------------------------------------------------

   //Channel
   result = AD7091_ReadData(0x800);   //0

   //Configuration
   result = AD7091_ReadData(0x1000);   //192

   //Channel 0 low limit
   result = AD7091_ReadData(0x2000);   //0

   //Channel 0 high limit
   result = AD7091_ReadData(0x2800);   //4095

   //Channel 0 hysteresis
   result = AD7091_ReadData(0x3000);   //511

   //Channel 1 low limit
   result = AD7091_ReadData(0x3800);   //0

   //Channel 1 high limit
   result = AD7091_ReadData(0x4000);   //4095

   //Channel 1 hysteresis
   result = AD7091_ReadData(0x4800);   //511

   //---------------------------------------------------------------------


И ничего не поменялось...
Если я в Configuration записываю значение 0x16C0, то он в ответ на чтение присылает 192, а если записываю 0x16C3 - то 195


Вложения:
Комментарий к файлу: Вот, полный даташит к этому АЦП
AD7091R.pdf [854.58 KiB]
Скачиваний: 3
Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Вт дек 12, 2017 23:37:16 
Встал на лапы

Зарегистрирован: Вс авг 16, 2015 14:08:53
Сообщений: 103
Рейтинг сообщения: 0
Хотя с другой стороны посмотреть 4095 это и есть максимальное значение 12 АЦП. Вот он и присылает 0xFFF.
Цитата:
Если я в Configuration записываю значение 0x16C0, то он в ответ на чтение присылает 192
Если я правильно понял документацию флаг soft reset сбрасывается автоматически, вот он и возвращает значение 192. Пробуйте считывать данные, посмотрите что он будет выдавать.


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Пт дек 15, 2017 00:49:05 
Первый раз сказал Мяу!

Зарегистрирован: Ср мар 26, 2014 18:33:08
Сообщений: 38
Рейтинг сообщения: 0
Бубоник писал(а):
Пробуйте считывать данные, посмотрите что он будет выдавать.

Начал выдавать данные в нужной последовательности, но только почему то отправляет нулевые результаты, как будто напряжение равняется нулю...

Изображение

И еще один момент, он хоть и отправляет нулевые данные в нужном порядке, но только с третьего раза... То есть, первый раз смотрю в отладчике - результаты везде 0 (во всех 4 значениях), перезапускаю отладку через студию, на второй раз, результат тот же - все по нулям, второй раз перезапускаю отладку - и данные начинают приходить...


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Пт дек 15, 2017 18:06:51 
Встал на лапы

Зарегистрирован: Вс авг 16, 2015 14:08:53
Сообщений: 103
Рейтинг сообщения: 0
Че то он многовато присылает 8192. Spi протокол точно правильно работает?


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Пт дек 15, 2017 19:42:07 
Первый раз сказал Мяу!

Зарегистрирован: Ср мар 26, 2014 18:33:08
Сообщений: 38
Рейтинг сообщения: 0
Бубоник писал(а):
Че то он многовато присылает 8192. Spi протокол точно правильно работает?

Вроде все правильно, в первом варианте 0, он и в Африке ноль)))

Изображение

8192 это в двоичном формате выглядит так: 001 0 000000000000
Первые 12 бит, это собственно результат конвертации
12 бит, это ALERT, он тут не используется
13, 14, 15 биты, это канал на котом происходило измерение

Все правильно, в первом варианте результат равен нулю, так как это 0 канал, а во втором варианте измерение на 1 канале, но результат, тоже равен нулю. Если смотреть по схеме, оба канала соединены вместе...

Но там не может быть нуля, там порядка 3 вольт:

Изображение

Ну и опорное напряжение для измерения:

Изображение

PS Прошу прощения за качество фото, не удобно одной рукой держать щуп, а второй рукой фоткать с телефона


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Внешний АЦП AD7091R
СообщениеДобавлено: Сб дек 16, 2017 17:49:14 
Встал на лапы

Зарегистрирован: Вс авг 16, 2015 14:08:53
Сообщений: 103
Рейтинг сообщения: 0
Исходник можно в студию?


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



Часовой пояс: UTC + 3 часа [ Летнее время ]


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

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


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

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


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