реклама на сайте
подробности

 
 
> Вопросы по ATtiny461, как правильно работать с ADMUX?
ivainc1789
сообщение Oct 10 2007, 09:25
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807



Устройство должно измерять три аналоговых сигнала: AS1, AS2, AS3. Таймер 1 переполняется каждые 32 мкс. К факту переполнения привязан ADC с общими настройками:

Код
  

  ADCSRA = BIN(10111101); // ADC 250kHz при Fbq=8MHz, включен

  ADCSRB = BIN(00000110);


Конечно, таймер 1 переполняется чаще, чем ADC успевает выполнить одно преобразование, но это пока представляется не важным.

Обработчик прерывания по завершению преобразования выполнен так:

Код
// ADC Conversion Complete
#pragma vector = ADC_vect
__interrupt void ADC_COMPLITE(void) {
  unsigned int tmp = ADC;
  if(ADMUX == BIN(10010010)){AS1 = tmp;ADMUX = BIN(10000010);return;}
  if(ADMUX == BIN(10000010)){AS2 = tmp;ADMUX = BIN(10000011);return;}
  if(ADMUX == BIN(10000011)){AS3 = tmp;ADMUX = BIN(10010010);return;}
}


Казалось бы, все правильно: закончили одно преобразование, забрали результат, посмотрели от какого MUX оно произошло и записали в соотв глобалную переменную. Но не работает. Причина установлена, заключается в том, что ADMUX некорректно менять в данный момент в данном прерывании. Если читать только одну величину преобразования (не меняя ADMUX) ее значение получается правильным и устройство работает.

В даташите по поводу работы с мультиплексором написано на стр.147-148:



If Auto Triggering is used, the exact time of the triggering event can be indeterministic. Special

care must be taken when updating the ADMUX Register, in order to control which conversion

will be affected by the new settings.

If both ADATE and ADEN is written to one, an interrupt event can occur at any time. If the

ADMUX Register is changed in this period, the user cannot tell if the next conversion is based

on the old or the new settings. ADMUX can be safely updated in the following ways:

a. When ADATE or ADEN is cleared.

b. During conversion, minimum one ADC clock cycle after the trigger event.

c. After a conversion, before the Interrupt Flag used as trigger source is cleared.

When updating ADMUX in one of these conditions, the new settings will affect the next ADC

conversion.



Использовать вариант (a) как-то не хочется, вкл/выкл ADC на такой частоте чреват переходными процессами... Хотелось бы все же менять ADMUX в прерывании по окончанию преобразования, но как это лучше сделать и можно ли понять пока не смог...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ivainc1789
сообщение Oct 10 2007, 17:25
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807



И, наконец, окончательно установлено: в ATtiny461 переключение мультиплексора ADC с single ended input на differential input приведет к последующему ошибочному преобразованию, которое необходимо пропустить. Что-то в даташите на данную тему никаких notes не обнаружено. Для моего случая обработчик должен выглядеть так:

Код
unsigned char ADMUXval=0;
// ADC Conversion Complete
#pragma vector = ADC_vect
__interrupt void ADC_COMPLITE(void) {
  //AS2value = ADC;
switch(ADMUXval){
    case 0: break;// холостое измерение для AS2
    case 1: ADMUX = AS1set;AS2value = ADC;break;
    case 2: ADMUX = AS3set;AS1value = ADC;break;
    case 3: ADMUX = AS2set;AS3value = ADC;ADMUXval=0xFF;break;    
  }  
  ADMUXval++;
  SETBIT(ADCSRA,ADSC);// начать очередное преобразование
}
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 10 2007, 18:20
Сообщение #3


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(ivainc1789 @ Oct 10 2007, 21:25) *
И, наконец, окончательно установлено:
............................

Покажите наконец весь код ....smile.gif
Ваша проблема скорее всего заключается в использовании 2 прерываний для работы с ADC,
в итоге Вы и имеете то что переключение каналов происходит в момент когда его нельзя
переключать, Вы должны понять что преобразование НЕ начинается в момент когда
Вы выставили флаг начать преобразование и НЕ начинается синхронно от таймера в случае
если частота преобразования ADC не кратна частоте таймера.
Go to the top of the page
 
+Quote Post
ivainc1789
сообщение Oct 10 2007, 18:58
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807



