[AVR] wejscia przetwornika ADC

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); }

Reply to
roxy
Loading thread data ...

roxy pisze: > (...)

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

"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

Reply to
mw158979

"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

Reply to
mw158979

ATMEGA16

Reply to
roxy

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.

Reply to
John Smith

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

Reply to
Grzegorz Kurczyk

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.

Reply to
T.M.F.

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.

Reply to
T.M.F.

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; } /*****************************************************

Reply to
roxy

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.