Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla 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

21 Maj 2011 15:32 2026 24
  • 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
  • Poziom 38  
    Tryb free running nie jest najlepszy przy pomiarze wielu kanałów. Zastosuj tryb single. lub pobieraj 2 pomiar z danego kanału.
  • 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.
  • 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.
  • 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.
  • Poziom 32  
    I jeszcze zamiast starych nazw przerwań zaczynających się od "SIG_" powinno się używać tych kończących się na "_vect".
  • 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?
  • 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.
  • 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).
  • 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);
    }
  • 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
  • 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
  • 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);
  • 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
  • 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?
  • Poziom 38  
    Przecież kanał nigdy nie przekroczy wartości 7. Maskowane są bity od 3 w gore. czyli z 7 przeskoczysz na 0.
  • 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.
  • 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?
  • 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ę.
  • 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
  • Poziom 30  
    Opisz mi słowami czemu się nie włączy a nie kodem.
  • 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.
  • 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.
  • 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.