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

ADC- błędy poczas pomiaru na kilku kanałach

INTOUCH 21 Maj 2011 15:32 1864 24
  • #1 21 Maj 2011 15:32
    INTOUCH
    Poziom 30  

    Witam.
    Pomiar dla pojedynczego kanału, który bym nie wybrał jest zawsze poprawny.
    Problem pojawia się gdy występuje multipleksowanie (zmiana kanału).
    Podejrzewam, że może być problem z przesłuchem od kanałów.

    Poniżej przedstawiam dwa kody: Proszę o pomoc bardziej doświadczonych forumowiczów o rozwiązanie problemu.

    Pomiar z wykorzystaniem pojedynczego kanału:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    Pomiar z wykorzystaniem kilku kanałów
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 24
  • Arrow Multisolution Day
  • #2 21 Maj 2011 15:46
    tadzik85
    Poziom 38  

    Tryb free running nie jest najlepszy przy pomiarze wielu kanałów. Zastosuj tryb single. lub pobieraj 2 pomiar z danego kanału.

    0
  • #3 21 Maj 2011 16:08
    INTOUCH
    Poziom 30  

    Czy tryb single mogę zrobić na przerwaniu.
    Nie uśmiecha mi się pisanie funkcji ponieważ kod wykonywany w pętli głównej programu może być długi.

    0
  • #4 21 Maj 2011 16:11
    tadzik85
    Poziom 38  

    oczywiście, że może po odczytanie ADC zmienia kanału ponownie startujesz ADC. i to wszystko. W twoim przypadku jest błąd bo kanał zmieniasz podczas konwersji. Stąd błędy.

    A zmiana jest prosta wyłącz free running dodaj na końcu przerwania uruchomienie przetwornika.

    0
  • #5 21 Maj 2011 16:14
    tmf
    Moderator Mikrokontrolery Projektowanie

    Błąd wynika z tego, że zmiana MUX będzie obowiązywać dopiero przy kolejnym pomiarze ADC. W momencie kiedy jesteś w procedurze obsługi przerwania pomiar już trwa. Stąd też odczytywany wynik dotyczy poprzedniego kanału, a nie tego, który aktualnie znajduje się w rejestrze MUX.

    0
  • #6 21 Maj 2011 17:39
    McMonster
    Poziom 32  

    I jeszcze zamiast starych nazw przerwań zaczynających się od "SIG_" powinno się używać tych kończących się na "_vect".

    0
  • Arrow Multisolution Day
  • #7 21 Maj 2011 18:38
    INTOUCH
    Poziom 30  

    Czyli krótko mówiąc muszę ustawić ADATE w stan zero i na końcu obsługi przerwania do ADSC wpisać 1.
    Potrzebuję tylko 2 kanałów w których pomiar będzie wykonywany z częstotliwością 1100Hz.
    Czy mogę do przerwania wrzucić opóźnienie?

    0
  • #8 21 Maj 2011 18:43
    tadzik85
    Poziom 38  

    nie! a jeśli chcesz próbkować określoną F proponuję pobierać 2 pomiar z próbkowania z 2xf. do wyzwalania można wykorzystać timer.

    0
  • #9 21 Maj 2011 18:46
    krru
    Poziom 32  

    Żadnych opóźnień lepiej nie umieszczaj w obsłudze przerwania. Podłącz przerwania z timera 1100 razy na sekundę, tam startuj przetwornik na jednym kanale, w pierwszym przerwaniu od ADC odczytaj wartosc i wystartuj przetwarzanie na drugim kanale, w kolejnym przerwaniu odczytaj wynik i już nie ruszaj ADC. Niech czeka na przerwanie z zegara. Będziesz potrzebował prościutki automat stanowy pamiętający, w której fazie przetwarzania jesteś, by wiedzieć co zrobić w przerwaniu od ADC. Być może da się wykorzystać do tego odczyt rejestru MUX, ale lepiej na zmiennej. Przy okazji możesz sprawdzić czy wyrabia się przetwornik (jak za szybko dostaniesz przerwanie od timera).

    0
  • #10 21 Maj 2011 19:36
    INTOUCH
    Poziom 30  

    Nadal nie działa.
    Czyta mi mi tylko z kanału 1;

    Auto wyzwalanie wyłączone.
    CLR_BIT(ADCSRA, ADATE);//AUTOWYZWALANIE WYŁĄCZONE

    ISR(ADC_vect)
    {
    pomiar[kanal]=ADC;
    ADMUX =(ADMUX & 0b11000000) + kanal;
    ++kanal;

    if(kanal > 7)
    {
    kanal = 0;
    }
    SET_BIT(ADCSRA, ADSC);
    }

    0
  • #12 21 Maj 2011 20:20
    INTOUCH
    Poziom 30  

    Wszystkie Timery będą wykorzystane do innych celów dlatego nice chcę wykorzysta któregokolwiek timera do przetwarzania ADC




    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #13 21 Maj 2011 20:26
    GSM
    Poziom 25  

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Nawiasem mówiąc, inkrementując zmienną 'kanal' PO ustawieniu multipleksera przy następnej konwersji do tablicy 'pomiar' do pozycji n'tej zapisze się wynik z n+1'tego kanału.
    I ja to bym zrobił raczej jakoś tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Poza tym, możesz powiedzieć na jakim mikrokontrolerze pracujesz?

    Pozdrawiam,
    GSM

    0
  • #14 21 Maj 2011 21:08
    INTOUCH
    Poziom 30  

    Mikrokontroler to ATMEGA32.

    Nie bardzo rozumiem jak to ma działać?
    Ile kanałów obsłuży poniższy kod?
    pomiary[kanal++] = ADC;
    ADMUX = 0b11000000 | (kanal & 0b00000111);

    0
  • #15 21 Maj 2011 22:03
    GSM
    Poziom 25  

    Tyle samo ile kolegi wersja - 8;
    Czego dokładnie nie rozumiesz?
    Po zakończonym pomiarze wartości napięcia na kanale N,
    zapisana zostanie wartość z przetwornika do N'tej komórki tablicy 'pomiary',
    zmienna 'kanal' zostanie zwiększona o 1,
    do rejestru ADMUX zostanie wpisany stały nastaw źródła referencyjnego 2,56V (0b11000000) zsumowany z 3 ostatnimi bitami zmiennej 'kanal' (kanal & 0b00000111).
    Gdy zmienna kanał będzie miała wartosc 7 (0b111) i zwiększymy ja o 1 otrzymamy 8 (0b1000), porzucają wszystko poza 3 najmłodszymi bitami otrzymamy liczbę 0 (0b000). Gdy 9 (0b1001) to 3 ostatnie bity będą miały wartość 1, i tak w kółko.
    Oszczędzamy sobie tym samym skoku warunkowego.

    Pozdrawiam,
    GSM

    0
  • #16 22 Maj 2011 15:28
    INTOUCH
    Poziom 30  

    Według DTR dla(0b1000) (ustawienie najmłodszych bitów) uruchamiany jest pomiar dla kanałów różnicowych. Po co miałbym przechodzić z pomiaru z pojedynczych kanałów na różnicowe?

    0
  • #17 22 Maj 2011 15:36
    tadzik85
    Poziom 38  

    Przecież kanał nigdy nie przekroczy wartości 7. Maskowane są bity od 3 w gore. czyli z 7 przeskoczysz na 0.

    0
  • #18 22 Maj 2011 16:42
    INTOUCH
    Poziom 30  

    Można jaśniej z tym maskowaniem?
    Jak dla mnie taka realizacja może zmienić stan trzech najstarszych bitów i wtedy pomiar nie będzie działa tak jak powinien.

    0
  • #19 22 Maj 2011 16:55
    tadzik85
    Poziom 38  

    gdy po kanal++ kanal wyniesie 8 czyli 0001000 maskowane jest 5 starszych bitów czyli w wyniku uzyskujesz 0

    więc w czym problem?

    0
  • #20 22 Maj 2011 18:58
    INTOUCH
    Poziom 30  

    Chodzi mi o wynik.

    Kod: c
    Zaloguj się, aby zobaczyć kod



    ADMUX = 0b11000000 | (kanal & 0b00000111) dla kanału =0 ADMUX = 0b11000111

    ADMUX = 0b11000000 | (kanal & 0b00000111) dla kanału =1 ADMUX = 0b11001000
    dla wartości 0b11001000 wchodzi na pomiar różnicowy.

    Gdy ADMUX będzie miał wartość 0b11100000 włączy się bit ADLAR.

    Według mnie to tak działa. No chyba że się mylę.

    0
  • #21 22 Maj 2011 19:05
    tadzik85
    Poziom 38  

    mylisz się zapis jest poprawny i obsługa 8 kanałów różnicówka nigdy się nie włączy po kanale 7 wybrany zostanie 0 nie różnicowy.

    Ale jak nie rozumiesz zrób sobie to inaczej.

    prościej ci to zapiszę.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #22 22 Maj 2011 19:20
    INTOUCH
    Poziom 30  

    Opisz mi słowami czemu się nie włączy a nie kodem.

    0
  • #23 22 Maj 2011 19:30
    tadzik85
    Poziom 38  

    bo operacja & 0b00000111 zeruje bity od 3 do najstarszego więc niemożliwe jest by bit 3 się ustawił a co za tym idzie włączył pomiar różnicowy.

    0
  • #24 22 Maj 2011 19:37
    INTOUCH
    Poziom 30  

    Wygląda na to że jeden z forumowiczów wprowadził mnie w błąd poniższą treścią

    Cytat:
    Gdy zmienna kanał będzie miała wartosc 7 (0b111) i zwiększymy ja o 1 otrzymamy 8 (0b1000), porzucają wszystko poza 3 najmłodszymi bitami otrzymamy liczbę 0 (0b000). Gdy 9 (0b1001) to 3 ostatnie bity będą miały wartość 1, i tak w kółko.
    Oszczędzamy sobie tym samym skoku warunkowego.


    dla wartości kanal=1;

    kanal &= 0b00000111; będzie 0b00000001, a nie 0b1000 ostatnie bity z wartości 0b00001000.

    0
  • #25 22 Maj 2011 19:58
    tadzik85
    Poziom 38  

    Pisał dobrze ale ty masz problem ze zrozumieniem tego myślisz dziesiętni nie binarnie. a binarne myślenie wielokrotnie ułatwia życie. np w tym przypadku.


    Choć jego przykład z 9 jest nie na miejscu bo nigdy nie wystąpi bo nie wystąpi również 8 ale dobrze pokazuje zasadę działania.

    0