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

[xmega128a3u][int0] - PORT_ISC_LEVEL_gc - podwójne przerwanie

t__d 30 Lip 2014 07:38 1134 3
REKLAMA
  • #1 13836443
    t__d
    Poziom 10  
    Witam.

    Mam problem z kodem programu. Do pinu F5 XMegi128A3U mam podpięty przycisk wywołujący przerwanie INT0. O tak:

    [xmega128a3u][int0] - PORT_ISC_LEVEL_gc - podwójne przerwanie

    Kod włączający i konfigurujący przerwanie:

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


    I kod po wywołaniu przerwania:

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


    Problem polega na tym, że gdy przyciskam przycisk to wszystko jest ok. Wywołuje się raz przerwanie i na terminualu wyświetla się napis "on".
    Natomiast, gdy puszczam przycisk coś jest nie tak ponieważ przerwanie wywołuje się 2 razy. 2 razy wyświetla się napis "off".
    I nie chodzi tu raczej o drgania styków ponieważ nawet jak dam opóźnienie _delay_ms(1000) to i tak "off" wyświetli się zawsze 2 razy.

    [xmega128a3u][int0] - PORT_ISC_LEVEL_gc - podwójne przerwanie

    PORT_ISC_LEVEL_gc używam ze względu na to, że domyślnym stanem przycisku jest "wciśnięty" a domyślnym stanem uC uśpiony. Po zwolnieniu przycisku uC będzie się budził. A z tego co wiem budzenie możliwe jest to tylko stanem niskim. Zmiana PORT_ISC_LEVEL_gc na PORT_ISC_FALLING_gc pomaga. Ale nie mogę jej
    użyć bo chcę budzić uC.

    Poniżej screen po użyciu PORT_ISC_FALLING_gc.

    [xmega128a3u][int0] - PORT_ISC_LEVEL_gc - podwójne przerwanie

    Pytania:
    - dlaczego z PORT_ISC_FALLING_gc działa a z PORT_ISC_LEVEL_gc nie działa poprawnie,
    - jak zrobić aby z PORT_ISC_LEVEL_gc działało poprawnie ?

    pozdrawiam
  • REKLAMA
  • Pomocny post
    #2 13836534
    tmf
    VIP Zasłużony dla elektroda
    Generalnie przy LEVEL przerwania są tak długo emitowane, aż zniknie ich przyczyna, w efekcie wywoływane jest ISR i natychmiast zgłaszane jest kolejne przerwanie. Musiałbyś więc po zmianie z LEVEL na RISING jawnie kasować flagę przerwania. W większości przypadków się więc nie używa LEVEL. Piszesz strasznie skomplikowany kod - nie prościj dać BOTH_EDGES i tylko w ISR sprawdzać stan pinu, co pozwoli ustalić czy przycisk jest wciśnięty, czy nie? Co do budzenia MCU - na każdym porcie masz dwa piny mogące budzić MCU asynchronicznie.
  • REKLAMA
  • Pomocny post
    #3 13836556
    Konto nie istnieje
    Poziom 1  
  • #4 13836581
    t__d
    Poziom 10  
    Dziękuję bardzo za odpowiedzi.

    Podsumowując: Każdy port XMegi ma pin 2 asynchroniczny więc nie ma takiego zmartwienie jak na ATMedze i można spokojnie użyć BOTH_EDGES zamiast LEVEL a w ISR sprawdzić tylko stan pinu. Super :)
REKLAMA