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 2751 22
REKLAMA
  • #1 9553771
    stevie11
    Poziom 9  
    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  
    Spróbuj tak:

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

    w tym leży problem zapewne z typami.
  • REKLAMA
  • Pomocny post
    #5 9553982
    Fredy
    Poziom 27  
    a dołóż:
    wynik= (uint32_t) pm*25*57;
  • Pomocny post
    #6 9554024
    tmf
    VIP Zasłużony dla elektroda
    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.
  • #7 9554109
    stevie11
    Poziom 9  
    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  
    bo tak działa itoa. musisz sprawdzić czy ułamkowa cześć mniejsza od 10 i wstawić 0.
  • #9 9554214
    tmf
    VIP Zasłużony dla elektroda
    Jeśli masz dużo FLASH (tak ze 1,5kB) to prościej wykorzystać sprintf, który potrafi formatować ciągi wg zadanego wzorca.
  • REKLAMA
  • #10 9556980
    stevie11
    Poziom 9  
    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
  • #11 9557015
    GSM
    Poziom 25  
    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  
    Mam 2.032V.

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

    Pozdrawiam,
    GSM
  • #14 9557163
    stevie11
    Poziom 9  
    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  
    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  
    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  
    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
  • REKLAMA
  • #18 9558438
    stevie11
    Poziom 9  
    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  
    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  
    To samo co wcześniej..

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #21 9561553
    GSM
    Poziom 25  
    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
    Moderator na urlopie...
    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  
    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
REKLAMA