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