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

[ATmega32][C / Eclipse ] Obliczenia, przetwornik ADC

stevie11 28 Maj 2011 19:27 2898 22
REKLAMA
  • #1 9553771
    stevie11
    Poziom 9  
    Posty: 36
    Hej,

    Mam ustawiony przetwornik na wewnętrzne źródło 2.56V. Aby mierzyć napięcie 0-12V użyłem dzielnika napięcia. Mam problem, bo nie wiem czemu otrzymuję złe wartości w wyniku obliczeń. Otrzymuję wartość ADCW= 353, zatem wg obliczeń powinno wyjść: wynik= 353* 25* 57= 503025. Cz_d = 5, a cz_u= 03. Na wejściu mam 5V, więc wg obliczeń jest poprawnie.
    Natomiast na wyświetlaczu uzyskuję wartość 4.44..

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


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


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 9553836
    Fredy
    Poziom 27  
    Posty: 915
    Pomógł: 117
    Ocena: 28
    Spróbuj tak:

    cz_d = (uint8_t) (wynik/100000);
    cz_u =( uint8_t) ((wynik/1000) % 100);
  • #3 9553893
    stevie11
    Poziom 9  
    Posty: 36
    Niestety nadal to samo. W ogóle to pomyliłem się wyżej. Wartość wyświetlana to 0.44..
  • #4 9553929
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    w tym leży problem zapewne z typami.
  • Pomocny post
    #5 9553982
    Fredy
    Poziom 27  
    Posty: 915
    Pomógł: 117
    Ocena: 28
    a dołóż:
    wynik= (uint32_t) pm*25*57;
  • REKLAMA
  • Pomocny post
    #6 9554024
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2203
    W C domyślnie operacje i literały są traktowane tak jakby były typu int. Stąd też wynik operacji pm*25*57 jest obliczany na 16-bitach, domyślasz się więc, że liczby 503025 nie da się tak zapisać. Promocja do uint32_t następuje dopiero tuż przed operacją przypisania do zmiennej wynik, kiedy obliczona wartość już jest obcięta. Dodaj do jednego z literałów ul, np. 25ul i będzie ok.
  • REKLAMA
  • #7 9554109
    stevie11
    Poziom 9  
    Posty: 36
    Działa, dzięki wielkie :) Dodanie operatora rzutowania jak i UL zadziałały :)

    Tylko pojawił się kolejny problem. Bo jak mam akurat taką wartość 503025, to wyświetla mi wynik 5.3. Czyli pomija 0. W sumie logiczne, bo 03=3, ale.. jak zrobić, żeby to wyświetlić te 03 na lcd jako string?
    Kombinowałem coś w stylu:

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


    Ale nie poszło..
  • Pomocny post
    #8 9554169
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    bo tak działa itoa. musisz sprawdzić czy ułamkowa cześć mniejsza od 10 i wstawić 0.
  • #10 9556980
    stevie11
    Poziom 9  
    Posty: 36
    Udało się odczytać poprawnie. Jednak jak zwykle pojawił się kolejny problem. Mam w dzielniku rezystory 47Kom i 10Kom. Mam mierzyć napięcie w zakresie 0~14V. Chciałem odczytać napięcie z akumulatora (~11.5V), na dzielniku mam 2V. Jednak przetwornik zwraca mi wartość 1023, czyli w wyniku pomiaru odczytuje więcej niż te ~2.56V.. Jak mierzyłem sobie napięcie w zakresie 0-5V z zasilania mikro + zmiana wartości potencjometrem to odczytywało poprawnie.

    ATmegę mam podłączoną wg poniższego obrazka.
    [ATmega32][C / Eclipse ] Obliczenia, przetwornik ADC
  • REKLAMA
  • #11 9557015
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    Witam,

    twój schemat nie obrazuje podłączenia mierzonego napięcia do przetwornika!
    Na pewno na przetworniku masz 2V?
    Ja coś czuję, że rezystory w dzielniku odwrotnie wmontowałeś...

    Pozdrawiam,
    GSM
  • #12 9557064
    stevie11
    Poziom 9  
    Posty: 36
    Mam 2.032V.

    A podłączone tak:
    [ATmega32][C / Eclipse ] Obliczenia, przetwornik ADC
  • #13 9557116
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    To pokaż jeszcze pełen kod programu.

    Pozdrawiam,
    GSM
  • #14 9557163
    stevie11
    Poziom 9  
    Posty: 36
    Dla napięcia 0-5V, które brałem z zasilania płytki wyświetla wynik z dokładnością do 0.1V. A kod mam taki:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #15 9557703
    Fredy
    Poziom 27  
    Posty: 915
    Pomógł: 117
    Ocena: 28
    A nie dałeś podciągnięcia na wejściu pomiarowym?
    Zobacz w rejstrze PORT dla tego wejścia masz 0.
  • #16 9557765
    stevie11
    Poziom 9  
    Posty: 36
    Mam ustawione tak:

    DDRA = 0x00;
    PORTA = 0x1f;

    Na tych pinach PA0-PA4 mam klawiaturkę zrobioną. Może to coś przeszkadzać?
  • #17 9558150
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    Czy kolega rozumie słowo "pełen"?
    Utrudniasz nam możliwość niesienia jakiejkolwiek pomocy, do tego twój kod jest średnio czytelny.

    Klawiatura nie powinna przeszkadzać jeśli niczego nie sknociłeś.

    Pozdrawiam,
    GSM
  • #18 9558438
    stevie11
    Poziom 9  
    Posty: 36
    Pełen ma ok 2000 linijek + kilka oddzielnych plików, więc dałem tylko część odnośnie ADC. Jak będę w domku, to zrobię nowy program tylko z ADC i zobaczę, czy będzie to samo.

    Dobrze wiedzieć, że jest średnio czytelny. Staram się pisać, tak aby był jak najbardziej czytelny :)
  • #19 9558521
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    Chodzi o formatowanie, i dla własnego dobra nie stosuj gdzie nie potrzeba stałych liczbowych. Po to są zdefiniowane w plikach nagłówkowych nazwy rejestrów by zawsze z nich korzystać - za rok spojrzysz na ten kod i nie będziesz pamiętał co robiła jakaś liczba, a jak zobaczysz nazwę bitu/rejestru to od razu będziesz wiedział bez potrzeby głębszych rozmyślań.
    No i odstępy, zarówno pionowe jak i poziome - dla większej czytelności.

    Poza tym, w pełni popieram napisanie oddzielnego programu sprawdzającego ADC - czekam na rezultaty.

    Pozdrawiam,
    GSM
  • #20 9560038
    stevie11
    Poziom 9  
    Posty: 36
    To samo co wcześniej..

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #21 9561553
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    A jesteś pewien, że ta funkcja, wyświetlająca na LCD, dobrze działa?
    Spróbuj odczytać ADCL i ADCH zamiast całego słowa od razu.
    Może jakimś cudem upaliłeś sobie ADC? :D

    Ja jednak wciąż jestem za błędem na płytce :wink:
    Może pokaż jakieś zdjęcie?

    Pozdrawiam,
    GSM
  • #22 9561907
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    GSM napisał:
    Spróbuj odczytać ADCL i ADCH zamiast całego słowa od razu.

    GCC prawidłowo odczytuje cały ADC, więc to nie pomoże.

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


    Nigdy tak nie pisz (z użyciem delay) ponieważ gdy zmienisz częstotliwość zegara możesz mieć problemy.

    zamiast delay stosuj:

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


    To uniezależnia Ciebie od prędkości zegara i jednocześnie nie zatrzymuje procesora na zbędny czas (pomiar ADC trwa o wiele szybciej niż 100ms więc po co czekać?)


    Na schemacie widać że pin Vref podłączasz do zewnętrznego Vref - napisz coś na ten temat.
  • #23 9562189
    stevie11
    Poziom 9  
    Posty: 36
    Zrobiłem program wykorzystujący do odczytu wyników RS i tak samo jest. Dodatkowo zrobiłem to na ATmega 16. Więc nie mam pojęcia gdzie jest ten błąd..

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


    A do tego Vref nic nie podłączam. Mam na nim 2.516 czyli te źródło wbudowane.
    Korzystam z płytki uruchomieniowej ZL3AVR.

    Dokumentacja: http://www.btc.pl/pdf/zl3avr.pdf

Podsumowanie tematu

✨ W dyskusji poruszono problem z odczytem wartości napięcia z przetwornika ADC w mikrokontrolerze ATmega32. Użytkownik ustawił przetwornik na wewnętrzne źródło 2.56V i użył dzielnika napięcia do pomiaru napięcia 0-12V, jednak otrzymywał błędne wartości. Po kilku sugestiach dotyczących rzutowania typów i poprawy obliczeń, użytkownik zdołał uzyskać poprawne wyniki. Pojawił się jednak nowy problem z wyświetlaniem wartości ułamkowych na LCD, co wymagało dodatkowego formatowania. Użytkownik również napotkał trudności z pomiarem napięcia z akumulatora, które przekraczało oczekiwaną wartość. Wskazano na możliwe błędy w podłączeniu dzielnika napięcia oraz na konieczność poprawy czytelności kodu.
Wygenerowane przez model językowy.
REKLAMA