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

Przerwania zewnętrzne - uC zasilany bateryjnie i wybudzanie przyciskiem

bipolunipol 12 Maj 2021 06:17 567 8
  • #1 19428928
    bipolunipol
    Poziom 19  
    Witam,

    projektuję układ z mikrokontrolerem ATTINY414 zasilany bateryjnie.
    Jego zadaniem jest cykliczne, co 3 s, wykonywanie pomiaru temperatury i obliczanie średniej.
    Ponieważ jest zasilany bateryjnie, układ będzie normalnie uśpiony i tylko co 3 s Timer wybudzi uC, aby zmierzył temperaturę i dalej się uśpił.

    Teraz mam taki problem: do urządzenia chciałbym dodać przycisk. Jego wciśnięcie spowoduje wyświetlenie bieżącej wartości średniej temperatury.
    Myślałem, aby wykorzystać przerwanie zewnętrzne. Wciśnięcie przycisku wywołuje pojawienie się zbocza opadającego na pinie uC i reakcję. Niestety jest problem drgających styków. Nie uwzględniłem tego sprzętowo (już PCB wykonana), dlatego chciałbym dodać programową obsługę. I teraz zastanawiam się nad tym, czy takie podejście jest ok:

    W procedurze obsługi przerwania od przycisku czyszczę flagę przerwania, wyłączam przerwania, aby drgające styki kolejnych nie wywoływały, czekam 20 ms, sprawdzam czy stan przycisku się nie zmienił, włączam przerwania, opuszczam procedurę.

    A może lepiej zrezygnować z przerwań zewnętrznych i użyć TIMERA, który będzie co np. 400 ms budził procesor i sprawdzał stan przycisków?
  • Pomocny post
    #2 19428986
    Steryd3
    Poziom 33  
    Myślę, że pierwsze podejście jest jak najbardziej poprawne. Chodzi o to by po pierwszym przerwaniu wystąpił jakiś czas nieczułości na kolejne przerwanie zewnętrzne. Może on być nawet znacznie dłuższy- nie sądzę by ktoś chciał klikać przycisk do wyświetlania kilka razy na sekundę. Wybudzanie mikrokontrolera cyklicznie co 400ms z pewnością nie poprawi kwestii długości pracy na baterii a i tak chyba nie bardzo by to się sprawdziło.
  • Pomocny post
    #3 19429017
    dondu
    Moderator na urlopie...
    Tak jak napisał kol. Steryd3 prawidłowo podchodzisz do zadania.

    Możesz oczywiście jeszcze pokombinować, by przez te 20ms także uśpić mikrokontroler, choć z powodu małej ilości użyć przycisku nie da to wielkich rezultatów, ale ziarnko do ziarnka ...

    Interesuje mnie natomiast z jaką częstotliwością taktujesz mikrokontroler.
    Tutaj bowiem możesz sporo zaoszczędzić.

    Przeczytaj 3 części artykułu: Bateria zasila mikrokontroler
  • Pomocny post
    #4 19429139
    BlueDraco
    Specjalista - Mikrokontrolery
    W przerwaniu przycisku blokujesz przerwanie przycisku i uruchamiasz timer sterujący wyświetlaniem, który kiedyś tam, gasząc wyświetlacz, włącza przerwanie przycisku. To "czekanie 20 ms" i powtórne sprawdzanie przycisku to jakaś magia i nie ma ani trochę sensu.
  • #5 19429168
    dondu
    Moderator na urlopie...
    BlueDraco napisał:
    W przerwaniu przycisku blokujesz przerwanie przycisku i uruchamiasz timer sterujący wyświetlaniem, który kiedyś tam, gasząc wyświetlacz, włącza przerwanie przycisku. To "czekanie 20 ms" i powtórne sprawdzanie przycisku to jakaś magia i nie ma ani trochę sensu.

    Słuszna uwaga jeśli przycisk tylko wybudzanie obsługuje.
  • #6 19429203
    ex-or
    Poziom 28  
    BlueDraco napisał:
    To "czekanie 20 ms" i powtórne sprawdzanie przycisku to jakaś magia i nie ma ani trochę sensu.

    Może zachodzi obawa wystąpienia fałszywych sygnałów od zakłóceń?
  • #7 19429866
    bipolunipol
    Poziom 19  
    BlueDraco napisał:
    W przerwaniu przycisku blokujesz przerwanie przycisku i uruchamiasz timer sterujący wyświetlaniem, który kiedyś tam, gasząc wyświetlacz, włącza przerwanie przycisku. To "czekanie 20 ms" i powtórne sprawdzanie przycisku to jakaś magia i nie ma ani trochę sensu.


    Nie wspomniałem o jeszcze jednej rzeczy. Gdy wciśnięty zostanie przycisk i włączy się wyświetlacz, tym samym przyciskiem można sobie wybrać tryb wyświetlania. Tak więc każde kolejne wciśnięcie przycisku inkrementuje zmienną trybu wyświetlania. W zależności od jej stanu pojawia się inny ekran z informacjami.

    Więc zrobiłem tak:

    Ustawienie przerwań na przycisku podpiętym do pinu PA4:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Uruchomienie przerwań:

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


    Później mam taką funkcję obsługi przerwania:

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


    Przerwanie przychodzi, sprawdzam jakie, wyłączam globalnie przerwania, czekam 30ms, sprawdzam jeszcze raz przycisk, wykonuję operacje, włączam globalnie przerwania i opuszczam procedurę obsługi przerwania.

    dondu napisał:

    Interesuje mnie natomiast z jaką częstotliwością taktujesz mikrokontroler.
    Tutaj bowiem możesz sporo zaoszczędzić.


    Gdy procesor jest uśpiony, taktuję go z wewnętrznego rezonatora 32k. Gdy nie jest uśpiony i chcę obsłużyć wyświetlacz, przełączam dynamicznie na wyższą częstotliwość 3.33 MHz (podział przez dzielnik f z 20Mhz):


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


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


    Czy takie podejście jest słuszne?
  • Pomocny post
    #8 19430384
    BlueDraco
    Specjalista - Mikrokontrolery
    Takie podejście jest fatalne. Wyłączaj przerwanie od przycisku w obsłudze tego przerwania. Włączaj je ponownie w przerwaniu timera. W praktycznie każdym urządzeniu potrzebujesz przerwania timera. Na czas uśpienia może go nie być, ale w czasie aktywności jest niezbędne. Kiedy urządzenie nie śpi, przerwanie timera odlicza wszystkie czasy i w odpowiednich momentach coś robi. Może też testować stan przycisku np. co 20 ms. Przerwanie przycisku powinno służyć wyłącznie do wybudzania.
  • #9 19430609
    bipolunipol
    Poziom 19  
    BlueDraco napisał:
    Takie podejście jest fatalne. Wyłączaj przerwanie od przycisku w obsłudze tego przerwania. Włączaj je ponownie w przerwaniu timera. W praktycznie każdym urządzeniu potrzebujesz przerwania timera. Na czas uśpienia może go nie być, ale w czasie aktywności jest niezbędne. Kiedy urządzenie nie śpi, przerwanie timera odlicza wszystkie czasy i w odpowiednich momentach coś robi. Może też testować stan przycisku np. co 20 ms. Przerwanie przycisku powinno służyć wyłącznie do wybudzania.


    A tak? Przerwanie od przycisku ustawia flagę:

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



    Wykorzystałem RTC w roli timera zgłaszającego przerwania co 4ms, tu ciąg dalszy obsługi przycisku:

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


    Na koniec następuje ponowne włączenie przerwań dla przycisku, już nie wyłączam wszystkich.

    A potem: gdy urządzenie usypia się po 8 sekundach od ostatniego wciśnięcia przycisku (realizowane jest osobne zliczanie w tej procedurze 4ms), załączony jest rezonator 32kHz, wyłączam TWI, wyłączam 4ms przerwanie od RTC. Później włączam przerwanie RTC_CNT_vect wywoływane co 3 sekundy przez RTC. Co te 3 sekundy chciałbym mierzyć wartość na ADC - wykorzystywany jest analogowy czujnik. Tylko pytanie, czy na tak niskiej częstotliwości pracy uC pomiary ADC będą dokładne?
REKLAMA