Цитата(singlskv @ Oct 10 2007, 22:20) *
Покажите наконец весь код .... smile.gif
Ваша проблема скорее всего заключается в использовании 2 прерываний для работы с ADC,
в итоге Вы и имеете то что переключение каналов происходит в момент когда его нельзя
переключать, Вы должны понять что преобразование НЕ начинается в момент когда
Вы выставили флаг начать преобразование и НЕ начинается синхронно от таймера в случае
если частота преобразования ADC не кратна частоте таймера.


Весь код я привел выше. Единственное, о чем умолчал - как я определял правильно измеряется величина ADC или нет. Так как Дракона под рукой все еще пока нет использовались два метода:

1. Значение AS2value (по сути значение ADC для сигнала AS2) записывалось в EEPROM с периодом 5 сек. В некоторый момент EEPROM считывалась программатором. Если мультиплексор переключался в прерывании по оконч преобр., то считывалось из EEPROM AS2value == 0;

2. Так как программатор самопал, в истинности считывания я усомнился и для контроля инициализировал таймер1 в режим inverted fastPWM, далее значение ADC записывалось в регистр сравнения. Контроль скважности проводился на пине OC1D. При увеличении значения ADC ширина импульсов должна была уменьшаться - так и было для всех трех сигналов, если mux не переключать в прерывании по оконч. преобразования...

Заметьте, что флаг ADATE в исправленном коде не установлен. То есть ADC работает в режиме единичного преобразования но с разрешенным прерыванием по оконч. преобраз. В обработчике стартует новое преобраз. Так организовано зацикливание. Согласно даташиту, если ADATE не установлен, то ADMUX можно безопасно записывать. Но даже в этом случае, если не пропускалось "битое" измерение от AS2, AS2value == 0, а на выводе OC1D присутствовал высокий уровень...

Далее я пробовал менять записи в ADMUX в прерывании, т. е. измерял сигналы в разной последовательности. И опять: только дифференциальный сигнал AS2 всегда возвращал некорректное (нулевое) значение...


"Двойственность" прерываний легко проверить. Для этого устанавливаем в единицу какой-либо тестовый пин в начале обработчика и сбрасываем его в ноль в конце. В моем случае на осцилле наблюдались короткие прямоуголные импульсы с периодом 62 мкс.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- ivainc1789   Вопросы по ATtiny461   Oct 10 2007, 09:25
- - Qwertty   Цитата(ivainc1789 @ Oct 10 2007, 13:25) ....   Oct 10 2007, 10:23
|- - ivainc1789   Цитата(Qwertty @ Oct 10 2007, 14:23) Може...   Oct 10 2007, 11:11
|- - Qwertty   Если ADC работает в режиме одиночного преобразоани...   Oct 10 2007, 14:04
|- - ivainc1789   Цитата(Qwertty @ Oct 10 2007, 18:04) Если...   Oct 10 2007, 15:49
|- - singlskv   Цитата(ivainc1789 @ Oct 10 2007, 22:58) В...   Oct 10 2007, 19:53
- - ArtemKAD   Цитатаa. When ADATE or ADEN is cleared. b. During ...   Oct 10 2007, 19:37
- - ArtemKAD   ЦитатаЧто я не так делаю, что у меня и без этого п...   Oct 10 2007, 20:16
- - ivainc1789   Привожу полный код. Оказывается, в прерывании от A...   Oct 10 2007, 21:13
|- - singlskv   Цитата(ivainc1789 @ Oct 11 2007, 01:13) К...   Oct 11 2007, 08:35
|- - ivainc1789   Цитата(singlskv @ Oct 11 2007, 12:35) реа...   Oct 11 2007, 20:51
- - smk   ЦитатаВопрос по сути: как правильно менять настрой...   Oct 11 2007, 06:12
- - ivainc1789   Оказывается, стоило просто открыть даташит на како...   Oct 12 2007, 17:01
- - ArtemKAD   Да, кстати, еще одна "особенность" связа...   Oct 17 2007, 16:38
- - ivainc1789   Цитата(ArtemKAD @ Oct 17 2007, 20:38) Да,...   Oct 17 2007, 22:49


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 12:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01415 секунд с 7
ELECTRONIX ©2004-2016