Перейти к содержанию
    

[atmega + tlv1570] Помогите подключить

Пытаюсь подключить к ATmega16 и заставить работать внешнее АЦП TLV1570 - появились некоторые затруднения, прошу помочь разобраться

 

Интерфейс соединения с микроконтроллером - SPI вот с этим я и борюсь.

 

Исходная информация:

 

1. Схема подключения:

 

В даташите структурно это выглядит так:

tlv_to_mc_817.gif

 

На деле так:

tlv_to_mc_scheme_841.gif

2. Алгоритм работы и прошивка для МК

 

Работает данное АЦП следующим образом:

а. Передаем 16 конфигурационных бит с настройками.

б. Передаем 16 конфигурационных бит с настройками и читаем 10 бит результата (то что сконфигурировали в пункте а.)

... и т.д.

 

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

 

* Для оцифровки сигнала на канале 0, с внутренней опорой в 2.3В, мне необходима следующая комбинация битов:

[00000000 01000000] или 0x40h

 

1. Определения

#define ADC_SCLK  PORTA.0
#define ADC_SDIN  PORTA.1
#define ADC_SDOUT PORTA.2 
#define ADC_CS    PORTA.3

 

2. Функция передачи 16 бит на АЦП

 void spi_send (void) {
  char  ctr = 8;
  
  ADC_CS = 1;
  ADC_SCLK = 0;
  ADC_CS = 0;
  
  while (ctr) {
        ADC_SDIN = adc_conf_hi & 0b10000000;
        ADC_SCLK = 1;
        adc_conf_hi <<= 1; 
        ADC_SCLK = 0;
        ctr--; 
test_sdout = test_sdout + ADC_SDOUT;     
  }
  
  ctr = 8;
  
  while (ctr) {
        ADC_SDIN = adc_conf_low & 0b10000000;
        ADC_SCLK = 1;
        adc_conf_low <<= 1;
        ADC_SCLK = 0;
        ctr--;  
  } 
  
  ADC_CS = 1;
  } 
}

 

3. Основная процедура

while (1)
      { 
      adc_conf_hi = 0x00;
      adc_conf_low = 0x40;
      spi_send();  
      };

 

* Состояние ноги ADC_SDOUT (т.е. там где должны появлятся оцифрованные данные) - контролирую по УАРТУ (код посылки состояния ноги в ПК не стал приводить, дабы не загромождать(putchar(ADC_SDOUT);))

 

3. Временные диаграммы

 

Проэмулировал работу прошивки в VMLAB - вроде всё как в даташите:

 

Диаграмма из ДШ:

tlv_to_mc_diagram_981.gif

 

Диаграмма из VMLAB (передача [00000000 01000000]):

vmlab_diagram_519.jpg

 

* насколько я понял чтение данных происходит по спаду.

 

Признаки жизни

При передачи 16 бит конфига: [00000000 01000000] - я говорю АЦП что бы использовался канал #0. Тогда напряжение, подаваемое на CH0 отобразится на ноге AIN - т.е на аналоговом входе. Путем изменения номеров каналов, и подачи постоянного напряжения туда - убедился в том что АЦП распознает конфигурационные 16 бит, и правильно выбирает канал для оцифровки. => оно живое, оно работает, просто вредничает и не хочет оцифровывать мой сигнал

 

Перепробывал уже почти всё, на выходе (ADC_SDOUT) всегда 0 оцифрованных данных. Может кто советом поможет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

while (ctr) {

ADC_SDIN = adc_conf_hi & 0b10000000;

ADC_SCLK = 1;

adc_conf_hi <<= 1;

ADC_SCLK = 0;

ctr--;

test_sdout = test_sdout + ADC_SDOUT;

}

 

 

мне кажется или нет? но ты вываливаешь старшим битом байта вперед, а судя по даташиту надо младшим

 

сделай СПИ аппаратным. оно за тем и сделано читоб таких костылей, что выше, небыло

Изменено пользователем yod

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мне кажется или нет? но ты вываливаешь старшим битом байта вперед, а судя по даташиту надо младшим

По ДШ (по крайней мере на приведенной диаграмме).

DI15 -> SCLK1 (старший - первым)

DI1 -> SCLK15

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Переделал на аппаратный SPI и оно заработало. Есть кое какие глюки - но пока работаю над этим, если что не получится - обязательно спрошу.

 

Пока такой вопрос:

 

По даташиту написано что ацп - однополярный, что я могу подавать сигнал в пределах от 0V - AVDD (0-5В)

Мне нужно оцифровать переменный сигнал (синус) - как быть в этом случае? Т.е я просто подаю на выход как обычно, главное следить чтобы аплитуда была не более 2.5В ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ADC_SDIN = adc_conf_hi & 0b10000000;

 

Может, так:

 

ADC_SDIN = (adc_conf_hi & 0b10000000) != 0;

 

Или присвоение единицы в случае не-нуля для битовых полей автоматически в Вашем компиляторе делается?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне нужно оцифровать переменный сигнал (синус) - как быть в этом случае

Смотря что Вы имеете ввиду под словом "переменный".

. Если это сигнал переменного тока (т.е. каждых пол-периода меняется направление тока), то нельзя. В этом случае сигнал нужно "поднимать", т.е. вносить в него постоянную составляющую, равную 1/2 от AVDD (2.5В). И следить. чтобы амплитуда входного сигнала (до "поднятия") не превышала 2,5В

. Если меняется только амплитуда сигнала (но не направление тока/полярность), т.е. сигнал однополярный, то можно.

главное следить чтобы аплитуда была не более 2.5В ?

Для однополярного синуса, "прижатого" к 0, амплитуда равна размаху сигнала, поэтому - не более 5В

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...