Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

ATmega8A-PU - Przerwanie podczas przerwania?

ksztanan 09 Sty 2013 21:01 1224 4
  • #1 09 Sty 2013 21:01
    ksztanan
    Poziom 7  

    Witam wszystkich,
    mam następujące pytanie: czy podczas wykonywania procedury przerwania (ATmega8A-PU, przerwanie INT0) procesor pozostaje kompletnie "głuchy" na inne przerwania tego samego typu? Czy może gdzieś zapamiętuje kolejne próby wywołania do późniejszego wykonania?

    Wywołuję przerwanie stanem niskim z komparatora analogowego, który to komparator dostaje sygnał napięciowy z piezo. Celem reagowania tylko na pierwszy pik ustawiam w przerwaniu opóźnienie dłuższe niż najdłuższy czas wygasania oscylacji z piezo. W przerwaniu inkrementuję zmienną licznikową tylko raz, jednak przy sygnałach o wysokiej amplitudzie zwiększa mi się ona o 2-3. Stąd moje podejrzenie o "zapamiętywaniu" kolejnych przerwań do wykonania.

    z góry dziękuję za pomoc, mam nadzieję, że wyraziłem się dość jasno

    0 4
  • Pomocny post
    #2 09 Sty 2013 21:19
    Steryd3
    Poziom 31  

    Podczas wykonywania programu obsługi przerwania w mikrokontrolerach AVR zgłoszenie przerwania tego samego typu ( lub innego) zostaje przyjęte do realizacji. Zostanie zrealizowane po zakończeniu obsługi bieżącego przerwania(nie koniecznie natychmiast). Jeżeli w trakcie przerwania zostaną zgłoszone 2 przerwanie różnego typu to po zakończeniu obsługi tegoż wywołana będzie obsługa tego którego wektor znajduje się w pamięci bliżej adresu 0. Jeżeli podczas wykonywania obsługi przerwania( INT0 lub innego) zgłoszone zostanie kilka przerwań tego samego typu (np. 2 lub więcej razy INT0 ) to po zakończeniu obsługi tego przerwania obsługa przerwania zgłoszonego kilkakrotnie zostanie wykonana tylko raz. AVRy nie mają zaimplementowanej obsługi wywłaszczania przerwań(przerywanie przerwań) -można to uzyskać programowo umieszczając na początku programu obsługi przerwania którego dopuszczamy wywłaszczanie globalne odblokowanie systemu przerwań sei();

    0
  • #3 09 Sty 2013 22:08
    ksztanan
    Poziom 7  

    Wielkie dzięki. A da się jakoś wyczyścić (ew. zablokować) to przerwanie? Próbowałem juz wpisywać w procedurze przerwania cli(), wyłączać INT0 w rejestrze GICR, ustawiać flagę w GIFR. Póki co z marnym skutkiem.

    0
  • #4 09 Sty 2013 22:15
    Fredy
    Poziom 27  

    ksztanan napisał:
    Wielkie dzięki. A da się jakoś wyczyścić (ew. zablokować) to przerwanie? Próbowałem juz wpisywać w procedurze przerwania cli(), wyłączać INT0 w rejestrze GICR, ustawiać flagę w GIFR. Póki co z marnym skutkiem.


    możesz zarówno zarówno zablokowac każde przerwanie z osobna, a także wyczyścić flagę od ich zgłoszenia. Możesz to uczynić także w przerwaniu.
    Tylko uważaj, w AVR kasowanie flag od przerwań odbywa się poprzez wpisanie jedynki do odpowiedniego rejestru. Czyli aby skasować to trzeba ustawić :D

    0
  • #5 10 Sty 2013 06:20
    Steryd3
    Poziom 31  

    Dokładnie tak jak pisze Fredy. Z pewnością po zastosowaniu jego rad twój problem zostanie zlikwidowany. Nie mniej jednak ogólna strategia programowania mikrokontrolerów (mikroprocesorów) mówi, że program obsługi przerwania powinien wykonać się maksymalnie szybko. Jeżeli twój program nie robi wiele więcej Twoje rozwiązanie z poprawkami zaproponowanymi przez Fredy będzie działać ale gdyby ten program miał robić coś więcej to proponuje przebudowanie programu. Proponuje skorzystanie z kolejnego układu na pokładzie ATmega8 tj licznika.
    Program w opisie słownym mógł by działać następująco:
    Pierwsze przerwanie od INT0 niech włączy licznik który po wymaganym czasie twojego opóźnienia zgłosi przerwanie. Niech przerwanie INT0 dodatkowo inkrementuje zmienną mówiącą ile razy to przerwanie wystąpiło. W obsłudze przerwania od licznika wyłącz licznik, obsłuż zmienne mówiące o zaistniałym zdarzeniu oraz wyzeruj zmienną mówiącą o ilości wystąpień przerwania INT0. Program obsługi INT0 niech włącza licznik jeżeli zmienna zliczająca liczbę wystąpień przerwanie INT0 jest równa 0.

    0