Skocz do zawartości

[C] Atmega8 ADC - zawyżone odczyty.


Pomocna odpowiedź

Witam, dzisiaj zacząłem się bawić przetwornikiem adc w mojej atmedze8. Chodzi o to że odczyty które wyświetlają mi się na wyświetlaczu są trochę zawyżone, im niższe napięcie daje do przetwornika tym bardziej są zawyżone (przy napięciu poniżej 1V jest to ok 0,3V odchyłku), im wyższe napięcie daje na przetwornik tym odczyty są dokładniejsze np. przy 4V odchyłek to już ok 0,05V, zauważyłem też pewną zależność od częstotliwości, mianowicie jeśli taktuję atmegę z zewnętrznego kwarcu 16MHz to odczyty są bardziej niedokładne niż przy wewnętrznym oscylatorze np. 4MHz. Próbowałem jescze podpiąć 10 kondensatorów 100nF połączonych równolegle do PC5 i GND, nie zauważyłem poprawy odczytów.

#define F_CPU 4000000L 
#include <avr/io.h> 
#include <util/delay.h> 
#include "hd44780.h" 

int main (void) 
{ 

DDRB = 0xff; 
PORTB = 0x02; 
DDRC = 0x00; 
DDRD = 0xFF; 
PORTD = 0x00; 
PORTC=0xff;


ADMUX |= (1<<REFS0)|(0<<REFS1); //porównuje z AVCC,  AREF--||--GND 
       //0 tylko dla zasyganlizowania ze jest tam zero bo to nic nie zmienia 
       ADCSRA |= (1<<ADEN);


	int getADC(char number) 
//number należy do <0, 7>, kod nie sprawdza szkoda pamięci FLASH 
{ 
       ADMUX &= 0xf0; //zerowanie 4 młodszych bitów 
       ADMUX |= number; //ustawianie numeru kanału 

       ADCSRA |= 1<<ADSC; //zaczyna konwersję 
       while(ADCSRA & (1 << ADIF));    //dopuki bit ADIF nie jest ustawiony nie jest gotowa kowersja 
       ADCSRA &= ~((1 << ADSC) | (1 << ADIF)); //zeruj flage konwersji i rozkaz rozpoczecia 
       return ADCW; 
} 





unsigned int pomiar;
float napiecie,napiecie_zasilania;
char str[20];
napiecie_zasilania=5.0;


/* Programowa inicjalizacja wyświetlacza */
 lcd_init();
 /* Włącza wyświetlanie */
 LCD_DISPLAY(LCDDISPLAY);  
 /* Czyści  ekran */
 LCD_CLEAR;            
LCD_LOCATE(0,0);

for(;;){

pomiar= getADC(5); //zaladuj do zmiennej pomiar wartosc z PC5

napiecie=napiecie_zasilania*pomiar/1023; //oblicz napiecie
dtostrf(napiecie,1,2,str); //zamien zmienna typu float na string
lcd_puts(str); //wyslij stringa do wyswietlacza
LCD_LOCATE(0,0);

_delay_ms(150);
}//end for

}//main 

Link to post
Share on other sites

Dziesiątki powodów:

1. brak filtru LC na AVcc

2. antenki na wolnych pinach,
3. miernik do którego porównujesz pomiary, także ma swoją dokładność,
4. nieprawidłowo zaprojektowane PCB

5. bo wewnętrzny generator RC jest znacznie mniej dokładny niż kwarc,
6. otoczenie,
7. itd.

Zajmujesz się mikrokontrolerami od ponad roku, a nie wiesz takich podstaw? A kondensatory, o których pisał Piotrek, .... przykładaj się do tego co robisz już tak długo lub nie rób tego wcale.

Lektura: ADC - Dokładność vs podłączanie

Dlaczego definiujesz funkcje getADC(), w ciele funkcji main()?

Link to post
Share on other sites
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Ok dzięki za pomoc 😮

Zajmujesz się mikrokontrolerami od ponad roku, a nie wiesz takich podstaw?

Określanie umiejętności w skali roku nie jest zbyt dokładne, bo jedna osoba może sie tym zajmować po 3godziny dziennie codziennie, a druga 4godziny miesięcznie.

Dlaczego definiujesz funkcje getADC(), w ciele funkcji main()?

A jakie to ma znaczenie jak działa?

Link to post
Share on other sites
Określanie umiejętności w skali roku nie jest zbyt dokładne, bo jedna osoba może sie tym zajmować po 3godziny dziennie codziennie, a druga 4godziny miesięcznie.

No tak, faktycznie okres nie do końca jest właściwym miernikiem, jednak nie zwalnia od czytania datasheetów stosowanych elementów elektronicznych. Czytaj, bo warto.

