|
ADC+MUX, засада |
|
|
|
Jan 24 2007, 22:15
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Проблема такая ,пытаюсь мерять 2 напряжения с помощью ADC ,попеременно переключая входы в прерывании от АЦП ,в результате у меня получаемые значения как будто я меряю только на одном входе и как правило того входа АЦП ,которое я инициализирую первым ,хотя бывают "глюки-исключения"  MUX меняю точно ,пробовал отключать и заново запускать АЦП ,что битами ,что полностью регистрами-результат одинаков,похоже есть какой то ньюанс при переключении АЦП,но какой не знаю  Вот такие лыжи на асфальте ,и не могу понять в чем дело.
|
|
|
|
|
Jan 24 2007, 23:13
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Привет Богдан! Было бы приятно тебе помочь. Привожу пример на любимом твоём АСМе. Код ; Сменить канал АЦП izm1: mov wpl,chan andi wpl,7 ; выделить номер канала subi wpl,-2 ; начать с канала 2 ori wpl,kadmux .if chip == 88 sts admux,wpl; включить новый канал .else out admux,wpl; включить новый канал .endif ....... ; Инициализация
.if chip == 88 .equ kadcsra = exp2(aden)+exp2(adsc)+exp2(adate)+exp2(adps1)+exp2(adps0) .else .equ kadcsra = exp2(aden)+exp2(adsc)+exp2(adfr)+exp2(adps1)+exp2(adps0) .endif ; Для внутреннего АЦП ;.equ kadmux = exp2(refs1)+exp2(refs0)+exp2(adlar) ; Для внешнего АЦП .equ kadmux = exp2(adlar)
ldi chan,0 ldi wl,kadcsra+exp2(adif) .if chip == 88 sts adcsra,wl; сбросить флаг завершения преобразования .else out adcsr,wl; сбросить флаг завершения преобразования .endif mov wl,chan subi wl,-2 ; начать с канала 2 ori wl,kadmux .if chip == 88 sts admux,wpl; включить новый канал .else out admux,wpl; включить новый канал .endif Я, в данном случае использовал автоматический режим. Вожможная причина твоей проблемы. Я измеряю в прерывании от таймера. Интервал выбран по времени измерения. Я сначала измеряю, а потом переключаю канал. То есть должно пройти время от переключения до измерения. С уважением.
|
|
|
|
|
Jan 25 2007, 00:08
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Цитата(Dopler @ Jan 24 2007, 22:47)  Не надо после Mux ничего дергать, все должно работать и так. На какой частоте работаете? МК 1МГц Камень "нулевый" Клок 125кГц ,тоесть все как книжка пишет. В симуляторе тоже песня. Но по факту бздык. ADEN и дергал и не дергал ,и режимы другие пробовал,и регистры по разному читал ,короче как угодно  По идее по прерыванию от АЦП ,в регистрах уже должны быть необходимые данные от нужного входа. Ок! Всем спасибо за советы ,завтра на работе попробую Ваши предложения. 1 Сделаю по прерыванию от таймера. 2 Сделаю по прерыванию от АЦП ,но результат буду снимать после 2-3 выборки после переключения. 3 Если не поможет поставлю камень в уже готовый проект на проверку,там точно все переключается,но только "вручную". Похоже действительно ,что то со временем на переключение,попробую разобраться и доложить результат
|
|
|
|
|
Jan 25 2007, 21:38
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Kovrov ,респект,дали правильное направление в поиске трабла.  Сделал по прерыванию от АЦП ,так как уже были наброски. Вот что выяснилось ,при переключении (вне зависимости дергаем ADEN или нет) ,АЦП делает 1 холостой ход ,при этом генерируя прерывание. А при включеном бите ADATE нужно пропустить 2 цикла конверсии,и после этого уже считывать результат. Я знал что на переинациализацию нужно дополнительное время ,но не думал что будут генерироваться прерывания. В принципе проблема решена ,всем спасибо за советы.
|
|
|
|
|
Jan 25 2007, 22:56
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(bodja74 @ Jan 25 2007, 21:38)  Kovrov ,респект,дали правильное направление в поиске трабла.  Сделал по прерыванию от АЦП ,так как уже были наброски. Вот что выяснилось ,при переключении (вне зависимости дергаем ADEN или нет) ,АЦП делает 1 холостой ход ,при этом генерируя прерывание. А при включеном бите ADATE нужно пропустить 2 цикла конверсии,и после этого уже считывать результат. Я знал что на переинациализацию нужно дополнительное время ,но не думал что будут генерироваться прерывания. В принципе проблема решена ,всем спасибо за советы.  bodja74А Вы запускаете АЦП в режиме Single Conversion Mode или Free Running ? Если в Free Running, то Вы просто не вовремя меняеете ADMUX, его нельзя менять в том же прерывании где считывали последний результат В режиме Free Running новое преобразование начинается еще до того как Вы попали в прерывание и если Вы в прерывании меняете ADMUX пока не прошло 1,5 ADC clock cycles то следующий результат будет просто мусором Если Вам нужно после каждого результата менять канал ADC и режим Free Running, то тогда после считывания результата нужно подождать > 1,5 ADC clock cycles и до наступления нового прерывания успеть сменить ADMUX Удачи
|
|
|
|
|
Jan 26 2007, 00:35
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Цитата(singlskv @ Jan 25 2007, 22:56)  bodja74 А Вы запускаете АЦП в режиме Single Conversion Mode или Free Running ?
Если в Free Running, то Вы просто не вовремя меняеете ADMUX, его нельзя менять в том же прерывании где считывали последний результат В режиме Free Running новое преобразование начинается еще до того как Вы попали в прерывание и если Вы в прерывании меняете ADMUX пока не прошло 1,5 ADC clock cycles то следующий результат будет просто мусором Если Вам нужно после каждого результата менять канал ADC и режим Free Running, то тогда после считывания результата нужно подождать > 1,5 ADC clock cycles и до наступления нового прерывания успеть сменить ADMUX Удачи У меня действительно режим Free Running ,но это не значит ,что это режим непрерывного преобразования ,без бита ADATE - его не будет . Я уже писал выше ,что при установке ADATE я получал правильный результат на третьем прерывании. В моем же случае АЦП уже остановленно при входе в прерывание , читаю результат ,меняю MUX и при выходе запускаю АЦП битом ADSC и получаю правильный результат на втором прерывании. В данном случае я немогу точно сказать ,сколько времени нужно для полноценного переключения АЦП так как больше интересовало ,на каком прерывании я получу нужный результат.
|
|
|
|
|
Sep 25 2009, 03:55
|

