Jak na přerušení u PIC24?

Pěkný den přeju.
Pracuji na programu pro řízení grafické jednotky XY4140. Použil jsem PIC24FJ64GB002. Pomalu, velice pomalu se do toho dostávám, ale teď jsem narazil na problém, kdy nejsem schipen dát dokupy obsluhu přerušení. Přikládám celý program, který třeba budiž příkladem někomu, kdo se nedostal ani tak daleko a zároveň prosím o radu, co mi tam chybí nebo je špatně v souvislosti s tím přerušením:

;                     |--------V--------|
;                -  1 | /MCLR       VDD | 28 -
;                   2 | RA0         VSS | 27 -
;                   3 | RA1        RB15 | 26 STROBE
;                -  4 | PGED1      RB14 | 25 D
;                -  5 | PGEC1      RB13 | 24 CLOCK
;                   6 | RB2        VUSB | 23 -
;                   7 | RB3          D- | 22 -
;                -  8 | VSS          D+ | 21 -
;              (-)  9 | (OSCI)     VCAP | 20 -
;              (-) 10 | (OSCO)  DISVREG | 19 -
;                  11 | RB4         RB9 | 18 Levý doraz
;                  12 | RA4         RB8 | 17 Pravý doraz
;                - 13 | VDD         RB7 | 16 Pero
;                - 14 | USBID      VBUS | 15 -
;                     |-----------------|


.equ __24FJ64GB002, 1
.include "p24FJ64GB002.inc"


.global __reset

.global __INT1Interrupt    ;Declare Ext. int. 1 ISR name global 


.text                             ;Start of Code section

__reset:


	bclr	OSCCON,#10
	bclr	OSCCON,#9
	bset	OSCCON,#8

	bclr	CLKDIV,#10
	bclr	CLKDIV,#9
	bclr	CLKDIV,#8
	bclr	CLKDIV,#7
	bclr	CLKDIV,#6
	bset	CLKDIV,#5

	bset	IEC1,#4		;povolení přerušení External interrupt 1
	bset	IPC5,#0
	bset	IPC5,#1
	bset	IPC5,#2
	bset	INTCON1,#15	;zakázáno vnořování přerušení
	bset	INTCON2,#14	;povolena instrukce DISI
	bset	INTCON2,#1	;reakce na sestupnou hranu

;********************************************************************************
;Nastavení vstupně výstupních pinů
	bclr	TRISB,#7	;Pero
	bset	TRISB,#8	;Pravý doraz
	bset	TRISB,#9	;Levý doraz
	bclr	TRISB,#15	;STROBE
	bclr	TRISB,#14	;D
	bclr	TRISB,#13	;CLOCK
	

	;unlock registers
	push	w1;
	push	w2;
	push	w3;
	mov		#OSCCON, w1;
	mov		#0x46, w2;
	mov		#0x57, w3;
	mov.b	w2, [w1];
	mov.b	w3, [w1];
	bclr	OSCCON, #6;
	; Configure Input Functions (Table10-2)
	; Assign U1CTS To Pin RP1, U1RX To Pin RP0
	mov		#0b1000000000,w1;
	mov		w1,RPINR0;
	; Configure Output Functions (Table 10-3)
	; Assign U1RTS To Pin RP3, U1TX To Pin RP2
	mov		#0b11,w1;
	mov		w1,RPINR1;
	;lock registers
	mov #OSCCON, w1;
	mov #0x46, w2;
	mov #0x57, w3;
	mov.b w2, [w1];
	mov.b w3, [w1];
	bset OSCCON, #6;
	pop w3;
	pop w2;
	pop w1;

;********************************************************************************

	CALL Spusteni


	mov.b		#0b00010001,W0

Doleva_nahoru:

	;bset	PORTB,#7		

	call	Cekej

	mov		W0,W1
	nop
	rlnc.b	W1,W0
	CALL	Pohon

	nop
	btss	PORTB,#9
	goto	Doprava_dolu
	goto	Doleva_nahoru


Doprava_dolu:

	;bclr	PORTB,#7	

	call	Cekej

	mov		W0,W1
	nop
	rrnc.b	W1,W0
	CALL	Pohon

	nop
	btss	PORTB,#8
	goto	Doleva_nahoru
	goto	Doprava_dolu



;;;;;;;;;;;;;;;;;;;;;;;;; RUTINY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Spusteni:

	mov		#0,W0
	CALL	Pohon

	RETURN


