sarnecki Napisano Kwiecień 5, 2012 Udostępnij Napisano Kwiecień 5, 2012 Witam, na wstępie chciałbym prosić o cierpliwość i wyrozumiałość... Od jakiegoś czasu zmagam się z programem wykorzystującym przetwornik ADC w Atmedze16. Głównym i prawdopodobnie jedynym problemem jest konfiguracja ADC, nie moge poradzić sobie stosując note katalogową Atmegi. Chce osiągnąć następujący efekt: pomiar z ADC zapisywany jest jako np.: "pomiar" abym dalej mógł wykorzystać tę wartość if(pomiar<100) PORTC=0x42; else PORTC=0x81; Czujnik analogowy Sharpa podpięty jest pod ADC0 (PA0). Napisałem coś takiego lecz jak się można domyślić nie działa... #include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 1000000L unsigned int pomiar; //////////////////////////////////////////////////// SIGNAL(SIG_ADC) { pomiar=ADCH; } int main( void ) { ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<MUX0) | (1<<ADLAR); ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0) | (1<<ADATE) | (1<< ADIE); sei(); ADCSRA |= _BV(ADSC); while(1) { char LPPP, LTPT; DDRC=0xff; LPPP=0x42;//przod LTPT=0x81;//tyl if(pomiar<100) PORTC=LPPP; else PORTC=LTPT; } } Z góry dziękuje za pomoc. Pozdrawiam
dondu Kwiecień 6, 2012 Udostępnij Kwiecień 6, 2012 1. Słowo klucz: VOLATILE 2. Używasz przestarzałej funkcji obsługi przerwań SIGNAL(). Używaj ISR() i nowych wektorów: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html PS. Czójnik analogowy Sharpa podpięty jest pod ADC0 (PA0).
Foadrian Kwiecień 6, 2012 Udostępnij Kwiecień 6, 2012 Po pierwsze to co mówi dondu. Jeżeli chcesz odczytać tylko wyższy bajt rejestru ADC to powinno to wyglądać tak: ISR(ADC_vect){ pomiar=ADCH; } a skoro już bawimy się w przerwania to konieczne jest ich wcześniejsze odblokowanie. SREG|=_BV(7); Po za tym wartość zmiennej pomiar będzie zawsze mieściła się w zakresie od GND do Vref - 1LSB- dlatego nie rozumiem w jakim celu sprawdzasz warunek if(pomiar<100) i jeszcze jedna rzecz jak rzuciła mi się w oczy: ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<MUX0) | (1<<ADLAR); ta konfiguracja bitów daje odczyt na pinie ADC1 a nie jak sądzisz ADC0, żeby czytać z pinu ADC0 usuń ten | (1<
dondu Kwiecień 6, 2012 Udostępnij Kwiecień 6, 2012 Jeżeli chcesz odczytać tylko wyższy bajt rejestru ADC ... tutaj powinienem był jeszcze zapytać autora tematu, w jakim celu zmienna pomiar jest typu INT skoro odczytuje jej tylko starszy bajt?: unsigned int pomiar; ... pomiar=ADCH; a skoro już bawimy się w przerwania to konieczne jest ich wcześniejsze odblokowanie. SREG|=_BV(7); tę czynność autor wykonuje rozkazem sei(). A propos powyższego uwaga do autora: zdecyduj się, czy wykorzystujesz zapis (1< Po za tym wartość zmiennej pomiar będzie zawsze mieściła się w zakresie od GND do Vref - 1LSB- dlatego nie rozumiem w jakim celu sprawdzasz warunek if(pomiar<100) Nie bardzo rozumie, do czego masz zastrzeżenia.
Foadrian Kwiecień 6, 2012 Udostępnij Kwiecień 6, 2012 dondu Nie bardzo rozumie, do czego masz zastrzeżenia. if(pomiar<100) PORTC=0x42; else PORTC=0x81; Jak napisałem wcześniej pomiar będzie w zakresie GND a Vref - 1LSB. czyli np od 0 do ~5V co oznacza że nigdy nie wykona się instrukcja else. Czy źle interpretuje ten kod ?
dondu Kwiecień 6, 2012 Udostępnij Kwiecień 6, 2012 Autor ustawił Vref na wewnętrzne źródło napięcia 2,56V. Nie wiemy jakie napięcie mierzy, stąd nie można powiedzieć, że else się nie wykona. Wprawdzie podaje, że to czujnik Sharp i nic więcej, ani nawet nie pokazał schematu. Patrząc na wykres GP2Y0A21YK0F, kod działać będzie prawidłowo, choć nie wykorzysta pełnej skali pomiaru bliskich odległości. Innymi słowy brak danych, by twierdzić, że else się nie wykona.
Foadrian Kwiecień 6, 2012 Udostępnij Kwiecień 6, 2012 Kolega wybrał notację left adjusted - stąd ADCH to 8 bitów.
dondu Kwiecień 6, 2012 Udostępnij Kwiecień 6, 2012 Kolega wybrał notację left adjusted - stąd ADCH to 8 bitów. ADCH to zawsze jest 8 bitów choć nie zawsze zawiera 8 bitów pomiaru. Nie to wskazywałem, tylko: ... w jakim celu zmienna pomiar jest typu INT skoro odczytuje jej tylko starszy bajt?
kaliska5 Kwiecień 7, 2012 Udostępnij Kwiecień 7, 2012 Jeśli chcesz odczytać wynik konwersji to albo czytasz całość np. zmienna=ADCW albo najpierw czytasz dolny bajt potem górny,wszystko jest w nocie.
dondu Kwiecień 7, 2012 Udostępnij Kwiecień 7, 2012 Jeśli chcesz odczytać wynik konwersji to albo czytasz całość np. zmienna=ADCW albo najpierw czytasz dolny bajt potem górny,wszystko jest w nocie. Autor prawidłowo odczytuje starszy bajt wyrównując wynik do lewej, co świadczy o tym, że czytał notę, stąd Twój komentarz jest całkowicie zbędny.
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »