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

[attiny13][asm] przerwania pcint nie działają

->Mike<- 11 Wrz 2009 10:13 2270 6
REKLAMA
  • #1 7005137
    ->Mike<-
    Poziom 11  
    Otóż jak w tytule mam problem z przerwaniem pcint. program ma za zadanie zamrugać 2 diodami pb0 i pb1 po czym iść spać. Pcint ma go obudzić i wykonać taką samą sekwencję. Globalne mam odblokowane, pcint też, pul upy podciągnięte a to dalej nie działa.... Proszę o pomoc

    .DEVICE ATtiny13
    .ORG 0x0000
    ;-------------------- wektor przerwaĹ„ -------------------
    	rjmp reset
    	reti
    	rjmp pcint
    	reti
    	reti
    	reti
    	reti
    	reti
    	reti
    	reti
    ;--------------------------------------------------------
    
    reset:
    	sei
    ;----------------------- inicjacja SP -------------------
    	ldi r16, low(ramend)	
    	out SPL, r16			
    ;--------------------------------------------------------
    ;----------------------- ustawienia SLEEP ---------------
    	in r16, mcucr		 
    	sbr r16, 0b00100000	; se -> 1
    	cbr r16, 0b01011000	; pud -> 0, sm0 i sm1 ->0 idlle mode
    	out mcucr, r16
    ;-------------------------------------------------------- 	
    ;----------------------- ustawienia WDT------------------
    	in	r16, MCUSR
    	cbr r16, WDRF
    	out	MCUSR, r16
    	in	r16, WDTCR
    	sbr r16, wdce
    	out	WDTCR, r16
    	ldi r16, 0b00010111
    	out	WDTCR, r16
    	sei
    ;---------------------------------------------------------
    ;--------------------- inicjacja PCINT -------------------
    	in	r16, gimsk
    	sbr r16, pcie
    	out gimsk, r16	
    	in	r16, pcmsk	
    	sbr r16, 0b00111100
    	out pcmsk, r16	
    ;--------------------------------------------------------
    ;---------------------- main ----------------------------
    ldi r16,0b00000011
    	out ddrb, r16
    	rcall wait
    	ldi r16,0b00000010
    	out portb, r16
    	rcall wait
    	ldi r16,0b00000001
    	out portb, r16
    	rcall wait
    	ldi r16,0b00000010
    	out portb, r16
    	rcall wait
    	ldi r16,0b11111101
    	out portb, r16
    	sei
    	sleep
    ;---------------------------------------------------------
    ;------------------------ PCINT --------------------------
    pcint:
    	ldi r16,0b00000011
    	out ddrb, r16
    	rcall wait
    	ldi r16,0b00000010
    	out portb, r16
    	rcall wait
    	ldi r16,0b00000001
    	out portb, r16
    	rcall wait
    	ldi r16,0b00000010
    	out portb, r16
    	rcall wait
    	ldi r16,0b11111101
    	out portb, r16
    	reti
    ;---------------------------------------------------------
    ;--------------- PÄ™tla opóźnienia czasowego -------------- 
    wait:
    	
    	ldi r17, 0b11111111
    q0:
    	ldi r16, 0b11111111
    q1:	
    	wdr
    	dec r16
    	brne q1
    	dec r17
    	brne q0
    	ret
    ;---------------------------------------------------------
      


    Poprawiłem tytuł - regulamin p.11.2
    [zumek]
  • REKLAMA
  • #2 7005810
    JarekC
    Poziom 32  
    Witam,

    Masz błąd w procedurze odblokowania przerwań od portu.
    Instrukcja SBR operuje na "masce" a nie na numerze bitu.

    masz:
    
       in   r16, gimsk
       sbr r16, pcie
       out gimsk, r16
    


    powinno być:

    
       in   r16, gimsk
       sbr r16, (1<<pcie)
       out gimsk, r16
    


    Pozdrawiam
    JarekC
  • REKLAMA
  • #3 7008647
    ->Mike<-
    Poziom 11  
    ok powiedzmy że tu był błąd. Tylko że po w prowadzeniu poprawek procek nie taj jakby nie wchodził w ogóle w sleep... a sekwencja mrugania wykonuje się w nieskończoność :( a może to coś z programatorem jest(ten mój jest tak raczej na pająka zrobiony)? kod po poprawkach wygląda tak:

    .DEVICE ATtiny13
    .ORG 0x0000
    ;-------------------- wektor przerwań -------------------
    	rjmp reset
    	reti
    	rjmp pcint
    	reti
    	reti
    	reti
    	reti
    	reti
    	reti
    	reti
    ;--------------------------------------------------------
    
    reset:
    	sei
    ;----------------------- inicjacja SP -------------------
    	ldi 	r16, low(ramend)	
    	out 	SPL, r16			
    ;--------------------------------------------------------
    ;----------------------- ustawienia SLEEP ---------------
    	in		r16, mcucr		 
    	sbr 	r16,(1<<se)
    	cbr		r16,(1<<pud)|(1<<sm1)|(1<<sm0); idlle mode
    	out 	mcucr, r16
    ;-------------------------------------------------------- 	
    ;----------------------- ustawienia WDT------------------
    	in		r16, mcusr
    	cbr		r16, (1<<wdrf)
    	out		mcusr, r16
    	in		r16, wdtcr
    	sbr		r16, (1<<wdce)
    	out		wdtcr, r16
    	cbr		r16, (1<<wde)
    	out		wdtcr, r16
    	sei
    ;---------------------------------------------------------
    ;--------------------- inicjacja PCINT -------------------
    	in		r16, gimsk
    	sbr		r16, (1<<pcie)
    	out 	gimsk, r16	
    	in		r16, pcmsk	
    	sbr 	r16, (1<<pcint5)|(1<<pcint4)|(1<<pcint3)|(1<<pcint2)
    	out 	pcmsk, r16	
    ;--------------------------------------------------------
    ;---------------------- main ----------------------------
    	ldi		r16,0b00000011
    	out 	ddrb, r16
    	rcall 	wait
    	ldi 	r16,0b00000010
    	out 	portb, r16
    	rcall 	wait
    	ldi 	r16,0b00000001
    	out 	portb, r16
    	rcall 	wait
    	ldi 	r16,0b00000010
    	out 	portb, r16
    	rcall 	wait
    	ldi 	r16,0b11111101
    	out 	portb, r16
    	sei
    	sleep
    ;---------------------------------------------------------
    ;------------------------ PCINT --------------------------
    pcint:
    	ldi 	r16,0b00000011
    	out 	ddrb, r16
    	rcall 	wait
    	ldi 	r16,0b00000010
    	out 	portb, r16
    	rcall 	wait
    	ldi 	r16,0b00000001
    	out 	portb, r16
    	rcall 	wait
    	ldi 	r16,0b00000010
    	out 	portb, r16
    	rcall 	wait
    	ldi 	r16,0b11111101
    	out 	portb, r16
    	reti																																																																		
    ;---------------------------------------------------------
    ;--------------- Pętla opóźnienia czasowego -------------- 
    wait:
    	
    	ldi r17, 0b11111111
    q0:
    	ldi r16, 0b11111111
    q1:	
    	wdr
    	dec r16
    	brne q1
    	dec r17
    	brne q0
    	ret
    ;---------------------------------------------------------
    
  • REKLAMA
  • #4 7009201
    JarekC
    Poziom 32  
    Witam,

    Nie będzie działać poprawnie po popełniłeś jeszcze jeden błąd.

    Do momentu uśpienia wszystko jest ok, ale teraz następuje zmiana na porcie C,
    uP wstaje z uśpienia wykonywanie jest przerwanie pcint i teraz następuje powrót
    z przerwania. Powrót wykonywany jest jest nie do instrukcji SLEEP jak założyłeś
    a do pierwszej instrukcji po niej. Czyli następuje ponowne wykonanie przerwania
    pcint ale tym razem powrót następuje w nieokreślone miejsce bo nie było CALL
    ani zgłoszenia przerwania (na stosie nie ma poprawnego adresu powrotu).
    Aby układ po wykonaniu ponownie wszedł w tryb uśpienia musisz znowu wykonać
    instrukcję SLEEP.

    Kod po poprawce:

    
    ;---------------------- main ----------------------------
       ldi      r16,0b00000011
       out    ddrb, r16
       rcall    wait
       ldi    r16,0b00000010
       out    portb, r16
       rcall    wait
       ldi    r16,0b00000001
       out    portb, r16
       rcall    wait
       ldi    r16,0b00000010
       out    portb, r16
       rcall    wait
       ldi    r16,0b11111101
       out    portb, r16
       sei
    _loc_1:
       sleep
       rjmp _loc_1
    


    Ponieważ w main i w pcint wykonujesz dokładnie te same czynności wystarczy
    wykorzystać pcint tylko do obudzenia uP.

    
    ;---------------------- main ----------------------------
    _loc_1:
       ldi      r16,0b00000011
       out    ddrb, r16
       rcall    wait
       ldi    r16,0b00000010
       out    portb, r16
       rcall    wait
       ldi    r16,0b00000001
       out    portb, r16
       rcall    wait
       ldi    r16,0b00000010
       out    portb, r16
       rcall    wait
       ldi    r16,0b11111101
       out    portb, r16
       sei
    
       sleep
       rjmp _loc_1
    
    pcint:
         reti
    


    W tym konkretnym przypadku nie ma to znaczenia, ale korzystając z przerwań
    należy w nich zachować a następnie odtworzyć stan SREG i wykorzystywanych
    rejestrów.

    Nie mam po ręką karty katalogowej ale należałoby jeszcze sprawdzić jak działa
    Watchdog w stanie uśpienia.

    Pozdrawiam
    JarekC
  • #5 7010208
    ->Mike<-
    Poziom 11  
    Dzięki za pomoc to rzeczywiście może być to sprawdzę zaraz jak wrócę do domu ;) wdt mam wyłączonego tak że nie powinien mi przeszkadzać....

    Pozdrawiam:
    Mike
  • REKLAMA
  • #6 7016937
    ->Mike<-
    Poziom 11  
    wróciłem i sprawdziłem i coś jeszcze nie tak po zmianach w kodzie µK już nie startuje z sekwencją tylko idzie spać... Tylko że jak go obudzę to jest zły i wykonuje sekwencje losową ilość razy... zmieniłem też trochę sekwencję i zastanawia mnie dlaczego polecenie
    cbr 	r16, (1<<portb1)
    gasiło mi 2 diody na raz (po uprzednim ich zapaleniu). może mam coś z µK mógłby to ktoś wgrać i zobaczyć czy u nie go tak samo nie działa?

    .DEVICE ATtiny13
    .ORG 0x0000
    ;-------------------- wektor przerwań -------------------
    	rjmp reset
    	reti
    	rjmp pcint
    	reti
    	reti
    	reti
    	reti
    	reti
    	reti
    	reti
    ;--------------------------------------------------------
    
    reset:
    	sei
    ;----------------------- inicjacja SP -------------------
    	ldi 	r16, low(ramend)	
    	out 	SPL, r16			
    ;--------------------------------------------------------
    ;----------------------- ustawienia SLEEP ---------------
    	in		r16, mcucr		 
    	sbr 	r16,(1<<se)
    	cbr		r16,(1<<pud)|(1<<sm1)|(1<<sm0); idlle mode
    	out 	mcucr, r16
    ;-------------------------------------------------------- 	
    ;----------------------- ustawienia WDT------------------
    	in		r16, mcusr
    	cbr		r16, (1<<wdrf)
    	out		mcusr, r16
    	in		r16, wdtcr
    	sbr		r16, (1<<wdce)
    	out		wdtcr, r16
    	cbr		r16, (1<<wde)
    	out		wdtcr, r16
    	
    ;---------------------------------------------------------
    	ldi		r16,0b00000011
    	out 	ddrb, r16
    	ldi 	r16,0b11111100
    	out 	portb, r16
    	sei
    ;--------------------- inicjacja PCINT -------------------
    	in		r16, gimsk
    	sbr		r16, (1<<pcie)
    	out 	gimsk, r16	
    	in		r16, pcmsk	
    	sbr 	r16, (1<<pcint5)|(1<<pcint4)|(1<<pcint3)|(1<<pcint2)
    	out 	pcmsk, r16	
    ;--------------------------------------------------------
    ;---------------------- main ----------------------------
    	
    s0:
    	sei
    	sleep
    	rjmp s0
    ;---------------------------------------------------------
    ;------------------------ PCINT --------------------------
    pcint:
    	rcall 	wait
    	sbr 	r16, (1<<portb1)
    	out 	portb, r16
    	rcall 	wait
    	sbr 	r16, (1<<portb0)|(1<<portb1)
    	out 	portb, r16
    	rcall 	wait
    	sbr 	r16, (1<<portb0)
    	cbr 	r16, (1<<portb1)
    	out 	portb, r16
    	rcall 	wait
    	cbr 	r16, (1<<portb0)
    	out 	portb, r16
    	reti																																																																		
    ;---------------------------------------------------------
    ;--------------- Pętla opóźnienia czasowego -------------- 
    wait:
    	
    	ldi r17, 0b11111111
    q0:
    	ldi r16, 0b11111111
    q1:	
    	wdr
    	dec r16
    	brne q1
    	dec r17
    	brne q0
    	ret
    ;---------------------------------------------------------
    
  • #7 7430600
    ->Mike<-
    Poziom 11  
    Z poprzednim błędem sobie poradziłem ;)(w funkcji wait r16 bylo nadpisywane pop i push załatwiło sprawę)

    Ale mam kolejny problem:

    Bawię się pwm na osca0. Ma to działać mniej więcej tak:
    Pwm włącza się i wyłącza jak wcisnę razem pin 4i3. Jak wcisnę 3 to wypełnienie się zwiększa a jak 4 to się zmniejsza. Zmienia się ono w zakresie od 0b11011000 do 0b00010000.

    I to wszystko działa. Zrobiłem sobie czołówkę na 3 watowej diodzie.
    Podczas używania dostrzegłem jeden mankament:
    Jak przytrzymam dłużej piny 3i4 to jak latarka jest wyłączona to błyśnie na chwilę a jak jest włączona to zgaśnie na chwilę. W czym jest problem? Chciałbym zrobić tak że jak przytrzymam dłużej 3i4 to się włączy boost(wypełnienie 100%) ale ten jeden mankament mi troszkę przeszkadza...

    Proszę o pomoc

    ->Mike<-



    .DEVICE ATtiny13
    .ORG 0x0000
    .DEF wyp = r18
    ;-------------------- wektor przerwań -------------------
    	rjmp reset
    	reti
    	rjmp pcint
    	
    ;--------------------------------------------------------
    
    reset:
    ;----------------------- inicjacja SP -------------------
    	ldi 	r16, low(ramend)	
    	out 	SPL, r16			
    ;--------------------------------------------------------
    ;----------------------- inicjacja PWM -------------------
    	in		r16, tccr0b
    	sbr 	r16, (1<<cs01)|(1<<cs00)
    	out 	tccr0b, r16	
    ;--------------------------------------------------------
    ;----------------------- ustawienia SLEEP ---------------
    	in		r16, mcucr		 
    	sbr 	r16,(1<<se)
    	cbr		r16,(1<<pud)|(1<<sm1)|(1<<sm0); idlle mode
    	out 	mcucr, r16
    ;-------------------------------------------------------- 	
    ;----------------------- ustawienia WDT------------------
    	in		r16, mcusr
    	cbr		r16, (1<<wdrf)
    	out		mcusr, r16
    	in		r16, wdtcr
    	sbr		r16, (1<<wdce)
    	out		wdtcr, r16
    	cbr		r16, (1<<wde)
    	out		wdtcr, r16
    ;---------------------------------------------------------
    	ldi		r16,0b00000011
    	out 	ddrb, r16
    	ldi 	r16,0b11111100
    	out 	portb, r16
    ;--------------------- inicjacja PCINT -------------------
    	in		r16, gimsk
    	sbr		r16, (1<<pcie)
    	out 	gimsk, r16	
    	in		r16, pcmsk	
    	sbr 	r16, (1<<pcint4)|(1<<pcint3)
    	out 	pcmsk, r16	
    ;--------------------------------------------------------
    ;---------------------- main ----------------------------
    s0:
    	sei
    	sleep
    	rjmp s0
    ;---------------------------------------------------------
    ;------------------------ PCINT --------------------------
    pcint:
    	cli
    	in 		r16, sreg
    	push	r16	
    	rcall	wait0
    	sbis	pinb, pinb3
    	rjmp	p3
    	sbis	pinb, pinb4
    	rjmp	p4
    
    p3:
    	rcall	wait0
    	sbis	pinb, pinb4
    	rcall	pin3i4
    	rcall	pin3
    p4:
    	rcall	wait0
    	sbis	pinb, pinb3
    	rcall	pin3i4
    	rcall	pin4
    ;--------------------------pin3i4-------------------------
    pin3i4:
    	rcall	wait0
    	sbic	pinb, pinb3
    	reti
    	rcall	wait0
    	sbic	pinb, pinb4
    	reti
    	rcall 	wait0
    	rcall	wait0
    	sbic	pinb, pinb4
    	reti
    	rcall	wait0
    	sbic	pinb, pinb3
    	reti
    	in		r16, tccr0a
    	sbrc	r16, com0a1
    	rjmp	off
    	in		r16, tccr0a
    	sbr 	r16, (1<<com0a1)|(1<<wgm01)|(1<<wgm00)
    	out 	tccr0a, r16	
    	pop		r16
    	out		sreg, r16
    	reti
    
    off:
    	in		r16, tccr0a
    	cbr 	r16, (1<<com0a1)|(1<<com0a0)|(1<<wgm01)|(1<<wgm00)
    	out 	tccr0a, r16	
    	pop		r16
    	out		sreg, r16
    	reti
    ;---------------------------------------------------------
    
    ;--------------------------pin3---------------------------
    pin3:
    	rcall 	wait0
    	sbic	pinb, pinb3
    	reti
    	rcall 	wait0
    	sbic	pinb, pinb3
    	reti
    	in		wyp, ocr0a
    	subi	wyp, -40
    	ldi		r16, 0b11011000
    	cpse	wyp, r16
    	rjmp	s1
    	ldi		wyp, 0b00010000
    	out		ocr0a, wyp
    	pop		r16
    	out		sreg, r16
    	reti
    s1:
    	out		ocr0a, wyp
    	pop		r16
    	out		sreg, r16
    	reti
    ;---------------------------------------------------------
    
    ;--------------------------pin4---------------------------
    pin4:
    	rcall 	wait0
    	sbic	pinb, pinb4
    	reti
    	rcall 	wait0
    	sbic	pinb, pinb4
    	reti
    	in		wyp, ocr0a
    	subi	wyp, 40
    	in		r16, sreg
    	sbrc	r16, 0
    	ldi		wyp, 0b10110000
    	out		ocr0a, wyp
    	pop		r16
    	out		sreg, r16
    	reti
    
    ;---------------------------------------------------------
    ;---------------------------------------------------------
    
    ;--------------- Pętla opóźnienia czasowego ----------- 
    wait0:
    	push r16
    	push r17
    	ldi r17, 0b11111111
    q2:
    	ldi r16, 0b00100000
    q3:	
    	dec r16
    	brne q3
    	dec r17
    	brne q2
    	pop r17
    	pop r16
    	ret
    ;---------------------------------------------------------
     
    
    
REKLAMA