[AVR] wejscia przetwornika ADC

Nov 19, 2008 11 Replies

Witam Probkwany jest sygnal na wejsciach ADC0 (pin 0 portu A) i ADC3 (pin 3 portu A) Przetwornik ma ustawiony prescaler na 128 i jest wyzwalany od timera 0 co



2,5ms. Wejcia mam ustawione Po konwersji ma nastepowac zmiana kanalu wejsciowego z z ADC0 na ADC3 potem ADC3 na ADC0 itd Niestety poprawnie dziala tylko odczyt z portu ADC0 czyli czesc programu w sekcji "else". Z ADC3 dostaje jakies losowe wartosci w okolocy 0;

Co robie nie tak? gdzie robie blad?


PORTA &=~_BV(PA3); // wejscie ADC3 DDRA &=~_BV(PA3); PORTA &=~_BV(PA0); // wejscie ADC0 DDRA &=~_BV(PA0);



.....



ISR(ADC_vect) {



if(((ADMUX&0x07)==0x03)) // przeprowadzany byl pomiar pradu { //pomiar pradu (na oporniku) i=ADC; ADMUX&=~0x07; // nastepne probkowanie - napiecie


} else // przeprowadzany byl pomiar napiecia {


v=ADC; ADMUX|=0x03; // nastepne probkowanie - prad



} ADCSRA|=_BV(ADIF); }



roxy pisze: > (...)

1) Działasz w trybie free running? 2) Mierzyłeś miernikiem czy aby napewno nie ma tam zerowej wartości?

U¿ytkownik "Marcin" snipped-for-privacy@dyziek86.TEGO.NIE.MA> napisa³ w wiadomo¶ci news:gg1agb$t42$ snipped-for-privacy@nemesis.news.neostrada.pl...

ad1) tak. kolejne konwersje sa wyzwalane po przepelnieniu timer'a0 czyli co

2,5ms. Wewnatrz funkcji ISR od Timer0 jest tylko zaladowanie licznika nawa wartoscia TCNT0=100;

ad 2) mierzylem. jest OK

"roxy" snipped-for-privacy@o2.pl schrieb

Dlaczego po prostu nie zapisujesz 0 i 3 do ADMUX? Czy 5 najstarszych bitow jest gdzies inicjowane?

hej

"mw158979" snipped-for-privacy@tam.pl schrieb

Dobrze, wiem juz dlaczego. Tam sa jeszcze bity od referencji. Niemniej jak to jest inicjowane? Co to za procek w ogole?

hej

To już jasne (chyba). Wyniki są OK. Każdy wzmacniacz ma offset. Wzmocnienie jest duże i ten offset jest wzmacniany. W kanale ADC0 offset wychodzi poza zakres proporcjonalności i masz złudzenie o poprawności otrzymywanego wyniku przetwarzania. Wyjaśnienie masz na stronie 214 w dokumencie doc2466.pdf Proponuję podać na wejście znane napięcie i skonfrontować to z wynikami. K.

U¿ytkownik "John Smith" snipped-for-privacy@buziaczek.pl napisa³ w wiadomo¶ci news:gg1k17$9ij$1@217.76.112.12...

To chyba nie jest powodem. Na wejscia ADC mam podlaczone sygnaly z potencjometrow na ktorych jest napiecie okolo 3V na ADC0 i okolo 2V na ADC3. Nap. ref. 5V. Zaznaczam ze nie mierze sygnalu roznicowego tylko kazdy kanal w odniesieniu do GND. Na wejsciu ADC3 tam gdzie ma byc wartosc 2V z przetwornika otrzymuje "lataj±ce" 0. Jutro sprobuje na jakims innym wejsciu co sie bedzie dziac.

Użytkownik roxy napisał:

Coś mi się tak po głowie kołacze... czy w trybie FR wolno zmieniać wejście multipleksera "w biegu" ? Niech Kolega na próbę ustawi tryb pojedynczej konwersji i na końcu obsługi przerwania "ręcznie" wyzwoli następną konwersję ustawiając bit ADSC.

Pozdrawiam Grzegorz

Wolno zmieniac w biegu, z tym, ze ta zmiana bedzie obowiazywala przy nastepnej konwersji. Czyli wynik bedzie opozniony o jedna pozycje w stosunku do zawartosci rejestru ADMUX.

Musisz czytac ADCL i ADCH, w takiej dokladnie kolejnosci. Nie wiem czy w glibc juz cos porobili, zeby odpowiednio to czytalo caly 16-bitowy rejestr.

Tu masz problem. Wpisanie nowej wartosci multiplexera w trybie FR odniesie skutek nie przy nastepnym przerwaniu tylko przy jeszcze nastepnym. W momencie wpisu do tego rejestru idzie juz kolejna konwersja.

To nie jest potrzebne. Procesor sam to zrobi. Ale mam wrazenie, ze niepotrzebnie stosujesz tryb FR, on jest pomyslany dla samplowania z jednego kanalu, bez zmiany multiplexera. Jesli zmieniasz multiplexer to ustaw single conversion i start conversion w procedurze obslug przerwania.

Uzytkownik "T.M.F." snipped-for-privacy@nospam.mp.pl> napisal w wiadomosci news:gg25vd$5fb$ snipped-for-privacy@news.onet.pl...

Tak wystarczy czytac. Kompilator prawidlowo pobiera dana z rejestru. i=ADC;

Problem rozwiazany. Problemem byla zmienna "i" zadeklarowane raz jako zmienne globalna oraz w petli main jako zmienna iteracyjna . przepraszam za zamieszanie ale przede wszystki dziekuje za pomoc i udzial w dyskusji. Ponizej zamieszczam poprawnie dzialajace listingi funkcji.

volatile unsigned int v,i,b,c;

ADCSRA|=_BV(ADEN); // zalaczenie przetwornika ADCSRA|=_BV(ADIE); // uaktywnienie przerwan ADCSRA|=_BV(ADATE); // wyzwalanie ciagle SFIOR|=_BV(ADTS2); // przez timer0 ADCSRA|= (_BV(ADPS2)|_BV(ADPS1)|_BV(ADPS0)); //prescaler ADC ADMUX |=_BV(REFS0); // nap. odniesienia 5V ADMUX &=~_BV(REFS1);

PORTA &=~_BV(PA3); // wejscie ADC3 DDRA &=~_BV(PA3); PORTA &=~_BV(PA0); // wejscie ADC0 DDRA &=~_BV(PA0); /***************************************************************** ISR(ADC_vect) {

if((ADMUX&0x03)==3) // przeprowadzany byl pomiar pradu { //pomiar pradu i=ADC; // nastepne probkowanie - napiecie

} else // przeprowadzany byl pomiar napiecia {

//pomiar napiecia v=ADC; // nastepne probkowanie - prad

} ADMUX^=0x03;

}

/********************************************************* ISR (TIMER0_OVF_vect) { TCNT0=100; } /*****************************************************

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required