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

[atmega8][c] Problem z odczytem róznych wejść ADC...

trelek 18 Lut 2010 16:01 2136 5
  • #1 7713795
    trelek
    Poziom 14  
    Witam,

    Od wczoraj zmagam się z przetwornikiem. Odczyt z jednego kanału mam opanowany :D
    Ale schody zaczęły się gdy chce odczytać dane z kilku kanałów.

    Na początku wpisywałem wartości rejestrów ADCSRA i ADMUX w postaci 0b11111111, bo tak mi wygodniej i ten zapis rozumiem. Ale wyczytałem gdzieś na elce, że to może być błędem, no wiec teraz ryzykuje zapisem - dla mnie extremalnym : _BV(ADEN). Ale to nie pomaga, wraz jest problem i wyświetlacz pokazuje dane z portu ADC2 - chodź powinien pokazać z ADC0, mało tego ten pomiar jest "migajacy" na zmianę z zerem.

    Obu tych pomiarów będę używał później do działania moc=napiecie*prad, jednak na nic to, kiedy nie potrafię odczytać dwóch kanałów... :/

    Jeśli ktoś mógłby pomóc, będę bardzo wdzięczny, kod mojego programu:

    int main(void)
    {   
       DDRD = 0xff;
       DDRB = 0xff;
       DDRC = 0x00;
    
         ADCSRA = _BV(ADEN) |_BV(ADPS0)|_BV(ADPS1);
    
          int napiecie=0;
          int prad=0;
    
    while(1){
    
            ADMUX=34;
            ADCSRA |= _BV(ADSC);
            napiecie=ADCH;
    
            ADMUX=32;
            ADCSRA |= _BV(ADSC);
            prad=ADCH;
    
            wyswietl(napiecie);
    	}
    }
  • Pomocny post
    #2 7714064
    morson
    Poziom 14  
    Problem jest prosty uruchamiasz przetwornik, ale nie czekasz na to, aż zakończy przetwarzanie, a to chwilę trwa.
    
            ADMUX=34;
            ADCSRA |= _BV(ADSC);
            while(ADCSRA & _BV(ADSC)); // oczekiwanie na zakończenie konwersji
            napiecie=ADCH;
    
            ADMUX=32;
            ADCSRA |= _BV(ADSC);
            while(ADCSRA & _BV(ADSC));
            prad=ADCH;
    
            wyswietl(napiecie);
    


    Przy jednym wejściu ADC odczytywałeś poprostu starą zawartość.
  • #3 7714253
    trelek
    Poziom 14  
    Dziękuję kolego! :)

    na razie projekt ruszył, jak by coś jeszcze wynikło będę pytał, na razie, jeszcze raz Dzięki :)

    Dodano po 1 [godziny] 32 [minuty]:

    no i jest kolejny problem, otóż jak widać w programie odczytuje ADCH, więc moja rozdzielczość wynosi 255.
    1) Teraz jak chcę odczytać cały rejestr w GCC po prostu wklepuje ADC, zamiast ADCH? by mieć rozdzielczość1024?
    bo jeśli tak robię to na wyświetlaczu jest 0, albo er.

    Aha, wyświetlacz mam swój. To znaczy jest to 4x 7segmentowy wyświetlacz z budzika, wczoraj napisałem do niego sterownik, wyświetla liczby całkowite od 0-999, gdy jest coś innego wyświetla skromne Er. I w jednej linijce programuwynik mnożę *100 by przesunąć przecinek i z 4,33 zrobić 433 - żebym mógł wyswietlić :)

      int napiecie=0;
      float w=0;
      int prad=0;
      float pom=0;
    
         while(1){
    
              ADMUX=0x00;
              ADMUX= _BV(REFS1)| _BV(REFS0) | _BV(ADLAR);
              ADCSRA |= _BV(ADSC);
              while(ADCSRA & _BV(ADSC)); // oczekiwanie na zakończenie konwersji
              w=ADC;
    
    
              pom=((w*4.82)/1024)*100; // w tym miejscu *100 to dopasowanie do wyswietlacza, 4.82orientacyjne napiecie ref.
              //pom=((w*4.82)/255)*100;
              napiecie=pom;          // float => int, odcina wszystko po przecinku
    
              wyswietl(napiecie);    //wyswietla int'a


    Urządzenie docelowo to miernik mocy (U*I) wiec dokonuję pomiaru Napięcia i prądu jak na schemacie:
    [atmega8][c] Problem z odczytem róznych wejść ADC...
    I pojawia się problem, bo gdy brak obciążenia (Rl) pomiar napięcia jest bardzo dobry - wręcz zgodny z miernikiem, jednak gdy dołączę obciążenie - wentylator PC, pomiar znacznie rozjeżdża się z tym wskazanym przez miernik(spadek napięcie miedzy masą a dzielnikiem(PC0)). Dodam, że linijka odpowiedzialna za ten pomiar to zakomentowana linia:

    //pom=((napiecie*4.82)/255)*100;


    2) Czy moje podłączenie jest w porządku?
  • Pomocny post
    #4 7716412
    regrom
    Poziom 16  
    Problemem może być napięcie referencyjne, jeśli nie jest odpowiednio podłączone może pływać, np. zmienić się pod obciążeniem jeśli zasilasz z niego układ czy coś tam jeszcze. Stąd różnice w pomiarach.

    Użyj może wewnętrznego 2,54 V , ale musisz też dzielnik zmienić, mam nadzieje że o kondensatorach jak najbliżej ATmegi nie zapomniałeś?

    2) podłączenie raczej ok jeśli chodzi o ADC, tylko czy tak trudno jest wrzucić obrazek na serwer elektrody?

    1) A co do wartości ADC, to tak, możesz użyć np. ADCW - i przypisać do zmiennej,w tym zapisie masz zawarte ADCH i ADCL, poczytaj też o ADLAR - wyrównanie do lewej, możesz też użyć unii w C, ale po co skoro masz to w zapisie ADCW.

    Sam się nad tym głowiłem :) Warto przeczytać , [ATmega8][C] ADC - wartość, krótkie pytanie.
  • #5 7722239
    trelek
    Poziom 14  
    Dzięki regrom,
    co do napięcia ref. walcze z tym 2,5V, ale jak bym nie ustawiał ADMUX'a zawsze mam zakres referencyjny 5V... nie wiem dla czego, przecież dla wew. ref. powinno być 2,5V... ech... Podejrzewam, że mogłem uwalić ADC, bo na jednym wyjściu ADC1 mam pomiar logarytmiczny.. więc wnioskuję, ze to uszkodzony ADC, bo żadnych rejestrów na log. nie zmieniałem...(a chyba jest takie coś, jakoś i się kojarzy, że gdzieś w datasheecie mi się obiło....)

    A co do ADCW, na dniach mam dostać 2x16 więc będzie łatwiej testować, bo z moim sterownikiem widzę tylko eR więc nie wiem czego biedak nie może wyświetlić :)
  • #6 7722467
    morson
    Poziom 14  
    Prawdopodobnie uszkodzileś wewnętrzne źródło napięcia odniesienia (tym zwarciem do masy).
    Napięcie Ci się rozjeżdża, bo nie odejmujesz spadku napięcia na rezystorze do pomiaru prądu, a ono Ci pomniejsza napięcie wyjściowe.
    Do pomiaru nie potrzebujesz float'a wystarczy
    
    uint32_t pomiarU, pomiarI;
    ...
    pomiarU = ADC;
    pomiarU = pomiarU * 4820 / 1024 * 5; // i wynik masz w mV
    ...
    pomiarI = ADC
    pomiarI = pomiarI * 4820 / 1024; // spadek napięcia na Rpom
    pomiarU -= pomiarI;
    pomiarI /= 3; // prąd w mA (/3 lub *3)
    


    To chyba wszystkie wyliczenia.
REKLAMA