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

ATtiny25 - АЦП в биполярном режиме.

Для измерения втекающего/вытекающего тока была выбрана схема согласно вложенного файла. Rш - измерительный шунт, R и C - интегрирующее звено с частотой среза < 4 кГц.

Был выбран дифференциальный канал (MUX3...0 = 0111) с предусилением 20x в биполярном режиме (BIN = 1). Опорное напряжение Vref = 1,1В.

 

Согласно Атмелу ни на прямом, ни на инверсном входах напряжение не должно быть ниже Vgnd. Т.е., при измерении двунаправленного тока оба входа должны бы иметь определенную подтяжку относительно земли, чтобы ни при каких условиях не возникало ситуации, когда на одном из них появляется отрицательное напряжение относительно земли.

 

В моем случае это несколько неудобно. Наиболее подходящим для схемотехники был бы вариант, когда один из концов шунта сидит на земле. Конечно, можно было бы в разрыв между инверсным входом и землей вставить резистор с сопротивлением R и оба входа подтянуть к питанию дополнительными резисторами, чтобы обеспечить достаточное смещение (при Vref = 1,1В это >55мВ), но по определенным соображениям этого делать бы не хотелось.

 

Но так ли обязательна подтяжка? Для моего случая в контроллере перед АЦП стоит дифференциальный предусилитель на 20x. Многие операционники и дифференциальные усилители с однополярным питанием вполне неплохо себя чувствуют при небольших отрицательных напряжениях на их входах. В моем случае это напряжение не будет превосходить -55мВ.

 

Специально провел эксперимент, выбрав опорное в 2,56В, т.е. дифференциальное напряжение доходит до +/- 128мВ на весь диапазон. Проверил линейность АЦП при помощи В7-40. В обе стороны она в пределах нормы. Симметрия соблюдалась не смотря на то, что для отрицательных напряжений на прямом входе был минус относительно земли. Если АЦП ведет себя вполне адекватно при минус 128мВ, то при минус 55мВ (для моего случая) - должен бы тем более.

 

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

post-279-1303735570_thumb.png

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


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

Если АЦП ведет себя вполне адекватно при минус 128мВ, то при минус 55мВ (для моего случая) - должен бы тем более.

не так давно обсуждалось, что отрицательное напряжение подавать можно, важно ограничить ток через защитный диод (помнится, что советовали не превышать 2мА)

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


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

не так давно обсуждалось, что отрицательное напряжение подавать можно, важно ограничить ток через защитный диод (помнится, что советовали не превышать 2мА)
Дайте пожалуйста ссылочку на это обсуждение.

Эта http://electronix.ru/forum/index.php?showtopic=89501&hl= не она?

 

 

 

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


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

Дайте пожалуйста ссылочку на это обсуждение.

Эта http://electronix.ru/forum/index.php?showtopic=89501&hl= не она?

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

 

соврал... контроллер tiny25, дифференциальный режим с усилением, ИОН 1,1В - т.е. на входе те же 55мВ

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

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


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

Да, уж... Обнаружились абсолютно непонятные грабли. Опишу ниже.

 

Итак, контроллер ATtiny25, 5В питание, 1Мгц от внутреннего RC (с предделением на 8), АЦП - дифференциальный канал, 125кГц, MUX3...0 = 0111, усиление 20, (+)ADC2, (-)ADC3. Выбран биполярный режим (BIN = 1), оба входа подключены непосредственно к земле. При внутреннем опорном 2,56В показывает +2...3, что соответствует приблизительно +2,5...3,8мВ смещения. При опорном 1,1В показывает +5...7, что соответствует +2,7...3,8мВ смещения. Вроде как вполне согласуется для разых опорных.

 

Было бы неплохо учесть это смещение. Для этого есть возможность - MUX3...0 = 0101, оба входа усилителя внутри контроллера коммутируются на ADC2. Т.е. таким образом можно компенсировать смещение при измерении, вычитая это значение. Хорошо, выбираем MUX = 0101, смотрим отсчеты и... офигеваем. Вместо положенных +5...7 при 1,1В опоры имеем -29...35, при 2,56В опоры получаем соответственно -11...12. Совершенная чертовщина.

 

Во избежание лишних вопросов - пуллапов нет, утечек на плате нет, при коммутации каналов - дополнительные задержки 0,1 сек вставлены, без разницы, как определяется завершение преобразования, то ли со sleep и прерыванием, то ли по опросу ADIF, все равно грабли одни и те же.

 

