RTV forum PL | NewsGroups PL

Nieprawidłowe odczyty z ADC3 na AVR: dlaczego tylko ADC0 działa poprawnie?

[AVR] wejscia przetwornika ADC

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Nieprawidłowe odczyty z ADC3 na AVR: dlaczego tylko ADC0 działa poprawnie?

roxy
Guest

Wed Nov 19, 2008 3:34 pm   



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

Marcin
Guest

Wed Nov 19, 2008 4:06 pm   



roxy pisze:
Quote:
(...)

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

roxy
Guest

Wed Nov 19, 2008 4:24 pm   



Użytkownik "Marcin" <gmail.com@dyziek86.TEGO.NIE.MA> napisał w wiadomości
news:gg1agb$t42$1@nemesis.news.neostrada.pl...
Quote:
roxy pisze:
(...)

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

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

mw158979
Guest

Wed Nov 19, 2008 5:46 pm   



"mw158979" <e@tam.pl> schrieb
Quote:
ADMUX&=~0x07; // nastepne probkowanie - napiecie
ADMUX|=0x03; // nastepne probkowanie - prad

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

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

hej

mw158979
Guest

Wed Nov 19, 2008 5:46 pm   



"roxy" <kicak@o2.pl> schrieb
Quote:
ADMUX&=~0x07; // nastepne probkowanie - napiecie
ADMUX|=0x03; // nastepne probkowanie - prad

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

hej

roxy
Guest

Wed Nov 19, 2008 6:49 pm   



Quote:
Co to za procek w ogole?

hej



ATMEGA16

John Smith
Guest

Wed Nov 19, 2008 6:57 pm   



Quote:
ATMEGA16

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.

roxy
Guest

Wed Nov 19, 2008 9:32 pm   



Użytkownik "John Smith" <dam9723@buziaczek.pl> napisał w wiadomości
news:gg1k17$9ij$1@217.76.112.12...
Quote:
ATMEGA16

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.



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.

Grzegorz Kurczyk
Guest

Wed Nov 19, 2008 11:11 pm   



Użytkownik roxy napisał:
Quote:
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.


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

T.M.F.
Guest

Wed Nov 19, 2008 11:49 pm   



Quote:
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.

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.

--
Inteligentny dom - http://idom.wizzard.one.pl
Teraz takze forum dyskusyjne
Zobacz, wyslij uwagi, dolacz do projektu.

T.M.F.
Guest

Thu Nov 20, 2008 12:03 am   



Quote:
ISR(ADC_vect)
{

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

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.

Quote:
ADMUX&=~0x07; // nastepne probkowanie - napiecie

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.

Quote:
}
else // przeprowadzany byl pomiar napiecia
{


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

}
ADCSRA|=_BV(ADIF);

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.



--
Inteligentny dom - http://idom.wizzard.one.pl
Teraz takze forum dyskusyjne
Zobacz, wyslij uwagi, dolacz do projektu.

roxy
Guest

Thu Nov 20, 2008 7:24 am   



Uzytkownik "T.M.F." <tfrancuz@nospam.mp.pl> napisal w wiadomosci
news:gg25vd$5fb$1@news.onet.pl...
Quote:
ISR(ADC_vect)
{

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

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.

ADMUX&=~0x07; // nastepne probkowanie - napiecie

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


Quote:

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.

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

elektroda NewsGroups Forum Index - Elektronika Polska - Nieprawidłowe odczyty z ADC3 na AVR: dlaczego tylko ADC0 działa poprawnie?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map