Pohon:		;Bere hornotu z W0,#0 - W0,#7.

	bclr	PORTB,#15
	bclr	PORTB,#13

	btss	W0,#7
	bclr	PORTB,#14
	btsc	W0,#7
	bset	PORTB,#14
	bset	PORTB,#13
	bclr	PORTB,#13
	
	btss	W0,#6
	bclr	PORTB,#14
	btsc	W0,#6
	bset	PORTB,#14
	bset	PORTB,#13
	bclr	PORTB,#13

	btss	W0,#5
	bclr	PORTB,#14
	btsc	W0,#5
	bset	PORTB,#14
	bset	PORTB,#13
	bclr	PORTB,#13

	btss	W0,#4
	bclr	PORTB,#14
	btsc	W0,#4
	bset	PORTB,#14
	bset	PORTB,#13
	bclr	PORTB,#13

	btss	W0,#3
	bclr	PORTB,#14
	btsc	W0,#3
	bset	PORTB,#14
	bset	PORTB,#13
	bclr	PORTB,#13

	btss	W0,#2
	bclr	PORTB,#14
	btsc	W0,#2
	bset	PORTB,#14
	bset	PORTB,#13
	bclr	PORTB,#13

	btss	W0,#1
	bclr	PORTB,#14
	btsc	W0,#1
	bset	PORTB,#14
	bset	PORTB,#13
	bclr	PORTB,#13

	btss	W0,#0
	bclr	PORTB,#14
	btsc	W0,#0
	bset	PORTB,#14
	bset	PORTB,#13
	bclr	PORTB,#13

	bset	PORTB,#15
	bclr	PORTB,#15

	RETURN


Cekej:

	repeat 	#10000
	nop
	repeat 	#10000
	nop
	repeat 	#10000
	nop
	repeat 	#10000
	nop
	repeat 	#10000
	nop
	repeat 	#10000
	nop

	RETURN


IN:

	mov		#0,W0
	CALL	Pohon

	RETURN


;;;;;;;;;;;;;;;;;;;;;;;; /RUTINY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;; Přerušení ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;..............................................................................
;Interrupt Service Routine
;Example context save/restore in the ISR performed using PUSH.D/POP.D
;instruction. The instruction pushes two words W4 and W5 on to the stack on
;entry into ISR and pops the two words back into W4 and W5 on exit from the ISR
;..............................................................................

__INT1Interrupt:
	
	PUSH.D	W4                  ;Save context using double-word PUSH
	disi	#100
	;<<insert user code here>>
	bset	PORTB,#7
	mov		#0,W0
	CALL	Pohon
	;;;;;;;;;;;;
	
	BCLR	IFS1,#4           ;Clear the Timer1 Interrupt flag Status
	                           ;bit.
	POP.D	W4                   ;Retrieve context POP-ping from Stack
	RETFIE                     ;Return from Interrupt Service routine


;;;;;;;;;;;;;;;;;;;;;;;; /Přerušení ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


.end

Chtěl bych obsloužit přerušení na pinech RB2 a RB3, jímž jsem snad tuto funkci správně přiřadil, protože ten kus kódu, jak je možná vidět jsem odkudsi zkopíroval a poupravil.
Pokud máte někdo nějaký nápad, předem za něj děkuji, případně dovysvětlím přiložený kód.

Odporucal by som urobit uplne minimalny kusok kodu, na ktorom sa da demonstrovat pouzitie prerusenia, v nom trebars iba zmenit stav LED-ky, jednoducho co najmensi priklad, lebo taketo dlhe sa mi to nechce citat. Dalej, prerusovacia rutina ide iba od INT1 vektora, ktory, zda sa, nie je zapnuty. Prerusenia od RB2, 3 (asi mas na mysli prerusenie od CN6, CN7) zas nemas zapnute ani osetrene prerusovacou rutinou.

Treba zacat od zaciatku, takto je to nesmierne neprehladne.

Zatím jsem ještě vyzkoušel, že pokud programově nastavím příznak daného přerušení, bez problémů se provede.
Zkusil jsem tedy jednodušeji, bohužel i tak bez výsledku:

.equ __24FJ64GB002, 1
.include "p24FJ64GB002.inc"

.global __reset
.global __INT1Interrupt    ;Declare Ext. int. 1 ISR name global 

.text                             ;Start of Code section