Местный
  
Группа: Свой
Сообщений: 253
Регистрация: 28-12-07
Из: Украина г. Первомайск
Пользователь №: 33 716

|
На ATmega8 делал вольтметр + амперметр CODE //ADC_INIT ldi tmp,0x87 // Bits 2 1 0 ADC PRESCALLER out ADCSRA, tmp //
main: rcall wait ldi tmp,0xC2 // ADC_2 out ADMUX,tmp // rcall ADC_1 // ;rcall decod_V //
ldi tmp,0xC1 // ADC_1 out ADMUX,tmp // rcall ADC_1 // ;rcall decod_A // sei rjmp main //
ADC_1: // sbi ADCSRA,6 // ADC_NV: // sbic ADCSRA,6 // rjmp ADC_NV // in yl, ADCL // in yh, ADCH // ret //
Может не в тему , но работает без нареканий.
|
|
|
|
|
Sep 25 2009, 06:40
|
Участник

Группа: Участник
Сообщений: 20
Регистрация: 12-01-09
Из: Донецк, Украина
Пользователь №: 43 218

|
Вот мой кусок кода на С, работает как надо: Код for (i=0; i<6; i++) { ADMUX&=0b11110000; ADMUX|=i; ADCSRA|=0x40; while(!(ADCSRA & (1<<ADIF))); ADCSRA|=(1<<ADIF); adc_data=ADCW; ..... };
Сообщение отредактировал troy97 - Sep 25 2009, 06:42
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|