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

Attiny2313 konfiguracja watchdoga i wybudzanie uC z trybu uśpienia

dejmos 17 Maj 2022 10:06 729 9
  • #1 20022264
    dejmos
    Poziom 23  
    Witam.
    Po krótce. Mam urządzenie zbudowane na Attiny2313 zasilane indukcyjnie. Działa to na takiej zasadzie, że kondensatory zasilające ładują się, procesor się włącza, wykonuje jakieś operacje, które trwają około 1s i tyle.
    Chodzi o to, że kilka lat nie programowałem a potrzebuję na szybko coś zmienić, dlatego proszę Was o pomoc.
    Chodzi o to, żeby uśpić procka na około 200ms tak aby na kondensatorach napięcie osiągnęło odpowiednią wartość i następnie wybudzić procka watchdogiem oraz wyłaczyć zbędne moduły aby pobór energii był jak najmniejszy.
    Próbuję to ogarnąć, ale jakoś mi nie idzie ☹
    Chodzi o to aby napisać taką sekwencję:
    Procesor się włącza;
    Jest usypiany na 200ms;
    Zostaje wybudzony przez watchdoga;
    Watchdog zostaje wyłączony;
    Poniżej wykresy ładowania kondensatorów podczas normalnej pracy procka z wykorzystaniem tylko funkcji delay() w celu oczekiwania na naładowanie kondensatorów.
    Drugi to wykres po wprowadzeniu procesora w SLEEP_MODE_STANDBY
    Po prostu nie potrafię skonfigurować WDT tak aby wybudził procek po 200 ms
    Ktoś pomoże? Z góry dziękuję.

    Attiny2313 konfiguracja watchdoga i wybudzanie uC z trybu uśpienia Attiny2313 konfiguracja watchdoga i wybudzanie uC z trybu uśpienia
  • Pomocny post
    #2 20023037
    mpier
    Poziom 29  
    Witam,
    problemem może być to 200ms, bo według dokumentacji najbliższe są 125ms lub 250ms z odpowiednią tolerancją. Spróbuj ustawić watchdoga i włączyć odpowiedni tryb sleep (może być POWER OFF) i spradź czy zadziała. Pamiętaj, że watchdog będzie ciągle włączony, jeśli wcześniej był powodem resetu.
    Dokumentacja do avr/wdt.h i avr/sleep.h powinna wyjaśnić więcej.

    Pozdrawiam.
  • Pomocny post
    #3 20023282
    bart-projects
    Poziom 29  
    Konfigurujesz WD na 256 i startujesz.
    Teraz jeśli chcesz by WD wybudził procesor, ale go nie zresetował to MUSISZ włączyć przerwanie od WD. W obsłudze przerwania nie musisz nic robić. Procek wroci w miejsce gdzie użyłeś SLEEP. Teraz jeśli możesz przez tę sekundę kiedy pracuje resetować WD co 200ms to nic nie trzeba robić, ale jesli coś tam dłuzej trwa to można przekonfigurować WD na 1024/2048/4096 czy 8192 cykle.

    Robisz co chcesz zrobić i konfigurujesz na 256. Teraz NAJWAŻNIEJSZE. Przerwanie od WD TRZEBA włączać za każdym razem przed komendą SLEEP bo wejscie w przerwanie automatycznie kasuje bit który zezwala na przerwanie i następny okres WD po prostu bez tego zresetuje uC.
  • #4 20023763
    dejmos
    Poziom 23  
    Wstawiłem coś takiego:
    [syntax=c]
    
    int main(void)
    {
       set_sleep_mode(SLEEP_MODE_STANDBY);									//ustaw uśpienie na STANDBY
    	ACSR |= (1<<ACD);       											// wyłącz przetwornik ADC
    	cli();
    	wdt_enable(WDTO_250MS);
    	sleep_mode();
    	wdt_reset();
    	sei();
    
    // pozostała część programu który ma się wykonać
    //w między czasie resetuję wdt
    
    
          while(1) wdt_reset();
    }
    
    ISR(WDT_OVERFLOW_vect){}
    
    [/syntax]


    Procesor zamiast wyjść z trybu uśpienia resetuje się. Co jest nie tak?
  • Pomocny post
    #5 20023808
    ex-or
    Poziom 28  
    bart-projects napisał:
    Przerwanie od WD TRZEBA włączać za każdym razem przed komendą SLEEP bo wejscie w przerwanie automatycznie kasuje bit który zezwala na przerwanie i następny okres WD po prostu bez tego zresetuje uC.

    Tak jest w trybie Interrupt+Reset, wtedy pierwsze przepełnienie odpala przerwanie a drugie i następne reset. W trybie Interrupt bit WDIE nie jest kasowany.

    Co jest nie tak? Procek wchodzi w uśpienie z wyłączonymi przerwaniami, poza tym brakuje ustawienia trybu pracy watchdoga. Chyba (nie pamiętam a nie mam możliwości zajrzeć w źródła) w avr/wdt.h nie ma makra do ustawiania trybu Interrupt więc trzeba pożonglować bitami.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #6 20023825
    bart-projects
    Poziom 29  
    Jeśli WD ma być "tylko" do budzenia to się zgodzę. Przyzwyczaiłem się WD zostawiać sobie też dla bezpieczeństwa aplikacji.

    Cytat:
    If WDE is set, the Watchdog Timer is in Interrupt and System Reset Mode. The first time-out in
    the Watchdog Timer will set WDIF. Executing the corresponding interrupt vector will clear WDIE
    and WDIF automatically by hardware (the Watchdog goes to System Reset Mode). This is use-
    ful for keeping the Watchdog Timer security while using the interrupt. To stay in Interrupt and
    System Reset Mode, WDIE must be set after each interrupt.


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


    Mam taki odstaszacz do kretów i żeby spał na mikroamperach ale działał ciagle to sekwencja jest taka:

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


    Żeby cokolwiek zmienić w WD potrzebna jest specjalna procedura krytyczna czasowo. Najpierw ustawia się bit Change Enable i w 4 taktach trzeba ustawić co się chce.
  • #7 20024185
    dejmos
    Poziom 23  
    Napisałem takie funkcje:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    I wywołuję je w zależności od potrzebnego czasu w miejscach gdzie procesor nic nie robi. Działa to całkiem dobrze tak że dziękuję za pomoc. A tak na marginesie można zmieniać ustawienia watchdoga w programie w zależności od potrzeb tak jak ja to zrobiłem?
  • Pomocny post
    #8 20024225
    bart-projects
    Poziom 29  
    Mozna spokojnie. U siebie (tez Tiny2313) zmieniam podczas pracy nawet taktowanie.
    Jeśli uC u mnie pracuje na 8MHz bo musi wygenerować rózne wysokie częstotliwości to podczas snu brał 2mA.
    Teraz przed uśpieniem dobieram się do rejestru CLKPR - Clock Prescale Register.
    Zasada przestawiania jest podobna jak w WD. Trzeba najpierw ustawić CLKPCE: Clock Prescaler Change Enable
    Zwalniam sobie uC o ile chcę od /2 do /256 i dopiero usypiam.
    WD ma swój osobny oscylator więc to na czasy nie wpływa, ale za to uC bierze około 1uA (mikro a nie mili).
    Po pobudce ustawia się Prescale = 1 czyli nic.
  • Pomocny post
    #9 20024232
    ex-or
    Poziom 28  
    dejmos napisał:
    WDTCSR |= (1<<WDCE) | (1<<WDE);
        WDTCSR &= ~(1<<WDP2) & ~(1<<WDP1) & ~(1<<WDP0);
        WDTCSR |= (1<<WDIE) | (1<<WDP0); ////ustaw wdt na 0,032s


    Read-Modify-Write jest tu niepotrzebne i stwarza ryzyko że konfiguracja się nie powiedzie ponieważ...
    bart-projects napisał:
    Żeby cokolwiek zmienić w WD potrzebna jest specjalna procedura krytyczna czasowo. Najpierw ustawia się bit Change Enable i w 4 taktach trzeba ustawić co się chce.

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


    Dodano po 10 [minuty]:

    bart-projects napisał:
    Jeśli uC u mnie pracuje na 8MHz bo musi wygenerować rózne wysokie częstotliwości to podczas snu brał 2mA.

    Jeżeli w głębokim uśpieniu procek bierze 2mA to znaczy że tak naprawdę się nie uśpił albo jest płytko uśpiony (IDLE).
REKLAMA