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

[C] Attiny13 ADC Wskaźnik napięcia zasilania

mati1988k 11 Gru 2011 17:20 5339 13
  • #1 10247090
    mati1988k
    Poziom 13  
    Mam banalny problem z ADC na attince :) .
    Przedstawiony poniżej program działa tak że diody są zapalone cały czas.
    Funkcja LED_driver wysyła dane do drivera LED sct2110. Dziwne jest wg mnie to, że jak mierzę multimetrem napięcie na ADC2 to cały czas pokazuje mi 0V. No ale może jest tak, że wejście ADC ściąga napięcie do 0V?

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

    [C] Attiny13 ADC Wskaźnik napięcia zasilania

    Docelowo układ ma pokazywać napięcie zasilania latarki . Dzielnik napięcia R7 R8 jest dla tego bo napięcie zasilania będzie miało 12V.
  • #2 10247359
    excray
    Poziom 41  
    Ustawiłeś w DDRB wszystkie piny PB jako wyjścia a przecież PB4 to wejście i tak musisz je ustawić. ADC nie ściąga nic do masy, to komenda PORTB=0b00000000 ściągnęła Ci wejście do masy. Niemniej tego nie zmieniaj. Jak ustawisz DDRB=0b11101111 to powyższa komenda spowoduje że wejście nie będzie podciągane do plusa zasilania i nie będzie zawyżać wyniku.
  • #3 10247398
    mati1988k
    Poziom 13  
    No to rozwiązało to problem pomiarów na pinie PB4. Można zmierzyć wartości wejścia. Jednak diody i tak cały czas się palą. Funkcja LED_driver na pewno działa dobrze.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Sprawdziłem i na ADC mam ciągle 0.
  • #4 10247456
    excray
    Poziom 41  
    Bo się pdf'ów nie czyta. W instrukcji jest wyraźnie napisane że częstotliwość taktowania ADC powinna być nie większa jak 200kHz a Ty męczysz ADC z taktowaniem CLK/2 czyli 2,4MHz. Zapoznaj się z instrukcją strona 83 i z bitami ADPS2-0 w ADCSRA.
  • #5 10247542
    mati1988k
    Poziom 13  
    Dzięki za podpowiedź.
    Niestety po zmianie prescalera na 64:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    4.8MHz / 64 = 75KHz
  • #6 10247552
    excray
    Poziom 41  
    Mógłbyś pokazać obecny kod?
    BTW> Do czego ma służyć komenda ADC=0; ? Przeciez w pdf'ie jest napisane że ADCL i ADCH są tylko do odczytu?
  • #7 10249059
    mati1988k
    Poziom 13  
    excray napisał:
    Mógłbyś pokazać obecny kod?
    BTW> Do czego ma służyć komenda ADC=0; ? Przeciez w pdf'ie jest napisane że ADCL i ADCH są tylko do odczytu?


    Widziałem to w jakimś samouczku. Ale już to wywaliłem.

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


    EDIT:

    Teraz działa jednak nie jestem usatysfakcjonowany bo nie wiem czemu :). Przed pomiarem muszę włączyć też bit ADIF.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #8 10249256
    excray
    Poziom 41  
    ADIF jest flagą dla przerwań. W ogóle nie musisz i nie powinieneś z niego korzystać przy takim sposobie pracy. Normalnie po ustawieniu flagi ADSC sprawdzasz czy jest dalej ustawiona. Po zakończonej konwersji ADC ją zeruje.
    Cytat:
    Bit 6 – ADSC: ADC Start Conversion
    In Single Conversion mode, write this bit to one to start each conversion. In Free Running mode,
    write this bit to one to start the first conversion. The first conversion after ADSC has been written
    after the ADC has been enabled, or if ADSC is written at the same time as the ADC is enabled,
    will take 25 ADC clock cycles instead of the normal 13. This first conversion performs initializa-
    tion of the ADC.
    ADSC will read as one as long as a conversion is in progress. When the conversion is complete,
    it returns to zero.
    Writing zero to this bit has no effect.
    Spróbuj poniższego kodu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #9 10249295
    mati1988k
    Poziom 13  
    Działa!
    Dzięki wielkie :)
  • #10 10249772
    SylwekK
    Poziom 32  
    Ja na co innego chciałem zwrócić uwagę... Jeśli dzielnik na wejściu adc ma Ci badać stan akumulatora to jest duże prawdopodobieństwo,ze szybko uwalisz port. Wyliczony jest dokładnie na 12V i nic więcej, a to ryzykowne posunięcie. Jeśli badane jest napięcie aku to dałbym mu bezpieczny zakres na min 14,5-15V.
  • #11 10260294
    mati1988k
    Poziom 13  
    SylwekK dzięki za radę, ewentualnie można chyba też dać diodę zenera 5.1V albo 4.7 łączącą linię pomiarową z GND.

    Teraz mam nowy problem z ADC postanowiłem zrobić auto trigger na timer0. I z tego co rozumiem on będzie wyzwalał konwersję, a pomiar powinienem odczytać w przerwaniu ADC_vect, czyli przerwanie które się włącza gdy zostanie zakończona konwersja. Mam taki kodzik testowy który po wejściu w przerwanie ADC_vect ustawia a na 1 i zapala diody. Niestety nic się nie dzieje :).

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #12 10260586
    excray
    Poziom 41  
    Na pewno zmienną pomiar i a musisz zadeklarować jako volatile. Ustawień nie patrzyłem na razie.
  • #13 10260632
    mati1988k
    Poziom 13  
    Zadziałało. Dzięki :)

    Dodano po 10 [minuty]:

    Jednak nie działa. Tylko raz odczytuje wartość przy resecie procka.
  • #14 10261244
    excray
    Poziom 41  
    Bo nie zerujesz flagi przerwania. Podczas porównania ustawia Ci się flaga przerwania OCF0A w TIFR0. Normalnie w czasie obsługi przerwania taka flaga się kasuje samoistnie ale u Ciebie nie ma obsługi przerwania od Timer/Counter Compare Match A więc flaga zostaje ustawiona. Musisz w obsłudze przerwania od zakończonej konwersji ADC dołożyć ręczne kasowanie tej flagi poprzez wyzerowanie bitu OCF0A w TIFR0.

    EDIT> A nie lepiej jest Ci pracować w trybie Free Running mode i w obsłudze przerwania od zakończonej konwersji ustawiać bit ADSC do rozpoczęcia kolejnej konwersji?
REKLAMA