ЦАП+Mega

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Доброго времени суток!
Спрашивал на многих форумах, но мне либо ни где не отвечали, либо отправляли в гугл. Вы моя последняя надежда.
Есть Arduino Mega, ЦАП - AD420AN, ОУ - LM358.

Суть задачи:
Подключить ЦАП к Arduino через SPI и очень-очень плавно повышать напряжение. 

Что сделал:
1. Собрал все это вкучу по даташиту на ЦАП(http://www.analog.com/static/imported-files/data_sheets/AD420.pdf) Схема на 10-ой странице под заголовком VOLTAGE-MODE OUTPUT. 6 лапу ЦАПа(Clear) кинул на +5В, 7 лапу(Lath) на 53 пин ардуино, 8 лапу(Clock) на 52 и 9(Data in) на 51 пин.
2. Написал скетч (но он почему-то не работает):

#include <SPI.h>

void setup()
{
  pinMode(SS, OUTPUT);
  SPI.begin();
  digitalWrite(SS,LOW);
}

void setLevel(int level)
{
  digitalWrite(SS, LOW);
  SPI.transfer(level);
  digitalWrite(SS, HIGH);
}

void loop()
{
  for(int i=0; i<65535;i+=5)
  {
    setLevel(i);
    delay(5);
  }
  delay(1000);
}

Вопросы:
1. Правильно ли я подключил ЦАП к Arduino.
2. Можете привести пример кода для управления ЦАПом?

maksim
Offline
Зарегистрирован: 12.02.2012

Не вдаваясь в подробности даташита, вопрос такой на выходе ЦАП что нибудь получаете?

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

maksim пишет:

Не вдаваясь в подробности даташита, вопрос такой на выходе ЦАП что нибудь получаете?

Постоянно около 1,2 вольта. 
Но там не сразу с ЦАПа, а через ОУ.

maksim
Offline
Зарегистрирован: 12.02.2012

Первое что вам нужно сделать это прочитать про типы данных особенно про intunsigned int и byte, зетем обязательно почитать про SPI.

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

maksim пишет:

Первое что вам нужно сделать это прочитать про типы данных особенно про intunsigned int и byte, зетем обязательно почитать про SPI.

Про int, это да, напортачил. Переправил в программе на unsigned int, но это так и не спасло.
По поводу раздела SPI - я его читал, все что я из него понял, есть в моем коде.
Мне пока сложно с ним разобраться, поэтому и прошу помочь с кодом.

maksim
Offline
Зарегистрирован: 12.02.2012

 Затем подробнее изучить даташит и воспользовавшись функциями lowByte() и highByte() продвинуться ближе к решению данной задачи.

maksim
Offline
Зарегистрирован: 12.02.2012

AlexSMGr54 пишет:

maksim пишет:

Первое что вам нужно сделать это прочитать про типы данных особенно про intunsigned int и byte, зетем обязательно почитать про SPI.

Про int, это да, напортачил. Переправил в программе на unsigned int, но это так и не спасло.
По поводу раздела SPI - я его читал, все что я из него понял, есть в моем коде.
Мне пока сложно с ним разобраться, поэтому и прошу помочь с кодом.

Плохо значит читали, потому как SPI.transfer() отправляет/принимает данные типа byte, а вам нужно отправить unsigned int - это два байта.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

 

7 строка. Непонятно зачем включать разрешение SS (устанавливается в LOW), не вдаваясь в подробности - это выглядит странно.

 

void writeShiftRegister16(int ss_pin, uint16_t value)
{
  digitalWrite(ss_pin, LOW);
  /* Фокус вот в чём: сначала шлём старший байт */
  SPI.transfer(highByte(value));
  /* А потом младший */
  SPI.transfer(lowByte(value));
  digitalWrite(ss_pin, HIGH);
}

Это кусок кода отсюда: http://nnm.ru/blogs/e-troll/arduino-spi/

 

maksim
Offline
Зарегистрирован: 12.02.2012

В даташите есть пример кода на асме, так вот все то что после  ;  это комментарии.
Вот вам комментарии по которым можно написать код на СИ:

// DABL INTRPTS, SPI IS MASTER & ON  
// CPOL = 0, CPHA = 0, 1MHZ BAUDRATE  
// INFINITE LOOP 
// DRIVE SS (LATCH) LOW 
// SEND MS-BYTE TO SPI DATA REG  
// SEND LS-BYTE TO SPI DATA REG  
// DRIVE SS HIGH TO LATCH DATA 
AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Спасибо, что отозвались, но мне ни один из ваших вариантов не помог, увы.
На одном из американских сайтов нашел пример кода для работы с ЦАПом:

void writeValue(uint16_t value)
{
  digitalWrite(LATCH,LOW);
  digitalWrite(CLOCK,LOW);

  for(int i=15;i>=0;i--)
{
    digitalWrite(DATA,((value&(1<<i)))>>i);
    delayMicroseconds(HALF_CLOCK_PERIOD);
    digitalWrite(CLOCK,HIGH);
    delayMicroseconds(HALF_CLOCK_PERIOD);
    digitalWrite(CLOCK,LOW);
  }

  digitalWrite(DATA,LOW);
  digitalWrite(CLOCK,LOW);
  digitalWrite(LATCH,HIGH);
  delayMicroseconds(HALF_CLOCK_PERIOD);
  digitalWrite(LATCH,LOW);
 
}

Устройство с этим кодом у меня работает. Я так понимаю, тут число передается по 1 биту. Но я не совсем понимаю, что именно, точнее почему именно так, тут происходит.
Не могли бы вы помочь мне разобраться с этим кодом?

maksim
Offline
Зарегистрирован: 12.02.2012

В этом примере интерфейс реализован програмно.

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

maksim пишет:

В этом примере интерфейс реализован програмно.

Т.е. весь код, который я привел можно заменить этим:

void writeShiftRegister16(int ss_pin, uint16_t value)
{
  digitalWrite(ss_pin, LOW);
  /* Фокус вот в чём: сначала шлём старший байт */
  SPI.transfer(highByte(value));
  /* А потом младший */
  SPI.transfer(lowByte(
  digitalWrite(ss_pin, HIGH);
}

 

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Всем спасибо!
Разобрался со всеми кодами, все из приведенных выше работают.

Теперь умею плавно поднимать напряжение от 0 до +5В.

Ещё вопрос. Чтобы изменять напряжение от -5 до 0В нужно переделывать плату или это можно решить программно?

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

up

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

А почитать в даташите 10 страницу "VOLTAGE-MODE OUTPUT" религия не позволяет? В чем проблема? Более того там постоянно  твердят о выходных напряжениях.

 

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Понимаете, 10 страницу даташита я уже до дыр истер и я не слепой, раздел "VOLTAGE-MODE OUTPUT" я читал, религия мне не запрещает читать.
Проблема, уважаемый, в том, что если я собираю схему вточности, как указано в вышеупомянутом разделе, прибор не выдает +\-5В, он выдает даже больше чем должен, от приблизительно 0,6 до 12,5В, что я нормальным не считаю.

Собственно поэтому я вопрос и задал, решается ли моя проблема программно или же нужно что-то делать с самой схемой

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Вот теперь вопрос понятен, почему не работает режим +-5 В по схеме с 10 страницы даташита.

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Я разобрался, как можно сделать отрицательно напряжение, но мне нужна помощь, т.к. своими силами я тут не справляюсь.
Чтобы изменять напряжение от 0 до 5В я пользуюсь следующей схемой:

На выходе ОУ IC2A мы будем получять такое напряжение, которое подаем на 15 лапу (Reference Input),
Сейчас я получаю напряжение от 0 до 5В, т.к. 14 лапа - это +5В  замкнута с 15, т.е мы подаем +5В. Значит если подать на 15 лапу -5В, то я должен получать напряжение от 0 до -5В.

Собственно вопрос - как это можно сделать?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

ИМНО, чтобы получить двуполярное напряжение, нужно выходной усилитель включить по дифференциальной схеме, подав на инвертирующий вход подпорку в 2,5 В и коэффициент усиления 2. Тогда 0 на 17 ноге будет давать на выходе -5В, а +5В (на17 ноге) - даст на выходе те же +5В. Если же всё питание однополярное, то нужно брать виртуальную землю не с земли схемы, а с другой точки.

Кстати, если добился на выходе от 0 до 12 В, то можно померять напряжение между REF OUT и выходом операционника, по моему там и получится от -5В до +5В, т.е. REF OUT и есть вритуальная земля.

Могу ошибаться, давно отошел от схемотехники.

UPD: Да, я рассматривал схему включения с 10 страницы, а не та, что выше.