Skriva till Rb utan att få en interrupt?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Skriva till Rb utan att få en interrupt?

Inlägg av PHermansson »

Ytterligare en braintwister :)
Har i min varvräknare displayen kopplad på PIC16F73's port b. Jag har även en tryckknapp som ska användas för att ändra vad som visas, denna har jag kopplat på RB7 eftersom den var ledig och jag vill utnyttja Interrupt on change-funktionen (finns endast på Rb4:Rb7).
Rb7 är satt som ingång, och det är enbart ingångar som utlöser en interrupt. Problemet är bara att jag får en interrupt när jag skriver data till displayen på port b...
Jag måste alltså på något vis hålla Rb7 oförändrad när jag skriver data till displayen, är detta möjligt? Vad jag förstår skulle varken Xor- eller And-kommandona fungera...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Läs porten och sätt de bitar som du vill ska vara o-ändade
i din variabel först, innan du skriver tillbaka den till porten.
Karro
Inlägg: 42
Blev medlem: 30 augusti 2007, 08:20:09
Ort: Kramfors

Inlägg av Karro »

Enligt Microchips dokumentation och blockdiagrammet ska skrivning till porten inte kunna orsaka interrupt, då inregistren och utregistren är helt separata. Men om du skriver till porten och sedan togglar TRIS två gånger skulle det kunna generera en interrupt. Lösningen då borde då vara att helt enkelt läsa porten efter skrivningen, då det nollställer interruptstatusen.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Hm, det stämmer att man inte *ska* få något interrupt från ut-pinnar.
Jag backar på föregående inlägg...
Det måste vara något attan som är förbisett...
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

Det är så jag tolkar databladet också... men praktiken säger annorlunda.... Söker vidare...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Kan du fixa en liten kort test-kod som uppvisar fenomenet ?
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

Får samma resultat i simulatorn med denna kod:

Kod: Markera allt

list      p=16f73             ; list directive to define processor
#include <p16f73.inc>         ; processor specific variable definitions
	__CONFIG   _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OS

errorlevel -302
#define     DLR3416_WR      PORTC, 2
#define     DLR3416_DATA    PORTB
#define 	led				PORTC, 7
#define		modeSw			PORTB, 7
#define     DLR3416_A0      PORTC, 0
#define     DLR3416_A1      PORTC, 1
INT_VAR	   UDATA	0x70
pos		RES	1
char	       RES	1
mode	     RES	1		;Mode selector

RESET_VECTOR    CODE    0x000       ; processor reset vector
    goto    start               ; go to beginning of program

INT_VECTOR      CODE    0x004       ; interrupt vector location
    bcf		INTCON, RBIF	;Clear flag
    retfie                      
MAIN    CODE
start
;Setup A/D
	;N/A(5),A/D?(5)
	movlw b'00000000'			
	movwf ADCON1 
	;Clock select(2),channel(3),Go/done(1),N/A(1),A/D on/off(1)
	;RA1 = Batt(001)
	movlw b'11001001'
	movwf ADCON0

;Setup Ports
	banksel     TRISA               ;
	movlw	    b'11111111'	;PortA = input
	movwf	    TRISA
        clrf             TRISB
	bsf		 TRISB, 7	;Rb0:6-out, Rb7-in
        clrf             TRISC
	bcf		option_reg, not_rbpu
;Enable interrupts
	BSF		INTCON, RBIE
	BSF		PIE1, ADIE
	BSF		INTCON, PEIE
	BSF		INTCON, GIE

;Write welcome message
	;Char
        movlw 		b'01010011'	;Char 'S' in W
	;Set data	
        movwf       dlr3416_data	;W to data
	;Pos
	movlw		b'00000011'
	movwf		pos
	call toggle_wr

loop
    	goto loop                       

toggle_wr
              ;Reset adress
		bcf			DLR3416_A0
		bcf			DLR3416_A1

              ;Set address
		btfsc		       pos,0				;Check if A0 is set in pos
		bsf			DLR3416_A0
		nop
		btfsc		       pos,1				;Check if A0 is set in pos
		bsf			DLR3416_A1
		nop

;Toggle Write
        bcf         dlr3416_wr          ; Skriv till displayen.
        nop
        bsf         dlr3416_wr
        nop

        return

    end
Karro
Inlägg: 42
Blev medlem: 30 augusti 2007, 08:20:09
Ort: Kramfors

Inlägg av Karro »

Vilken instruktion genererar avbrottet?
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

Det är skrivningen som gör det, raden:
movwf dlr3416_data
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

IOC är inte helt enkelt.
Du har läst det som handlar om "end the mismatch condition" t.ex ?
Jag ser inte att du gör det på ett sätt som skulle undvika att RBIF hela
tiden sätts igen.

Det står även att p.g.a av vissa problem att kombinera IOC med annan
användninga av PORTB, så rekomenderar man inte att man gör det.
Det har du sett ?

Jag skulle se till att IOC verkligen är clearat innan jag sätter RBIE.
Karro
Inlägg: 42
Blev medlem: 30 augusti 2007, 08:20:09
Ort: Kramfors

Inlägg av Karro »

Det här är väl ett typiskt problem som kan uppkomma vid hårdvarunära programmering. Eftersom man inte har schema på PIC-processorn, får man istället försöka hitta ett sätt att kringå problemet.

Här finns ju många frågor. Varför genereras avbrottet?
Är det för att man skriver till portb överhuvudtaget, är det för att man skriver en högsta bit som skiljer sig från input, eller är det ett initialproblem, för att man inte har initierat ordentligt?
Det finns mycket du kan göra, ja bland annat som sojan säger, göra en riktig reset av porten i avbrottsrutinen, men kanske också prova att göra en reset av porten direkt efter initieringen. Ett annat prov är att sätta B7 till 1 och se om det fungerar.
When everything else fails, kan man alltid disabla interrupts, göra skrivningen, göra en läsning och sedan slå på interrupten igen, även om det kanske ser lite fult ut.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Bara för att förtydliga lite...
Med "reset av porten" avser du alltså det som i databladet kallas
"end the mismatch condition", eller hur ?
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

Ska det inte räcka med att nolla RBIF för att nolla interrupt? Och även om man kan prova fler åtgärder för att häva mismatch condition i avbrottsrutinen så förklarar det ju inte varför avbrott initieras vid den första skrivningen till porten? RB7 är satt som input och ska ju inte ge ett avbrott även om jag skriver till port b.
Ska testa det där sista... nolla RBIF och Port B innan jag sätter RBIE så får vi se...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Ska det inte räcka med att nolla RBIF för att nolla interrupt?

Nej, och det förklaras tydligt.

För övrigt har du rätt, det hela verkar lite konstigt.
Användarvisningsbild
PHermansson
EF Sponsor
Inlägg: 4340
Blev medlem: 22 december 2004, 00:46:38
Ort: Särestad Grästorp
Kontakt:

Inlägg av PHermansson »

Har äntligen haft tid att fundera vidare på detta och testa lite... Har testat lite olika varianter men inget hjälper. Får nog bli en fullösning med att cleara RBIE före varje skrivning...
Skriv svar