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.

xmega - blokada przerwań po wywołaniu

ele_marek 16 Lis 2015 10:53 825 8
  • #1 16 Lis 2015 10:53
    ele_marek
    Poziom 6  

    Witam
    w funkcji obsługi przerwania ISR(PORTC_INT0_vect){....
    chce zablokowań kolejne wywołanie tego przerwania, ale nie mogę i proszę o pomoc kolegów bardziej doświadczonych.
    Konfigurację przerwania zrobiłem tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Moje próby opierały się na zablokowaniu przerwania ustawiając w kodzie uruchamianym w przerwaniu:
    PORTC.PIN4CTRL=PORT_ISC_INPUT_DISABLE_gc;
    próbowałem też blokować wszystkie przerwania przez cli();
    Po wielu testach doszedłem do tego że po prostu kończąc przerwania jest przywracana zawartość rejestrów konfigurujących przerwania jak wielu innych rejestrów. Niby wiem że tak działają przerwania, ale w atmegach mogłem zatrzymać kolejne wywołania INT0 z ciała funkcji obsługującej to przerwania.

    Jeśli mam rację że w xmegach rejestry konfigurujące przerwania są przywracane do wartości z przed przerwania to jak mogę zrealizować mój cel czyli po pierwszym wystąpieniu zbocza opadającego na INT0 na kolejne zbocza nie reagować.

    Liczę na jakąś podpowiedź jak to prawidłowo się robi.
    Marek

    0 8
  • Pomocny post
    #2 16 Lis 2015 11:24
    tmf
    Moderator Mikrokontrolery Projektowanie

    cli i sei zmienią globalną flagę przerwań, blokując lub odblokowując wszystkie. Na to nakładają się priorytety przerwań kontrolera przewań i na końcu masz przerwania z danego modułu. Kolejne możesz zablokować tak jak masz, wpisując blokadę do PINCTRL lub w rejestrze kontrolnym przerwań dla danego peryferium (w tym przypadku PORT). Normalnie RETI na końcu ISR odblokowuje dany poziom przerwań w PMIC. Najprawdopodobniej nieskuteczność w twoim przypadku wynika z tego, że kolejne zbocze nadchodzi w trakcie wykonywania ISR i stan ten jest pamiętany w postaci flagi przerwania dla danego układu peryferyjnego, którą też należałoby skasować, inaczej przerwanie to zostanie obsłużone.

    0
  • #3 16 Lis 2015 12:40
    ele_marek
    Poziom 6  

    czy chodzi o rejestr PORTC.INTFLAGS to w nim mam przez zakończeniem obsługi przerwania usunąć informacje że pojawiło się kolejne zbocze?

    Dodano po 49 [minuty]:

    Moja funkcja obsługi przerwania wygląda tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    doprecyzuję że robię to na xmega16A4U,
    do portu PC2 podłączyłem analizator stanów i niestety nadal widzę prostokąt jak podam kilka zbocz na INT0 w porcie C
    O co chodzi?

    0
  • #4 16 Lis 2015 20:08
    tmf
    Moderator Mikrokontrolery Projektowanie
  • #5 17 Lis 2015 09:17
    ele_marek
    Poziom 6  

    OK to na początek napisze _wielkie dzięki_ już to uruchomiłem.
    Pierwsza podpowiedź z wyłączaniem flagi była rozwiązaniem problemu.
    Niby już tak robiłem w atmegach ale jakoś mi się zapomniało.
    Kolejne moje problemy miałem na własne życzenie ponieważ źle podłączyłem analizator i mierzyłem nie to co myślałem że mierzę:)
    Tak więc mój drugi zamieszczony kod jest już prawidłowo działający.
    Ale że jestem z tych wnikających to pozwolę sobie jeszcze na dwa pytania.
    1
    Dlaczego przed skasowaniem flagi w INTFLAGS mam skasować wyzwalanie w INT0MASK?
    Nie wystarczy zablokowanie przerwania tak jak teraz to robię:
    PORTC.PIN4CTRL = PORT_ISC_INPUT_DISABLE_gc;
    2
    Jak kasuję flagę to robię to jakoś topornie bo tak:
    PORTC.INTFLAGS = 0x01;
    choć wolałbym czytelniejszym kodem tak:
    PORTC.INTFLAGS |= (1<<INT0IF);
    tylko, że tak mi nie działa choć w kodzie na atmegę8 mogę tak kasować analogiczną flagę:
    GIFR |= _BV(INTF0);
    Czy powinienem dodać jakąś bibliotekę żeby nazwy konkretnych bitów mogły być używane?
    UWAGA:
    Dla kolegów i oczywiście koleżanek którzy są z ta wiedzą za mną:)
    Używam określenia że kasuję flagę, a z kodu wynika że wstawiam jedynkę.
    Z dokumentacji wynika że przez ustawienie flagi rozumie się wpisanie w odpowiedni bit wartości zero. Więc skasowanie to wpisanie 1.
    tme czy prawdę piszę, dobrze to rozumie i nie wprowadzam nikogo w błąd?
    Kto jak kto, ale Ty to wiesz.

    0
  • #6 17 Lis 2015 10:28
    tmf
    Moderator Mikrokontrolery Projektowanie

    ad 1. Zastanów się co się stanie jeśli pomiędzy skasowaniem flagi, a zablokowaniem pinu nastąpi zmiana jego stanu? Flaga ponownie się ustawi sygnalizując przerwanie, które zostanie obsłużone. Dlatego lepiej najpierw zablokować możliwość sygnalizowania przerwania, a dopiero potem skasować flagę.
    ad 2. Kasowanie PORTC.INTFLAGS = 0x01; jest jak najbardziej ok. Zauważ, że operacja typu |= jest operacją RMW, co niepotrzebnie wydłuża dostęp do rejestru.Właśnie dlatego flagi kasuje się wpisując 1 na odpowiednim bicie, aby dało się zrobić tylko prosty zapis - stan flag, do których wpisujesz 0 nie zmienia się. Jeśli chodzi ci o literał 0x01, to można go zapewne zamienić na symbol, pewnie nazywa się INT0F_bm, czy jakoś tak, zgodnie z konwencją nazewnictwa w XMEGA. Atmel Studio powinien coś podpowiedzieć.

    0
  • #7 17 Lis 2015 10:49
    ele_marek
    Poziom 6  

    Ale przecież ja tak robię czyli najpierw blokuje możliwość odebrania przerwania

    Kod: c
    Zaloguj się, aby zobaczyć kod

    a potem kasuję flage
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Tak to zapisałem w cytowanym kodzie nr2.
    Moje pytanie jest dlaczego lepiej jest to robić maskując przerwanie
    INT0MASK
    niż tak jak ja to robię
    Kod: c
    Zaloguj się, aby zobaczyć kod

    A może nie ma różnicy?

    0
  • #8 17 Lis 2015 11:28
    tmf
    Moderator Mikrokontrolery Projektowanie

    Efekt końcowy jest taki, że nie ma różnicy. Jednak dla porządku zablokował bym przerwanie w rejestrze MASK dlatego, że do rejestru kontrolengo pinu czasami się zapisuje coś nowego. W efekcie przypadkiem możesz odblokować konfigurację np. w związku z konfiguracją event system i nagle program zacznie wywoływać jakieś dziwne przerwania... Jak zablokujesz w MASK to konfiguracja rejestru kontrolnego jest bez znaczenia, a to co normalnie wiążesz z przerwaniem można powiązać z event system, lub po prostu zignorować tą konfigurację.

    0
  • #9 17 Lis 2015 11:38
    ele_marek
    Poziom 6  

    Super, trafia to do mnie.
    Jeszcze dzisiaj to przećwiczę.

    0