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 - usypianie AVR w przerwaniu

r0bby 14 Paź 2014 18:11 1140 8
REKLAMA
  • #1 14041251
    r0bby
    Poziom 9  
    Cześć,

    Jest układ na Atmedze z timerem2 w trybie asynchronicznym realizującym RTC. Zależnie do stanu pinu kontrolowanego przez przerwanie INT2 układ ma albo działać normalnie, albo w uśpieniu (dokładniej na INT2 zrobioną mam detekcję zera sieci zasilającej i dodatkowo byłby to wskaźnik istnienia zasilania w ogóle). Timer2 musi pracować non-stop.

    I czegoś tu nie łapię. Wprowadzam układ w stan uśpienia w tryb SLEEP_MODE_PWR_SAVE, tyle że przerwanie od Timera2 wybudza go po sekundzie (PRAWIDŁOWO) i dalej już układ działa w trybie wybudzenia. Chciałbym aby przerwanie od Timera2 spowodowało tylko wykonanie procedury jego obsługi i układ wrócił w uśpienie. Całkowite wybudzenie następowałoby po wykonaniu sleep_disable(); w obsłudze przerwania INT2.

    Wydawało mi się, że wystarczy w końcu obsługi przerwania od TIMER2 wykonać sleep_mode() ale wtedy układ w ogóle nie działa (nigdzie nie mogę wyczytać, że sleep_mode() nie może być wykonane w przerwaniu).
  • REKLAMA
  • #2 14041308
    vonar
    Poziom 28  
    Wersja z usypianiem w przerwaniu nie działa, gdyż w czasie wykonywania procedury obsługi przerwania flaga I w SREG jest skasowana – przerwania są zablokowane, więc procesor się nie wybudzi z uśpienia.
  • REKLAMA
  • #3 14041343
    r0bby
    Poziom 9  
    Jeśli wstawiłem sleep_mode() w procedurę obsługi przerwania TIMER2_OVF (przed samym powrotem z przerwania) to nic nie działało, łącznie z tym przerwaniem. Poza tym, w trybie uspienia SLEEP_MODE_PWR_SAVE przerwanie od TIMER2 jak i od INT2 jest wykonywane.
  • REKLAMA
  • #4 14041359
    vonar
    Poziom 28  
    r0bby napisał:
    Jeśli wstawiłem sleep_mode() w procedurę obsługi przerwania TIMER2_OVF (przed samym powrotem z przerwania) to nic nie działało, łącznie z tym przerwaniem.
    Z powodu opisanego przeze mnie w poprzednim poście.

    Stwórz globalną flagę (z kwalifikatorem volatile!) np. uspienie i ustawiaj/kasuj ją w procedurze obsługi przerwania INT2, a w pętli głównej zależnie od jej wartości w pętli usypiaj procesor lub nie, tzn.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #5 14041405
    r0bby
    Poziom 9  
    W głównej pętli program robi jeszcze kilka innych rzeczy, a przerwanie TIMER2 może być wykonane w dowolnym momencie i tym samym powrót z tego przerwania również może nastąpić na każdym etapie wykonywania programu. Każdą instrukcję w programie musiałbym przeplatać z sleep_cpu() aby znowu wejść w uśpienie.
  • #6 14041411
    vonar
    Poziom 28  
    r0bby napisał:
    I czegoś tu nie łapię. Wprowadzam układ w stan uśpienia w tryb SLEEP_MODE_PWR_SAVE, tyle że przerwanie od Timera2 wybudza go po sekundzie
    To w którym miejscu w końcu wprowadzasz (za pierwszym razem) CPU w uśpienie?
  • #7 14041465
    r0bby
    Poziom 9  
    Chciałem zrobić tak jak pisałeś - tzn. na podstawie flagi z przerwania INT2 na początku pętli głównej wchodzić w uśpienie. Ale pętla główna jest wykonywana powiedzmy 0.5 sek. Co sekundę wykonywane jest przerwanie od Timer2. Więc procesor będzie w uśpieniu tylko ok. 50% czasu.

    Może coś źle rozumiem, ale jedynym sensownym miejscem na uśpienie procka, żeby działało to tak jak chcę, byłoby przerwanie TIMER2.
  • Pomocny post
    #8 14041529
    vonar
    Poziom 28  
    r0bby napisał:
    na podstawie flagi z przerwania INT2 na początku pętli głównej wchodzić w uśpienie. Ale pętla główna jest wykonywana powiedzmy 0.5 sek. Co sekundę wykonywane jest przerwanie od Timer2. Więc procesor będzie w uśpieniu tylko ok. 50% czasu.
    Ale problem z długim wykonywaniem się pętli głównej wystąpi tylko za pierwszym razem po zaniku zasilania (ustawienie flagi wskazującej konieczność uśpienia). Później sterowanie pozostanie w "pętli usypiającej" aż do skasowania flagi.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #9 14041588
    r0bby
    Poziom 9  
    Faktycznie :) Masz rację :) Dzięki :)
REKLAMA