Wie kann ich bei einem PIC16F886 einen Interrupt on change an PortB,7
auslösen?
Ich komm einfachn nicht in die Interrupt routine rein :(
Bitte um kurze hilfestellung, welche Bits ich setzen bzw, löschen muss.
Vielen Danke!
>auch nachdem ich> BANKSEL 1> movlw b'00000000'> movwf TRISC>für den ausgabe Pin eingefügt habe gehts leider nicht.
He? Was soll'n das? Ich denke du hast ein Problem mit IntOnChange an
PORTB? Was hat denn die Richtung von PORTC damit zu tun?
@tastendrücker
>(waren die nicht früher auf '1' nach PON?...)
The interrupt-on-change feature is
disabled on a Power-on Reset.
Wüsste nicht das es jemals anders war ;)
Ach so ja, die Ausgabe...
Passiert überhaupt was? Schwingt der Quarz oder nimmst du den internen
Oszi? In deiner Start-goto-Start würde ich mal ein PORTC-Pin toggeln, um
zu sehen, ob der PIC überhaupt läuft
>PIC läuft>aber der interrupt nicht.
Hast du den Tip von tastendrücker auch programmiert ?
>Wo kann ich denn einstellen, ob der Pin auf Lo->Hi oder Hi-Lo reagiert?>oder reagiert der auf beide flanken?
Interrupt On Change reagiert auf beide Flanken. Bei jeder
Änderung (Change) eben. Wenn du eine bestimmte Flanke möchtest
musst du das per Software lösen.
Dass heisst: Ein Pin toggelt im Betrieb vor sich hin - aber der
Interrupt löst nicht aus...
Poste doch noch mal den aktuellen Code
Wie wird denn der Pin angesteuert?
Inwieweit banksel mit einer Konstante funktioniert kann ich nicht sagen.
Die Syntax lautet jedenfalls "banksel label" und wird von mir nur so
verwendet. Also z.Bsp. so:
label equ 0x20
banksel label
Ansonsten solltest du RBIE noch setzen, sonst werden die IOC-Interrupts
nicht eingeschaltet. Da RB7 nicht analog benutzt wird, dürfte das
Umstellen auf digital keine Rolle spielen.
Weiterhin funktioniert deine LED-Toggle-Routine so nicht (hab ich auch
Anfangs so machen wollen, geht aber nicht)
BTFSS PORTC,3
BSF PORTC,3
BTFSC PORTC,3
BCF PORTC,3
Warum? Wenn RC3 Low hat, prüfst du dies auf Zeile 1. Da nicht gesetzt,
wird der Port auf Zeile 2 gesetzt. Nun prüfst du auf Zeile 3 ob Port
gesetzt. Ist er nun (wegen Zeile 2) also wird er auf Zeile 4
zurückgesetzt. Deine LED wird nie leuchten. Ich mach das immer so
movlw b'00001000'
xorwf PORTC,3 ;LED1 toggeln
Probier es ruhig mal.
Sven
>Weiterhin funktioniert deine LED-Toggle-Routine so nicht (hab ich auch>Anfangs so machen wollen, geht aber nicht)> BTFSS PORTC,3> BSF PORTC,3> BTFSC PORTC,3> BCF PORTC,3
Oops, is' mir gaanich aufgefallen...
> movlw b'00001000'> xorwf PORTC,3 ;LED1 toggeln
muss aber sein:
movlw b'00001000'
xorwf PORTC,1 ;LED1 toggeln
^
Ooops, was hab ich denn da mal in meinem Programm geschrieben (ich hab
das nur aus einem meiner Programme rauskopiert gehabt)? Ich schreib doch
eigentlich immer
xorwf PORTC,f (und nicht PORTC,1)
Wo ich mir doch nie merken kann was die 1 bzw. 0 hinter dem Komma
bedeutet ;-)
Gruß
Sven
Ja, man sollte wenn möglich die Symbole verwenden
w = 0 = WREG (Ergebnis der Operation wird ins WREG gespeichert)
f = 1 = file (Ergebnis der Operation wird ins file gespeichert)
Arbeitest du auch manchmal mit dem Simulator? Und liest du auch die
Fehlermeldungen? Dann hättest du gesehen was falsch läuft...
1. Routine Interrupt:
movlw b'00000100'
xorwf PORTC,3 ;LED3 toggeln
Das hatten wir doch schon hier besprochen. Da hatte ich einen Fehler
geschrieben. Hinter xorwf PORTC,3 kann keine 3 stehen nur ein f oder w.
Mach da also ein f draus. In dem Befehl davor (movlw b'00000100' musst
du die 1 um eine Stelle nach links versetzen, wenn du deine LED an
PORTC,3 angeschlossen hast.
2. Falsche Register Bank (die Zeilen vor Marke Start)
BANKSEL 0
BSF INTCON,RBIE
bsf IOCB,7
bcf OPTION_REG,7
bsf INTCON, GIE
INTCON liegt in Bank 0 -> richtig
IOCB und OPTION_REG liegt in Bank 1 -> musst du vorher umschalten!
So, und wenn das auch nicht geht, weiß ich nicht mehr weiter.
Schönen Abend noch (und grübel ruhig selbst mal ein wenig)
Sven
Ach ja, deine LED toggelt nun in der Startschleife mit einer Frequenz
von ein paar Megaherz. Du wirst das also nicht bemerken. Die LED wird
immer leuchten.
Und das bcf PORTC,3 vor retfie ist zuviel nimm es raus. Dadurch löschst
du die LED gleich wieder, nachdem du sie eingeschaltet hast.
So nun hab ich bei der Simulation den Fehler, dass das Programm nicht
mehr aus der Interruptroutine herauskommt. Nach einem Blich ins
Datenblatt:
This interrupt can wake the device from Sleep. The user,
in the Interrupt Service Routine, clears the interrupt by:
a) Any read or write of PORTB. This will end the
mismatch condition.
b) Clear the flag bit RBIF.
Du musst also vor dem löschen des RBIF-Bits noch den PortB lesen. Sonst
wird das RBIF Bit nicht zurückgesetzt und die ISR kann nicht beendet
werden.
Also bei mir läuft die Simulation. Nun du...