A jakie to ma znaczenie jak działa?

Dlatego, że jeżeli wpadnie Ci to w nawyk, to będzie przeszkadzać w przyszłości przy większych projektach. Poza tym analizowanie takiego kodu wrzuconego na forum, jest trudniejsze.

Link to post
Share on other sites

Ok dzięki dondu. Dzięki stronce zrozumiałem, że to co analogowe to jest delikatne ;D, generalnie ja teraz testowałem jak się obsługuje ADC przed przystąpieniem do czegoś poważniejszego co będzie to wykorzystywało. Temat do zamknięcia. Pozdrawiam!

Link to post
Share on other sites

Typowe błędy to błąd zera (offsetu) - gdzie mamy jakąś stałą wartość która dodaje się (ze znakiem) do wyniku i błąd skali, czyli problem z wielkością napięcia referencyjnego - tam z kolei różnica zwiększa się wraz ze wzrostem wielkości mierzonej. Tutaj jest jakiś inny problem. Trochę wygląda to tak, jakby zmniejszając położenie ślizgacza potencjometru coś pompowało w linię wejściową przetwornika coraz większy prąd. Taki model błędu wskazuje na rezystor wpuszczający prąd od góry. Błędem są oczywiście pull-upy załączone na całym porcie C (PORTC=0xFF) ale to mogłoby być źródłem takich wyników gdyby nie to, że przecież Ty zapewnie mierzysz rzeczywiste napięcie miernikiem wprost na wejściu PC5. Jak weryfikujesz pomiary? Multimetrem czy tylko kątem obrotu potencjometru? Czy zjechanie napięciem do zera na wejściu PC5 (i potwierdzenie tego multimetrem) daje wynik 0.5V? Zwarcie linii do masy powinno dać wynik w granicach zera ±2LSB niezależnie od wszelkich podciągów.

Czy na pewno obie masy ATmegi są dobrze podłączone do dobrej masy?

Link to post
Share on other sites

Ja bym jeszcze dodał że przetwornika nie mozna gonić szybciej niź jest to określone w dokumentacji, jest to około 200khz. Musisz odpowiednio ustawić dzielnik częstotliwości dla taktowania ADC.

Link to post
Share on other sites

Zastanawiałem się nad tym ale przetaktowanie przetwornika SAR wiązałoby się raczej z błędami na przypadkowych bitach bo komparator (lub DAC) by się nie wyrabiały z ustalaniem odpowiedzi kolejnego "ważenia". To jest raczej błąd "analogowy" więc ten wątek odrzuciłem, choć nie znając dokładnie szczegółów konstrukcji układu trudno jednoznacznie to wyrokować. Producent w danych katalogowych zamieszcza np. błędy przetwarzania A/C dla taktowania 200kHz (zalecanego) i 1MHz (duużo za szybko) i nieliniowości są (o ile pamiętam) wciąż poniżej 10LSB.

Link to post
Share on other sites

np. zjade potencjometrem do końca, miernik pokazuje 0V, a na wyświetlaczu mam 0,3V, ustawie potencjometr tak zeby na wyświetlaczu pokazywało 0,4V to miernik pokazuje 0,1V itd, im większe napięcie puszcze na adc to odchyłek jest coraz mniejszy.

Link to post
Share on other sites

Mam takie spostrzeżenie, trochę od czapy bo nie widzę związku z wynikami które obserwujesz ale moim zdaniem nie czekasz na zakończenie konwersji. Pętla:

while(ADCSRA & (1 << ADIF));

kręci się w kółko gdy ADIF jest ustawiony a przecież na tę jedynkę masz właśnie poczekać. Czyli robisz start konwersji i pętla while jednokrotnie sprawdza swój warunek bo przecież nie jest spełniony. Zaraz po tym próbujesz skasować bit ADSC (co nie jest możliwe) oraz bit ADIF, odczytujesz wynik (pewnie poprzedniej konwersji bo wciąż tam przecież jest) i go wyświetlasz. Ponieważ raz wystartowany pomiar trwa sobie w najlepsze, kolejne próby jego wystartowania nic nie dają ale za którymś obrotem głównej pętli trafiasz na zakończony pomiar. Wtedy startujesz kolejny, kasujesz (tym razem z powodzeniem) ADIF i znów czytasz wynik. Ten schemat w sumie jakoś działa ale czy może mieć wpływ na takie rezultaty jakie opisałeś - nie wiem. Na pewno koniecznie wyłącz podciąg na PC5. Na reszcie wejść przetwornika mogą na razie zostać żeby nie wisiały w powietrzu ale gdy zaczniesz te wejścia wykorzystywać, zdejmij i tam.

Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.