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

dziwne zachowanie przerwania INT2

maqister 01 Paź 2011 14:40 2090 3
REKLAMA
  • #1 9981927
    maqister
    Poziom 10  
    Witam szanownych użytkowników,

    Programuję mikrokontroler ATmega32, mam problem z przerwaniem INT2, które po starcie urządzenia się odpala mimo, że nie puszczam sygnału wyzwalającego przerwanie.

    Ponieważ projekt jest za duży, żeby zamieścić go w całości zamieszczam tylko najważniejsze fragmenty, a dodatkowo dodam plik .ZIP ze spakowanym projektem, który można odpalić w AVR Studio.



    Kod: text
    Zaloguj się, aby zobaczyć kod


    OPIS PROBLEMU:
    Program startuje inicjalizuje różne moduły (USART, PWM, PORTY) - wszystko działa doskonale i było testowane.

    Program sam w sobie pracuje w pustej pętli, z której tylko wyskakuje do obsługi przerwań. Kiedy dodałem obsługę przerwań INT0,1,2 nadal wszystkie moduły działają doskonale, przerwania reagują w czasie pracy właściwie, jednak zaraz po wystartowaniu mikrokontrolera odpala mi się przerwanie INT2 - nie rozumiem dla czego. Jak widać w obsługach przerwań zewnętrznych zrobiłem ustawienie stanu wysokiego na pewnych pinach do których mam podłączone diody. Przerwanie INT0 i INT1 działają zgodnie z moim zamiarem, a przerwanie INT2 - prawie. Kiedy już mikrokontroler pracuje po starcie, mogę to przerwanie wywoływać tak jak zamierzałem. Chciałbym pozbyć się tego efektu, że przerwanie jest odpalane zaraz po starcie.

    Dodam jeszcze moje spostrzeżenie. W dokumentacji mikrokontrolera ATmega32 było, że należy ustawić piny INT0, INT1, INT2 jako wyjścia. Kiedy zakomentowałem te linie kodu:
    	sbi DDRD, 2			; noga INT0 jako wyjście
    	sbi PORTD, 2		; noga PD2 w stanie wysokim
    	sbi DDRD, 3			; noga INT1 jako wyjście
    	sbi PORTD, 3		; noga PD3 w stanie wysokim
    	sbi DDRB, 2			; noga INT2 jako wyjście
    	sbi PORTB, 2		; noga PB2 w stanie wysokim


    problem nadal występował, jednak samoczynne wyzwolenie przerwania INT2 po resecie odbywa się nieco później.


    Najbardziej mnie denerwuje, że INT0 i INT1 działają dobrze tylko INT2 nawala, bo skoro umiałem skonfigurować INT0 i INT1 dlaczego z INT2 się nie udało?

    Proszę o rady.
  • REKLAMA
  • Pomocny post
    #2 9982125
    krzych41
    Poziom 15  
    !. Ustaw PIN-y INT jako wejścia z podciąganiem.
    2. Tuż przed aktywacją przerwań wyzeruj ich flagi wpisując logiczne 1.
  • REKLAMA
  • Pomocny post
    #3 9982541
    Konto nie istnieje
    Poziom 1  
  • #4 9982607
    maqister
    Poziom 10  
    Witam problem rozwiązany,

    najpierw zastosowałem rozwiązanie które podsunął krzych41 - działało.

    Zastanawiało mnie jednak skąd on to wytrzasnął, więc przejrzałem noty atmela w poszukiwaniu not dotyczących przerwań zewnętrznych, a następnie przeczytałem jeszcze raz bardzo dokładnie dokumentacje. Okazało się, że wczorajsze czytanie dokumentacji na siłę na mega zmęczeniu nic mi nie dało i kod przezemnie wytworzony był błędny.

    Po pierwsze tak jak napisał emarcus źle zrozumiałem tamten fragment, a po drugie pominąłem najważniejszy fragment w całym dziale EXTERNAL INTERRUPTS dokumentacji ATmegi32.

    dziwne zachowanie przerwania INT2

    Niepoprawne konfigurowanie bitu ISC2, może wywoływać właśnie taki efekt jaki mnie prześladował.

    Odpowiednia kolejność działania, jeżeli chcemy poprawnie skonfigurować przerwanie INT2 jest następująca:
    1) dezaktywacja przerwania INT2
    2) następnie możemy skonfigurowac bit ISC2
    3) wyzerowanie flagi przerwania INT2
    4) aktywacja przerwania INT2

    dzięki temu wytworzyłem kod który działa poprawnie, dziękuję wam za pomoc, była bardzo przydatna.

    INT_EXT_INIT:
    	push ACC
    	push ACC2
    
    	cbi DDRD, 2			; noga INT0 jako wejście
    	sbi PORTD, 2		; włączony rezystor podciągający
    	cbi DDRD, 3			; noga INT1 jako wejście
    	sbi PORTD, 3		; włączony rezystor podciągający
    	cbi DDRB, 2			; noga INT2 jako wejście
    	sbi PORTB, 2		; włączony rezystor podciągający	
    
    	in ACC, MCUCR
    	sbr ACC, (1<<ISC11)	; INT1 na opadające zbocze
    	sbr ACC, (1<<ISC01) ; INT0 na opadające zbocze
    	out MCUCR, ACC
    
    	in ACC, GICR
    	sbr ACC, (1<<INT1)	; aktywacja przerwania INT1
    	sbr ACC, (1<<INT0)	; aktywacja przerwania INT0
    	cbr ACC, (1<<INT2)	; dezaktywacja przerwania INT2
    	out GICR, ACC
    	
    	in ACC, MCUCSR
    	sbr ACC, (1<<ISC2)	; INT2 na opadające zbocze
    	out MCUCSR, ACC
    
    	in ACC, GIFR
    	sbr ACC, (1<<INTF2) ; wyzerowanie flagi przerwania INT2
    	out GIFR, ACC
    
    	in ACC, GICR
    	sbr ACC, (1<<INT2)	; aktywacja przerwania INT2
    	out GICR, ACC
    
    	pop ACC2
    	pop ACC
    	ret


    Jak widać w przypadku konfiguracji przerwania INT2, konieczne są 'techy' które mi podsunął krzych41

    Dziękuję jeszcze raz i zamykam :)
REKLAMA