__reset:

	bclr	OSCCON,#10
	bclr	OSCCON,#9
	bset	OSCCON,#8

	bclr	CLKDIV,#10
	bclr	CLKDIV,#9
	bclr	CLKDIV,#8
	bclr	CLKDIV,#7
	bclr	CLKDIV,#6
	bset	CLKDIV,#5


	mov		#0b10100000000,W0	;přiřazení přerušení INT1 pinu RP5
	mov		W0,RPINR0

	bset	INTCON2,#1	;nastavení reakce INT1 na sestupnou hranu
	bset	INTCON1,#15	;zakázáno vnořování přerušení
	bset	IPC5,#0		;nenulová priotita přerušení INT1
	bclr	IFS1,#4		;vynulování příznaku přerušení INT1
	bset	CNEN1,#2		;povolení přerušení z pinu CN2
	bset	IEC1,#4		;povolení přerušení External interrupt 1

;Nastavení vstupně výstupních pinů
	bset	TRISA,#0	;tlačítko
	bclr	TRISB,#3	;LED
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

smycka:	goto smycka	

;;;;;;;;;;;;;;;;;;;;;;;; Přerušení ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

__INT1Interrupt:
	
	bclr	IFS1,#4           ;Clear the Interrupt flag Status
	
	bset	PORTB,#3		;rozsvícení LEDky

	RETFIE                     ;Return from Interrupt Service routine

;;;;;;;;;;;;;;;;;;;;;;;; /Přerušení ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.end

moj osobny nazor je prejdi na Cko… lebo sa stoho zblaznis.

Céčko mě nijak neláká. Mám s ním zkušenost sice jen z programování pro PC a moc si to neumím představit a momentálně ani nemám čas začínat něco znova. Všechny tyhle problémy, co teď řeším s ASM pro PIC24 už jsem měl zmáknuté pro osmibity, takže ani nemám potřebu přecházet na C a mám zájem doučit se ASM pro šesnáctibity. Bohužel literatura s konkrétními příklady veškerá žádná, tak zkouším a když už to opravdu nejde, tak prátrám takhle po fórech.

Možná není problém v samotné obsluze přerušení, ale spíše v přiřazení funkce ,INT1" příslušnému RPn pinu, to jsem totiž pouze vyčetl z datasheetu a netuším, zda tam něco nechybí.
V odstavci o přerušení se taky nic nepíše o notnosti povolení vyvolání přerušení z příslušného CNn pinu.

Z datasheetu ww1.microchip.com/downloads/en/D … 39940d.pdf :

1, Kapitola 10.4.4.1 - pred zapisom do registrov ovladajucich mapovanie periferii na IO piny je treba povolit zapis do tychot registrov “magickou sekvenciou”, ktora odomyka pristup k nim. Je to preto, aby sa nahodou nemohli zmenit pocas behu programu.

2, Kapitola 10.2 Ak ma pin aj analogovu funkcionalitu, je treba ju vypnut, inak bude prislusny PORT bit citany stale ako nula, bez ohladu na skutocny stav portu, nastavuje sa to registron AD1PCFG (datasheet, register 22-5, strana 265)

3, CN piny sa daju pouzit na proste hlasenie zmeny stavu pinu. Nie je to tak konfigurovatelna periferia ako INT modul, ale na mnohe veci postaci, myslim ze na tvoj problem tiez. Viac o tom je v kapitole 10.3


Dalej, je vhodne stiahnut si aj referencny manual - je rozdeleny na viacero PDF-iek, podla toho, co pokryva. Referencny manual je detailnejsi nez datasheet.

Ak sa pozries na hlavnu stranku MCU, ktory si pouzil
microchip.com/wwwproducts/De … e=en536121
tak ich tam najdes, hladaj reference manual - pre teba budu asi podstatne kapitoly 8 a 12.

jaromir: Děkuju mockrát za objasnění hned několika věcí. Přerušení na základě Input Change Notification funguje bez problémů! Přísahám, že pokud se mi podaří dovést tento projekt ke zdárnému konci, vyrobím povídání pro podobně zoufalé začátečníky jako jsem teď já, a to HLAVNĚ s příklady kódů, protože těch se člověk prostě nedopátrá.

Ja si mylsim ze problem je predovstkym s tou odomykacou funkciou okolo OSCCON, viz 10.4.4.1 v datasheete. Je to jednoduche - tri instrukcie, podla datasheetu.

[code] mov #OSCCONL,w1
mov #0x46,w2
mov #0x57,w3
mov.b w2,[w1] ;write 0x46 to OSCCONL
mov.b w3,[w1] ;write 0x57 to OSCCONL
bclr OSCCON,#IOLOCK ;unlock remapping

; zapis do RPINR, RPOR registrov

       mov     #OSCCONL,w1
       mov     #0x46,w2
       mov     #0x57,w3
       mov.b   w2,[w1]                 ;write 0x0046
       mov.b   w3,[w1]                 ;write 0x0057
       bset    OSCCON,#IOLOCK          ;lock remapping [/code][/code]