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

[ATMEGA8][C]Obsługa 2 kanałów ADC

Aro_ 11 Lip 2008 11:34 8780 31
  • #1 5332879
    Aro_
    Poziom 15  
    Witam, mam problem z obłsugą dwóch kanałów ADC w tym mikrokontrolerze. Sygnały mieszają się ze sobą, brak separacji między kanałami. Niestety nigdzie nie mogę znaleźc jak to poprawnie zrobic. Aktualny kod wygląda tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Możliwe, że wina leży w ustawieniu bitów rejestrów ADC.

    Przed założeniem kolejnego tematu , proszę przeczytać
    https://www.elektroda.pl/rtvforum/topic1015361.html
    oraz poprawić błędy w treści.
    Tymczasem , tytuł poprawiłem
    [zumek]
  • #2 5332894
    Krzysiek_k1984
    Poziom 13  
    Z tego co widzę to nigdzie nie kasujesz MUX1. Ustawiasz go raz i koniec ;) Musisz go wyzerować.
  • #3 5333119
    Aro_
    Poziom 15  
    Jak to nie? Instrukcją:
    ADMUX = ( _BV(REFS1) | _BV(REFS0));    //kanał 0 

    Na pierwszy rzut oka może nie widac:) AVR to nie ARM.
    Bardziej mnie niepokoi ustawianie bitu ADCSR|=_BV(ADIF);, według książki tak ma byc. Ale bez znaczenia czy dam takie polecenie czy nie, program i tak nie działa prawidłowo:( Nawet specjalnie dodałem opóźnienia, też bez skutku.
  • #4 5333191
    Balu
    Poziom 38  
    He?
    Cytat:

    Kod:
    ADMUX = ( _BV(REFS1) | _BV(REFS0)); //kanał 0

    Po kiego wała za każdym razem ustawiasz napięcie odniesienia?
    Nie lepiej poptostu kasować bit od muxa?

    Poza tym nie wiem co on robi z rej. ADCSR bo takiego nie ma w m8:), jest za to ADCSRA

    Może po zmianie refów, trzeba ponownie ustawić coś więcej?
  • #5 5333809
    Aro_
    Poziom 15  
    Tylko że ja "refów" nie zmieniam. Pozmieniałem kod tak jak napisałeś i dalej to samo:( Problem jest gdzieś indziej. Kolega miał ten sam problem i zrezygnował z ADC, ja natomiast mam już gotowe urządzenie i nie mogę nic zmieniac w hardware. Może jakaś fabryczna wada ATMEGA8? Na internecie jakoś brak programów na kilka kanałów ADC.
  • #6 5333833
    snow
    Poziom 31  
    Spróbuj tak:


    
    
    
    void adc_init(void) 
    { 
     ADMUX =  (1<<ADLAR)| (1<<REFS0)|(1<<REFS1); 
     ADCSRA = (1<<ADEN) | (1<<ADPS2)| (1<<ADPS0);  
     
     }
    //
    
    
    
     
      ADCSRA |= _BV(ADSC);
        while(bit_is_set(ADCSRA,ADSC))
        {};   
      pomiar1=ADCW; 
    
     
      ADMUX |=_BV(0) ;          
      ADCSRA |= _BV(ADSC);        
      while(bit_is_set(ADCSRA,ADSC))   
        {};   
      pomiar2=ADCW;             
     ADMUX &=~_BV(0) 


    zmienne pomiar1 i pomiar2 jako unsigned int
  • #8 5333942
    Aro_
    Poziom 15  
    Cóż mogę powiedzieć... nie działa:( Chyba kiedyś już tak próbowałem, tylko wtedy wszystko sie zawieszało.
    Balu a nie masz tak czasem kodu do tego ADC?
  • Pomocny post
    #10 5333989
    snow
    Poziom 31  
    A tak w ogóle to zasiliłeś przetwornik? dałeś kondensator jak w nocie piszą na AREF? W moim przykładzie przetwarza kanał 0 i 1.
  • #11 5335151
    Aro_
    Poziom 15  
    W M8 nie trzeba zasilać, wewnętrznie zwarte, ale też próbowałem. Kondensator mam. A mógłbyś mi wysłać hexa tego programu? No chyba że to częśc większego projektu. Nie wiem czy przypadkiem wpływu nie ma to, że korzystam z wewnętrznego napięcia odniesienia, a na wejściu pojawia się czasem więcej niż 2,56V?
  • #12 5335354
    Balu
    Poziom 38  
    tak, może mieć, pradwopodobnie już nie żyje przetwornik, zajrzyj do datasheet ai dowiedz się więcej czy nie piszą co się stanie po przekroczeniu aref:)
    Wydaje mi się, że może to mieć wpływ.
    Poza tym KONIECZNIE trzeba zasilić avcc i odfiltrować.
    W polsce wszyscy wszystko starają się robić na odpieprz się:/
  • #13 5335580
    ZbeeGin
    Poziom 39  
    Balu. Akurat w ATMega8 nie ma to znaczenia czy podłączysz AVCC bo z powodu błędu w strukturze jest ono zwarte z VCC przez niewielką oporność.
    Domyślnie przetwornik korzysta z wewnętrznego źródła odniesienia 2.56V (które powinno mieć kondensator) ale jeśli program nadpisze rejestr to może włączyć się Vref = AVCC i stąd skoki na AREF. Trzeba by prześledzić co robi program wewnątrz (AVR Studio).

    To raczej w Atmelu zrobili to na odpieprz się i się nie przyznają do tego błędu.
  • #16 5336324
    Aro_
    Poziom 15  
    Problem musi byc w programie, skoro bascom sobie radzi. Jest tylko coś o czym nie napisali w książkach, a nawet w karcie katalogowej M8:( Tak sie zastanawiam, jakby tak zdesassemblowac plik hex bascoma. Czy to wogóle ma sens.
  • #19 5336409
    snow
    Poziom 31  
    W nocie katalogowej jest wszystko co potrzebne żeby uruchomić pomiar 2 i więcej kanałów. Jakoś z tym specjalnych problemów nie ma.
  • #20 5336645
    trol.six
    Poziom 31  
    A czemu miałby nie mierzyć? ja mierze nawet więcej kanałów. I stabilność mam na poziomie około 0.0001 z nadpróbkowaniem bez filtrów, z tym że sprawa jest taka, że normalnie przy jednym pomiarze ta cyfra zawsze sobie mryga. Co nie jest niczym niezwykłym.

    A co masz na resztach PIN'ów? Czy wszystkie pozostałe wejścia portów są podciągnięte?

    Aro_ napisał:

    
    
    
            ADCSR|=_BV(ADSC);
            _delay_loop_1(50);
    
            uint16_t value=ADCW;
    
            ADCSR|=_BV(ADSC);
    
            _delay_loop_1(15); <- czemu tutaj masz 15 a wcześniej 50?
    
    //jesteś pewien że te opóżnienia wystarczą?
    
    
    
            ADMUX = ( _BV(MUX1) | _BV(REFS1) | _BV(REFS0));   //kanał 3
    // raczej kanał 2 
    
    
    
    /// A to po co?
            ADCSR&=~(_BV(ADIF));      //powinno byc raczej 
    ADCSR|=_BV(ADIF);
    
    




    Dodam że przesłuchy mam na poziomie szacunkowo 0.01%, ale to szacunkowo, a w programie nie ma żadnych opóźnień pomiędzy kanałami. Ale nie wiem na ile jest to kwestia projektu a na ile samej atmegi.
  • #21 5336932
    Aro_
    Poziom 15  
    Wejścia nie są podciągnięte, bo niby po co? Aż tak zakłóceniami sie nie przejmuje. Opóźnienia o ile pamiętam to według karty katalogowej, a bit ADIF... próbowałem z myślą że się uda. Ehh, chyba muszę jescze przestudiowac słowo w słowo kartę katalogową, albo zainstalowac bascoma.
  • Pomocny post
    #22 5337101
    trol.six
    Poziom 31  
    Po pierwsze nieużywane podciąg, robi się to bardzo prosto przez np PORTB=0xff. A po co to cię ja moge zapytać po co głowe zawracasz na forum?
    Albo jak objawiają ci się te przesłuchy pomiędzy kanałami?

    Ta deklaracja value to też byś dał zaraz po main{ żeby było ładnie.

    Daj te opóźnienia większe. Tak ze 300, nie wiem ile to jest 300 u ciebie. Więc może tutaj masz błąd.

    Reszta wygląda na w miare poprawna. Pomijając że nie zastanawiałem sie co tam sie dzieje w pętlach. Więc jeszcze tam może być jakiś niuans.

    Dodane:
    to opóżnienie możesz mieć za małe, jeżeli już to sprawdzaj czy ADC skończył konwersje tak jak pisze to snow.
  • #23 5338478
    Aro_
    Poziom 15  
    Dzięki trol.six opóźnienia faktycznie za małe. Ehh, nie byłoby w ogóle problemu i nie zawracałbym głowy na forum, gdyby nie błąd na płytce próbnej. Po prostu jedno połączenie do ADC miało dużą rezystancję. Pech chciał, że błędny program działał tak samo na płytce próbnej jak i we właściwym urządzeniu. Niestety wszystkie późniejsze próby przeprowadzałem już tylko na płytce i stąd te kłopoty. Dzięki wszystkim za pomoc:)
  • #24 11132223
    Konto nie istnieje
    Poziom 1  
  • #25 11132279
    LordBlick
    VIP Zasłużony dla elektroda
    doles napisał:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    Babol pochodzący ze schematów myślenia zakorzenionych w innym języku programowania... ;)
    Bity rejestru nie mają adresu, ma go tylko rejestr. Popraw na :
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #26 11132296
    gaskoin
    Poziom 38  
    Rozwiąż sobie takie zadanie logiczne:

    001 | 010 = ?
    111 | 101 = ?

    nigdzie nie kasujesz bitów, mierzysz z kanału 1 a następnie do końca życia z kanału 3

    Zgadnij co robi operacja REJESTR |= 0 << 3; ??
  • #27 11132310
    Konto nie istnieje
    Poziom 1  
  • #28 11132353
    gaskoin
    Poziom 38  
    doles napisał:

    111 | 101 = 111

    ...
    REJESTR |= 0 << 3; - ustawia 0 na bicie 3, czyli przesuwa 0 o 3 miejsca w lewo ?


    Musisz się zdecydować, czy 111 | 101 = 111 czy = 101 ;]

    Podpowiem, że REJSTR |= 0 << 3; nie robi kompletnie nic.
  • #29 11132396
    Konto nie istnieje
    Poziom 1  
  • #30 11132478
    gaskoin
    Poziom 38  
    Operacje bitowe jak widzę nie stanowią problemu, ale pisząc |= 0 << 3 robisz operacje OR z zerem. Czyli właściwie nic nie robisz, nie da się skasować bitu operatorem |, trzeba to zrobić andem &.

    Musisz sobie zcacheować wynik odczytu z ADC bo po jego odczycie już jest dowidzenia :)

    Nie można zrobić tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    trzeba zrobić tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
REKLAMA