Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

atmega16 - ADC z dwóch kanałów

ublizzard 28 Kwi 2013 19:07 2430 19
  • #1 28 Kwi 2013 19:07
    ublizzard
    Poziom 11  

    Na początek podam kod:

    Kod: C
    Zaloguj się, aby zobaczyć kod


    Problemem jest, że w obu miejscach wyświetla pomiar z ADC5.
    Co zrobić, żeby wyświetlało również pomiar z ADC4?

    0 19
  • #2 28 Kwi 2013 19:19
    pawel_mr
    Poziom 14  

    Może zamiast:

    ADMUX |= 0b00101;//wybór kanału pomiarowego ADC5
    ADMUX |= 0b00100;//wybór kanału pomiarowego ADC4
    napisz:
    ADMUX = 0b00101;//wybór kanału pomiarowego ADC5
    ADMUX = 0b00100;//wybór kanału pomiarowego ADC4
    W pierwszym przypadku zapis:
    ADMUX |= 0b00100;
    nie zmieni wartości najmłodszego bitu więc finalnie nie zmieniasz wejścia. Oczywiście jeśli w ADMUX wcześniej były ustawione inne bity, trzeba o tym pamiętać bo mój zapis je wyzeruje.

    0
  • #3 28 Kwi 2013 19:19
    paladyn
    Poziom 15  

    Nie masz czasem problemu z rejestrem ADMUX ? Zdaje się, że po wykonaniu pomiaru powinieneś go zresetować, żeby móc ustawić inny kanał.

    Spróbuj tak: ADMUX |= (ADMUX & 0xF8) | channel;

    Edit:

    Zapis jak powyżej pozostawia 5 bitów licząc od lewej, natomiast trzy ostatnie bity odpowiadające za kanał są zerowane.

    0
  • #4 28 Kwi 2013 19:43
    ublizzard
    Poziom 11  

    Niestety koledzy nie w tym tkwi problem, bo nadal w obu miejscach wyświetla mi tą samą wartość z ADC5

    Co ciekawe, gdy zamienię kolejność ADMUX:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    To wraz pokazuje mi wartość z ADC5 w obu przydadkach.

    0
  • #7 28 Kwi 2013 21:45
    ublizzard
    Poziom 11  

    Dzięki dondu za podpowiedź i pokazanie tego fajnego kompilatora :D

    Niestety nawet jak przypiszę na "sztywno":

    Kod: c
    Zaloguj się, aby zobaczyć kod
    i cManiak pokazuje tak jak powinien:
    4
    5
    4
    To wyświetlacz pokazuje nadal dwa razy tą samą wartość (tą dla której po raz pierwszy w kodzie wybrałem kanał pomiarowy)

    0
  • #9 28 Kwi 2013 22:53
    ublizzard
    Poziom 11  

    dondu ja rozumiem tak działanie tego kodu:

    ADMUX |= (ADMUX & 0xF8) |0b00100;
    ADMUX |= 11111000 | 0b00100
    ADMUX |= 11111100
    Ponieważ ADMUX nie miał zadeklarowanej wartości zakładam, że jego wartość to 0, więc:
    ADMUX =11111100

    ADMUX |=(ADMUX & 0xF8) |0b00101;
    ADMUX |=11111000 | 0b00101
    ADMUX |=11111101
    ADMUX =11111101

    ADMUX |=(ADMUX & 0xF8) |0b00100;
    ADMUX |=11111000 | 0b00100
    ADMUX |= 11111100
    ADMUX =11111101

    Co do programu, to wygląda w ten sposób:

    Kod: c
    Zaloguj się, aby zobaczyć kod
    Usunąłem alternatywę przy wyborze kanału pomiarowego, niestety teraz pokazuje podwójnie drugi pomiar, czyli ADC4.

    0
  • Pomocny post
    #10 28 Kwi 2013 23:05
    miszczo997
    Poziom 27  

    W powyższy sposób pozbywasz się wybranego wcześniej źródła napięcia referencyjnego. Ma to wyglądać tak

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Zważ na to, że w tym rejestrze jest nie tylko wybór kanału, a Ty poprostu całego go sobie zerujesz oprócz bitów kanału. I źle rozumujesz
    Początkowa wartość ADMUX = 0bXXXX XXXX
    ADMUX = (ADMUX & 0xF8) |0b00100;
    ADMUX = 0bXXXX X000 | 0b00100
    ADMUX = XXXX X100
    Tam nie powinno być tego OR!

    0
  • #11 28 Kwi 2013 23:13
    ublizzard
    Poziom 11  

    Nie pomyślałem o tym.
    Masz rację już teraz działa poprawnie.

    0
  • #12 28 Kwi 2013 23:17
    dondu
    Moderator Mikrokontrolery Projektowanie

    miszczo997 napisał:
    Tam nie powinno być tego OR!

    Szkoda, że podpowiedziałeś wprost. Lepiej jest nakierowywać, ale błąd powinien znaleźć sam :)
    Wtedy łatwiej będzie mu znaleźć własne błędy w przyszłości.

    @ublizzard
    A teraz zastanów się jak taki rozkaz wpływa na Twój program:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Co konkretnie ustawi w przetworniku ADC.

    0
  • #16 29 Kwi 2013 09:16
    ublizzard
    Poziom 11  

    dondu napisał:
    Nie on, jest uparty, kombinuje i daje materiały do analizy - trzeba mu tylko wskazać drogę :)
    Żeby wszyscy tacy byli ...

    Dzięki za dobre słowa :D
    dondu napisał:
    @ublizzard
    A teraz zastanów się jak taki rozkaz wpływa na Twój program:

    Kod C - [rozwiń]
    ADMUX = 0b00101;
    Co konkretnie ustawi w przetworniku ADC.

    Pierwsze dwa bity odpowiadają za wybór napięcia wzorcowego, czyli w tym przypadku: 0 0 AREF, Internal Vref turned off
    A ja powinienem ustawić: 0 1 AVCC with external capacitor at AREF pin.
    Czyli powinienem napisać:
    ADMUX = 0b01101
    i
    ADMUX = 0b01100.
    ADC nie miał do czego przyrównać napięcia wej.

    0
  • #17 29 Kwi 2013 09:48
    dondu
    Moderator Mikrokontrolery Projektowanie

    No właśnie - wiedziałem, że dasz radę :)

    Teraz wróć do swojego pierwotnego zapisu, ale poprawionego i wszystko powinno być ok. Czyli to co napisał miszczo997.

    Poza tym, bity multipleksera nie bez przyczyny są na najmniej znaczących pozycjach. Dlatego do wskazania numeru kanału wystarczy używać liczby dziesiętnej (zamiast dwójkowej), co ułatwia rozumienie programu.

    0
  • Pomocny post
    #18 29 Kwi 2013 10:10
    BlueDraco
    Specjalista - Mikrokontrolery

    Tak się kończy uwielbienie dla operatorów |= i &= na rejestrach.

    Ja bym to zrobił tak:

    Najpierw definiujemy stałą - wzorzec bitowy tego, co ma być w ADMUX poza wyborem kanału, np.

    #define ADMUXVAL (1<<REFS0)

    a potem w programie, żeby wybrać sobie kanał, piszemy:

    ADMUX = ADMUXVAL | 4;

    albo

    ADMUX = ADMUXVAL | 5;

    W ten sposób:

    - skracamy program o kilkanaście/kilkadziesiąt instrukcji w porównaniu z wersją z |=
    - otrzymujemy program, który działa
    - zapisujemy numer kanału po ludzku, co by go było widać gołym okiem, zamiast kodować go binarnie.

    0
  • #19 29 Kwi 2013 10:16
    dondu
    Moderator Mikrokontrolery Projektowanie

    Propozycja BlueDraco w przypadku, tego rejestru jest bardzo rozsądną, tym bardziej, że prawdopodobnie w trakcie działania programu (po pierwszej inicjalizacji ADC) nie będziesz zmieniał źródła napięcia odniesienia (REFS1:0), ani wyrównywania do lewej/prawej (ADLAR).

    0
  • #20 29 Kwi 2013 16:14
    ublizzard
    Poziom 11  

    BlueDraco dzięki za podpowiedź, rzeczywiście jest to dużo lepsze rozwiązanie.

    Myślę, że już mogę zamknąć temat.

    0