logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega8][C] ADC - wartość, krótkie pytanie.

regrom 03 Sty 2010 19:53 4018 28
REKLAMA
  • #1 7480037
    regrom
    Poziom 16  
    Mam pewne pytanie.

    Jeśli używamy ADC 10 bit to wartość ADC zgodnie z notą równa się:
    VIN*1024/VREF

    ale jeśli używamy 8 bit, ustawiamy ADLAR, czytamy wtedy tylko ADCH
    to słuszny jest wzór:
    VIN*256/VERF :?:
  • REKLAMA
  • #2 7480227
    psooya
    Poziom 38  
    A niby dlaczego nie ? Nieważne jest w którą stronę będzie wyrównanie (ADLAR). Wygodniej jest czytać przy 8 bitach do ADCH bo i tak jako pierwszy musi być odczytany on właśnie. Uwaga tylko jest taka że Vin nie może przekroczyć Vref.
  • #3 7480273
    regrom
    Poziom 16  
    psooya napisał:
    Uwaga tylko jest taka że Vin nie może przekroczyć Vref.


    To rozumiem, i wiadomo o tym. Tylko zdziwiłem się jak bawiłem się ADC, i zmieniłem z 10 na 8 bit, nigdzie nie było napisane że wtedy ADC=VIN*256/VREF a to ważne.
  • REKLAMA
  • #4 7480314
    Konto nie istnieje
    Poziom 1  
  • Pomocny post
    #5 7480493
    tmf
    VIP Zasłużony dla elektroda
    regrom napisał:
    psooya napisał:
    Uwaga tylko jest taka że Vin nie może przekroczyć Vref.


    To rozumiem, i wiadomo o tym. Tylko zdziwiłem się jak bawiłem się ADC, i zmieniłem z 10 na 8 bit, nigdzie nie było napisane że wtedy ADC=VIN*256/VREF a to ważne.


    A jak zmieniles z 10 na 8 bit? Jedynie co mogles zmienic to wyrownanie do lewej lub prawej. Jesli ustawisz wyrownanie do lewej i do obliczen wezmiesz tylko ADCH to tak jakbys go wstepnie podzielil przez 4 (dwa najmlodzsze bity znajda sie w ADCL), stad tez mnoznik wyniesie 1024/4=256.

    Atom, nie do konca, jesli zalezy mu tylko na 8 bitach to tak jak pisze regrom wystarczy ustawic wyrownanie do lewej i czytac wylacznie ADCH.
    Co do przekraczania VCC (AVCC) na dowolnym pinie to myslalem, ze juz to kiedys wyjasnialismy :) Wszystko bedzie ok dopoki wydajnosc zrodla nie przekroczy ok. 1mA - wtedy cokolwiek podasz zostanie obciete przez wewnetrzne diody do AVCC+0,6V, a jako odczyt bedziesz mial 1024.
  • #6 7480606
    Konto nie istnieje
    Poziom 1  
  • #7 7480802
    psooya
    Poziom 38  
    Witam
    Ja nie napisałem że przekroczenie Vref uszkodzi od razu układ. Sam to testowałem i przy Vref 2,56V i Vin 5V nic się nie działo. Nie wnikam w szczegóły. Za to z PDF:
    Cytat:
    When an ADC conversion is complete, the result is found in these two registers. When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently, if the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.
    The ADLAR bit in ADMUX, and the MUXn bits in ADMUX affect the way the result is read from the registers. If ADLAR is set, the result is left adjusted. If ADLAR is cleared (default), the result is right adjusted.

    To chyba wyjaśnia moja niejasną wypowiedź ?
    Pozdrawiam :-)

    Dodano po 4 [minuty]:

    Może jeszcze to wyjaśnię. Przy 8 bitach wygodnie jest mieć wynik w ADCH bo ponowna konwersja następuje po odczycie ADCH więc nie będzie konieczny zbędny odczyt ADCL. W przypadku 10 bitów jest inaczej i tu czytać można to na 2 sposoby. Często robię tak, że używam 10 bitów z wyrównaniem do lewej a wykorzystuje tylko wynik 8 bitów z ADCH co powoduje że najmniej znaczący bit "mniej mruga" ale tracę na rozdzielczości bo mam tylko 8 bitów.
  • #8 7480881
    Konto nie istnieje
    Poziom 1  
  • #9 7481109
    regrom
    Poziom 16  
    tmf napisał:


    A jak zmieniles z 10 na 8 bit? Jedynie co mogles zmienic to wyrownanie do lewej lub prawej. Jesli ustawisz wyrownanie do lewej i do obliczen wezmiesz tylko ADCH to tak jakbys go wstepnie podzielil przez 4 (dwa najmlodzsze bity znajda sie w ADCL), stad tez mnoznik wyniesie 1024/4=256.


    Dziękuję bardzo, takie wyjaśnienie sprawia że wszystko jest jasne, polać koledze.

    Żeby się nie mieszało od lewej czy prawej warto zapamiętać to, wyższy nr ważniejszy bit:
    [ATmega8][C] ADC - wartość, krótkie pytanie.

    Pozdrawiam
  • REKLAMA
  • #10 7481233
    psooya
    Poziom 38  
    atom1477 napisał:
    psooya napisał:
    Często robię tak, że używam 10 bitów z wyrównaniem do lewej a wykorzystuje tylko wynik 8 bitów


    Co to znaczy "używam 10 bitów"?


    To znaczy że w M8 mamy w wersji BIP 28 o ile dobrze pamiętam 2 kanały 8 bitowe i resztę 10 bitową choć chyba w najnowszej rewizji tego procka wszystkie kanały ADC są już 10 bitowe. Często wystarcza mi 8 bitów a trzeba użyć ADC 10 bitowego. Więc jaki w tym problem by starsze 8 bitów wyjąć z ADCH i nie trzeba ani dzielenia przez 4 ani zbędnego odczytu ADCL. Wszystko widać z tabelki zamieszczonej przez kolegę regrom. Jak zechce mieć 8 bitów przy ADLAR = 0 to będę musiał odczytać ADCL potem ADCH do rejestrów zrobić 2 razy rotację w prawo i zostanie mi 8 bitów tego co mnie interesuje. W przypadku ADLAR = 1 wystarczy jak odczytam ADCH i już mam to co potrzebuje. Tracę na dokładności ale często tyle mi w zupełności wystarcza a zyskuję na mniejszym szumie bitu LSB i często nie muszę uśredniać wyniku bo to co otrzymam w zupełności wystarczy. To był przykład tego jak ja stosuję ADC i ułatwiam sobie robotę i nikt tego stosować nie musi.
    Pozdrawiam
  • #11 7481438
    Konto nie istnieje
    Poziom 1  
  • #12 7482050
    psooya
    Poziom 38  
    Witam
    Źle się wyraziłem więc już chyba sprostowane to jest dobrze. Otóż w PDFie na pierwszej stronie choćby :
    Cytat:
    Rev. 2486B–12/01
    – 6-channel ADC in PDIP package
    4 Channels 10-bit Accuracy
    2 Channels 8-bit Accuracy

    Rev.2486V–AVR–05/09
    – 6-channel ADC in PDIP package
    Six Channels 10-bit Accuracy


    Więc chyba coś się zmieniło. Nie wiem jak w praktyce ale jak na szybkości czytałem o ADC to nie znalazłem tam wzmianki o tym ze 2 kanały są "gorsze" choć mogłem nie doczytać więc na pewno kłócić się nie będę.
    Pozdrawiam :-)
  • #13 7482060
    Konto nie istnieje
    Poziom 1  
  • #14 7483294
    psooya
    Poziom 38  
    Tu masz rację. Przetwarzanie było 10 bitowe ale wynik dla tych 2 kanałów był 10 bitowy z tym że 2 najmłodsze bity wyniku były przypadkowe. Zaglądnę jeszcze do PDFa i poczytam o tym ADC dokładnie.
    Pozdrawiam
    Cytat:
    Note that ADC channels ADC4 and ADC5 are limited to 8-bit accuracy. Channels
    ADC[3:0] and ADC[7:6] offer full 10-bit accuracy.

    Dodatkowo nic nie znalazłem o przetwarzaniu ale z tabeli:
    [ATmega8][C] ADC - wartość, krótkie pytanie.
    Więc skoro czas przetwarzania jest zawsze taki sam to i rozdzielczość jest taka sama dla każdego kanału więc tylko dla dwóch kanałów 2 bity LSB były przypadkowe a pozostałe 8 zawierało wartość odczytaną z ADC. Tak to chyba było :-)
    Pozdrawiam
  • #15 7483499
    Konto nie istnieje
    Poziom 1  
  • #17 7485091
    Konto nie istnieje
    Poziom 1  
  • #18 7485400
    psooya
    Poziom 38  
    Nie chodziło mi o ADC ale jeszcze jest problem z podwójnym przerwaniem od timer 2. Mianowicie od przepełnienia i zrównania z OCR. Jak w tym pierwszym wpisze się wartość początkową timera na początku przerwania to to drugie nie zawsze a przeważnie nigdy się nie wykonuje. Ale to już nie ten wątek.
    Pozdrawiam
  • #19 7485529
    _Robak_
    Poziom 33  
    Mysle ze atmege8 mozna sobie odpuscic, jesli sie chce bardzo dokladne pomiary na ADC, bo maja ten znany blad w krzemie. Swoja droga to juz ich od dluzszego czasu nie ma w tme nawet ;)
  • #20 7485947
    Konto nie istnieje
    Poziom 1  
  • #21 7488039
    wladziu22
    Poziom 17  
    Czesc Wam,

    korzystając z Waszej dyskusji ma temat ADC, rozdzielczości i dokładności wyniku, przypomniałem sobie problem, który kiedyś miałem z ADC w ATtiny26. Mianowicie chodzi mi o dynamikę ADC. Mierząc/zmieniając szybko poziom napięcia np z 0V na 3V, ADC zanim na LCD pokazała mi się wartość w miarę blisko 3V wcześniej np pojawiła się wartość chwilowa np: 1.6V lub jeszcze jakaś mniejsza. Generalnie można było zaobserwować tak jakby jeden lub dwa skoki napięcia. Da się jakoś to wyeliminować? Tzn uzyskać wartość tylko początkowa i końcowa (nie musi być bardzo dokładna).
    A pomiar musiałby być wykonany (gotowy do wyświetlenia) w do ok. 5ms.
    Dodam, ze Fosc=8MHz, odczytuje tylko 8 bitow (ADCH<<2) oraz preskaler ustawiony na 64. Wyświetlanie wyniku odbywa się przy wyłączonym przerwaniu od ADC czyli po wykonanym pomiarze i zebraniu odpowiedniej liczby probek.


    Robiłem tak:
    
    unsigned int ADCResult=0;
    unsigned char Probki=64;
    int NapiecieSred;
    unsigned char NapiecieSredUpdate=0;
    ...
    ...
    ISR(ADC_vect)
    	{
    	static unsigned int mydiv;
    	unsigned int tmp = (ADCH<<2);
    	if(!--mydiv)								//zwolnienie przetwarzania
    		{
    		mydiv = 32;
    		ADCResult += tmp;					   //sumowanie kolejnych wynikow pomiaru
    		if(++Probki == 64)		   			   //licznik 64 probek
    			{
    			Probki = 0;				
    			NapiecieSred = (ADCResult+32) / 64;//zsumowane napiecie + 32 /  na 64
    												//32 po to by zapobiec zaklamaniu usredniania
    			ADCResult = 0;						//wyzerowanie sumy 64 probek napiecia
    			NapiecieSredUpdate = 1;
    			}
    		}
    	}
    
    ....
    ....
    
    void ADC_set(unsigned char NrKanlu)
    {
    	ADMUX = NrKanlu;
    	ADMUX |= _BV(ADLAR);
    // Prescaler 64 =>  8MHz / 64 = 125kHz
    ADCSR = _BV(ADEN)|_BV(ADFR)|_BV(ADIF)|_BV(ADIE)|_BV(ADPS2)|_BV(ADPS1);
    }
    
    void ADC_start(void)
    {
    	// strart conversji ADC
    	ADCSR |= _BV(ADSC);	
    }
    ...
    ...
    
    int main(void)
    {
    char pomiarNap[16];
    unsigned char sreg;
    ...
    sei();
    
    do
    {
    	sreg = SREG;
    	if(NapiecieSredUpdate)
    	{
    	cli();
    
    	wypiszNaLCD("\\cR=");
            itoa(NapiecieSred,pomiarNap,10);
    	wypiszNaLCD(pomiarNap);
    
    	NapiecieSredUpdate = 0;
    	SREG = sreg;
    	sei();
    	}
    	nop();
    }
    while(1);
    ...
    }
    
  • REKLAMA
  • #22 7488528
    Konto nie istnieje
    Poziom 1  
  • #23 7491027
    wladziu22
    Poziom 17  
    Poszedłem Twoim tropem i wyszło na to ze usunąłem przerwanie od ADC i zrobiłem pojedynczy pomiar i odczyt zaraz po po skoczeniu pojedynczej konwersji. Następnie odczekuje odpowiednia chwile (kilkadziesiąt [ms]) na rozpoczęcie kolejnego pojedynczego pomiaru. Dzięki temu nie widać przeskoków napięcia (ew. zapalanie się diód), pomiar zdaje się być stabilny i poprawny.

    Dziękuję za właściwy trop :)
  • #24 7491074
    Konto nie istnieje
    Poziom 1  
  • #25 7492840
    wladziu22
    Poziom 17  
    Zgadza się...tylko jeden pomiar. Ja jedynie potrzebuje trafić w odpowiednie zakresy napięciowe ("widełki"). Wiec nie potrzebuje super dokładnej wartości, wielu próbek.
  • #27 7494353
    _Robak_
    Poziom 33  
    atom1477 napisał:
    Jak nie ma jak 2 dni temu zamówiłem (chociaż w sumie jeszcze nie przyszły :D).
    w TME to nawet ATMEGę8515 mają :D

    Sa ale tylko Lki ;) No chyba ze mnie nie lubia :P
  • #28 7494784
    Konto nie istnieje
    Poziom 1  
  • #29 7514238
    wladziu22
    Poziom 17  
    Cytat:
    To nie lepiej było użyć komparatora ? Nie szumi pomiar ale wtedy nie wiesz ile jest tego napięcia a wiesz czy jest powyżej np 1,5V lub poniżej z jakąś histerezą żeby był stabilny na zboczach.

    Ja mialem do trafienia 7 przedzialow napieciowych. Ale zeby sprawdzic czy trafiam w te przedzialy musialem zmierzyc napiecie, korzystajac z dzielnika wiec i ADC a nastepnie wynik orientacyjnie sprawdzic na LCD.

    To co chcialem osiagnać działa jak nalezy w 100%, wiec nie bede już nic zmieniał.
REKLAMA