Мало того, если выбираю усиление 1x, (MUX = 0110) и (MUX = 0100), показывает уже смещение -11 и -17 для 2,56В, -23 и -31 для 1,1В соответственно.

 

Пробовал давать на оба соединенных вместе входа через делитель положительное смещение порядка 0,5В для всех вышеприведенных ситуаций - картина совершенно не меняется.

 

Вот такие пироги... :wacko:

 

PS: Перепаял контроллер, поставил другой экземпляр. Цифры несколько поменялись, но все равно фигня. Для 1,1В опоры замкнутые снаружи входы дают смещение +11...13, замкнутые внутри контроллера дают -19...23. Ерунда...

 

Может кто даст подсказку, почему АЦП так себя ведет, возможно есть моя ошибка, в чем она заключается?

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


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

Вобщем, с измерением смещения какие-то не совсем понятные грабли. Но, вроде как можно обойтись и без этого. Проверял смещение на нескольких различных образцах tiny25 и tiny45, оно небольшое, мало изменяется от температуры, его можно учесть один раз в процессе калибровки, а если учесть то, что достаточно 8 бит, то все вполне укладывается в предъявляемые требования.

 

Возникла иная проблема. Вот фрагмент тестовой программы (IAR). Задействовано прерывание от АЦП для пробуждения по завершению измерения и прерывание по сравнению от Таймера1 для побуждения и проведения измерения. Интервалы 0,25 сек.

...
#pragma vector = TIM1_COMPA_vect
__interrupt void tim1_compa(void)
{
}
...
#pragma vector = ADC_vect
__interrupt void adc(void)
{
}
...
  for(;;) // Главный цикл.
  {
    int I,U;
    ADCSRB |= (1<<BIN); // Биполярный режим
    ADMUX = I_ADC; // Ток
//  __delay_cycles(250000);
// ADCSRA &= (0<<ADEN);
    __sleep(); // спать до прерывания от таймера (0,25сек)
// ADCSRA |= (1<<ADEN);
    MCUCR = Noise_Reduction_Mode;
    ADCSRA |= (1<<ADSC); // Start_Conv;
    __sleep(); // спать до прерывания от АЦП
    MCUCR = Idle_Mode;
    I = ADC;
    Int_LED(I/64); // Вывод на СИД
    ADCSRB &= (0<<BIN); // Униполярный режим
    ADMUX = U_ADC; // Напряжение
//  __delay_cycles(250000);
// ADCSRA &= (0<<ADEN);
    __sleep(); // спать до прерывания от таймера (0,25сек)
// ADCSRA |= (1<<ADEN);
    MCUCR = Noise_Reduction_Mode;
    ADCSRA |= (1<<ADSC); // Start_Conv;
    __sleep(); // спать до прерывания от АЦП
    MCUCR = Idle_Mode;
    U = ADC;
    Int_LED(U); // Вывод на СИД
  }

 

В этом фрагменте заремлены программные задержки. Если их разремить и заремить рядом стоящие __sleep, все работает корректно. Если разремить до и после __sleep запрет и разрешение прерывания от АЦП, пробуждение от таймера происходит нормально. А вот в представленном выше виде происходит досрочное пробуждение от АЦП, хотя по логике его быть не должно. Т.е. вместо таймера пробуждает АЦП, если на это время его не запрещать совсем.

 

И с чего бы это АЦП пробуждать, если цикл измерения уже полностью отработан до того?

Может кто даст объяснение, почему такое может происходить?

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


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

С истинными причинами проблемы разобрался, тема закрыта.

Всем, кто помог, огромное спасибо.

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


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

Огласили бы эти истинные причины, интересно же.

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


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

Огласили бы эти истинные причины, интересно же.

Хорошо, очень кратко.

 

1) При коммутации аналоговых цепей внутри контроллера переходные процессы устаканиваются за определенное время (по экспериментальной оценке вплоть до 50...100 мкс), поэтому после включения АЦП, переключения опоры, переключения каналов нужно дать временную задержку перед стартом измерения. В противном случае результат будет искажен. Из-за отсутствия подробного описания атмеловского АЦП и предусилителя, сложно точно оценить время устаканивания, поэтому задержку лучше брать с запасом.

 

2) Поскольку никогда прежде не использовал спячку в режиме Noise Reduction Mode во время измерений и вообще режим сна при включенном АЦП, не сталкивался с тем фактом, что при включенном АЦП сама команда sleep запускает цикл измерений. В дейташите это очень вскользь упомянуто (как пишутся дейташиты, это еще та история, в свое время бытовало выражение - инструкции пишутся для тех, кто их уже досконально знает). Естественно, если разрешено прерывание по концу цикла измерения, контроллер просыпается по нему, а не по тому прерыванию, на пробуждение от которого было расчитано.

