Sida 1 av 1
Skriva till Rb utan att få en interrupt?
Postat: 27 september 2007, 17:00:05
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...
Postat: 27 september 2007, 17:40:43
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.
Postat: 27 september 2007, 17:56:33
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.
Postat: 27 september 2007, 18:46:45
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...
Postat: 27 september 2007, 20:40:43
av PHermansson
Det är så jag tolkar databladet också... men praktiken säger annorlunda.... Söker vidare...
Postat: 27 september 2007, 21:04:32
av sodjan
Kan du fixa en liten kort test-kod som uppvisar fenomenet ?
Postat: 27 september 2007, 23:59:24
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
Postat: 28 september 2007, 17:34:29
av Karro
Vilken instruktion genererar avbrottet?
Postat: 28 september 2007, 17:43:09
av PHermansson
Det är skrivningen som gör det, raden:
movwf dlr3416_data
Postat: 28 september 2007, 18:05:48
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.
Postat: 29 september 2007, 17:11:12
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.
Postat: 29 september 2007, 17:41:57
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 ?
Postat: 30 september 2007, 23:47:58
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...
Postat: 30 september 2007, 23:56:00
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.
Postat: 3 oktober 2007, 11:05:25
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...