Выхода два - либо перед спячкой с пробуждением по таймеру (как в моем случае) выключать АЦП, либо запрещать от него прерывание, а после спячки снова включать АЦП, либо разрешать прерывание, соответственно. Первое лучше с точки зрения уменьшения энергопотребления, но нужно давать дополнительную задержку, второе позволяет стартовать АЦП без задержки. Тут уж есть выбор, что важнее.

 

PS: В конце предыдущего сообщения вынес благодарность самому себе. :)

 

PPS: Хотя есть указание в документации, что ни на прямом, ни на инверсном входе напряжение не должно опускаться ниже уровня GND, все же при измерении с предусилением в реале можно давать небольшой минус на вход. Когда отрицательное напряжение на входе находится на начальном участке ВАХ входного защитного диода, т.е. он еще сколь-либо заметно не открыт, предусилитель ведет себя вполне пристойно и не ухудшает линейность АЦП. По крайней мере при минус 128 мВ ничего неприличного не наблюдалось, а уж для минус 55 мВ - тем паче. Проверялось на нескольких образцах ATtiny25, 45, 261, 461 с одновременным контролем по В7-40.

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


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

Итак, контроллер ATtiny25, 5В питание, 1Мгц от внутреннего RC (с предделением на 8), АЦП - дифференциальный канал, 125кГц, MUX3...0 = 0111, усиление 20, (+)ADC2, (-)ADC3. Выбран биполярный режим (BIN = 1), оба входа подключены непосредственно к земле. При внутреннем опорном 2,56В показывает +2...3, что соответствует приблизительно +2,5...3,8мВ смещения. При опорном 1,1В показывает +5...7, что соответствует +2,7...3,8мВ смещения. Вроде как вполне согласуется для разных опорных

А как вы так считали, не учитывая Ку? Ку=20, тогда смещение 0.5..0.75мВ в обоих случаях

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


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

1) При коммутации аналоговых цепей внутри контроллера переходные процессы устаканиваются за определенное время (по экспериментальной оценке вплоть до 50...100 мкс), поэтому после включения АЦП, переключения опоры, переключения каналов нужно дать временную задержку перед стартом измерения. В противном случае результат будет искажен. Из-за отсутствия подробного описания атмеловского АЦП и предусилителя, сложно точно оценить время устаканивания, поэтому задержку лучше брать с запасом.

в книжке Евстифеева написано: "...при смене канала с дифференциальным входом первое измерение следует производить не ранее, чем через 125мкс после выборки канала. Указанное время требуется для установления значения коэффициента усиления предусилителя..."

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


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

А как вы так считали, не учитывая Ку? Ку=20, тогда смещение 0.5..0.75мВ в обоих случаях

Да, конечно, именно эти значения, при написании там у меня вкралась досадная ошибка. Любая перепроверка ее выявила бы. Собственно говоря, именно эти значения потом и использовал. Но ввиду особенностей движка форума в том посте исправить ошибку не представляется возможным. :(

 

 

 

в книжке Евстифеева написано: "...при смене канала с дифференциальным входом первое измерение следует производить не ранее, чем через 125мкс после выборки канала. Указанное время требуется для установления значения коэффициента усиления предусилителя..."

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

Вот пример основного фрагмента тестовой программы, где все утрясено, попеременно через 1/8 сек измеряются ток и напряжение:

 

int Get_ADC(char mode) // Подпрограмма цикла измерения
{
  ADMUX = mode;
  MCUCR = 0xE0; // Idle Sleep
  ADCSRA &= 0xF7; // Запрет прерывания от АЦП
  __sleep(); // спать до прерывания от таймера (период - 0,125сек)
  ADCSRA |= 0x08; // Разрешение прерывания от АЦП
  MCUCR = 0xE8; //ADC Sleep
  __sleep(); // запустить АЦП и спать до прерывания
  return ADC;
}

  for(;;) // Главный цикл.
  {
    ADCSRB |= 0x80; // Биполярный дифференциальный режим с предусилением 20
    int I = Get_ADC(0xB7); // Ток
    Int_LED(I/64); // Вывод на СИД
    ADCSRB &= 0x7F; // Униполярный одновходовый режим
    int U = Get_ADC(0x91); // Напряжение
    Int_LED(U); // Вывод на СИД
   };

Все коммутации в АЦП и предусилителе производятся задолго до цикла измерения.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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