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!
org 0x0 GOTO Init org 0x04 InterruptServiceVector movwf W_save swapf STATUS,W bcf STATUS, RP0 movwf Status_save BTFSS PORTC,3 BSF PORTC,3 BTFSC PORTC,3 BCF PORTC,3 Intende_ BCF INTCON,RBIF bcf INTCON, T0IF swapf Status_save, w movwf STATUS swapf W_save,f swapf W_save,w retfie Init BANKSEL 1 movlw b'10000000' movwf TRISB bsf INTCON, GIE bsf IOCB,7 BANKSEL 0 Start_ GOTO Start_
Du musst in deiner INIT-Routine den PortB auf Digital-I/O schalten (ist nach PowerON auf Analog IN) BANKSEL 3 MOVLW 0 MOVWF ANSELH BANKSEL 0
auch nachdem ich BANKSEL 1 movlw b'00000000' movwf TRISC für den ausgabe Pin eingefügt habe gehts leider nicht. noch eine Idee?
> RBIE in INTCON zu setzen dürfte auch nicht schaden.
stimmt
(waren die nicht früher auf '1' nach PON?...)
>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?
naja, mit dem PortC,3 überprüfe ich, ob ich auch in den Interupt gesprungen bin.
@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. Wo kann ich denn einstellen, ob der Pin auf Lo->Hi oder Hi-Lo reagiert? oder reagiert der auf beide flanken?
Reagiert auf beide Flanken. Und: Das Interrupt-Flag musst du in der ISR wieder löschen, sonnst wird kein neuer Interrupt ausgelöst.
>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.
ja, ich habe alles so gemacht wie er vorgeschlagen hat. Ist es vielleicht noch wichtig zu erwähnen, dass ich ein PicKit2 verwende?
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 ^
@Sven Stefan nein, es gibt nur xorwf PORTC,0 ; -> Ergebnis in WREG xorwf PORTC,1 ; -> Ergebnis in PORTC daher: movlw b'00000001' xorwf PORTC,1 ; RC0 toggeln movlw b'00000010' xorwf PORTC,1 ; RC1 toggeln movlw b'00000100' xorwf PORTC,1 ; RC2 toggeln movlw b'00001000' xorwf PORTC,1 ; RC3 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)
Vielen dank für eure Ausführungen, aber... Geht immernoch nicht, bin ich zu doof? Hoffentlich sagt ihr jetzt ja und erklärt mir was ich falsch mache. Hier mein Code #include <p16F886.inc> #define CONFIGURATION1 _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF #define CONFIGURATION2 _BOR_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF & _DEBUG_OFF __CONFIG _CONFIG1, CONFIGURATION1 & CONFIGURATION2 W_save EQU 0x26 Status_save EQU 0x27 org 0x00 GOTO Configuration org 0x04 Interrupt movwf W_save swapf STATUS,W bcf STATUS, RP0 movwf Status_save movlw b'00000100' xorwf PORTC,3 ;LED3 toggeln BCF INTCON,RBIF bcf INTCON, T0IF swapf Status_save, w movwf STATUS swapf W_save,f swapf W_save,w BCF PORTB,3 retfie Configuration clrf PORTC BANKSEL TRISC movfw TRISC andlw b'00000000' movwf TRISC BANKSEL 0 clrf PORTB BANKSEL TRISB movfw TRISB iorlw b'11111111' movwf TRISB BANKSEL 0 BANKSEL ANSEL ; CLRF ANSEL BANKSEL ANSELH ; CLRF ANSELH BANKSEL 0 BSF INTCON,RBIE bsf IOCB,7 bcf OPTION_REG,7 bsf INTCON, GIE Start_ movlw b'0001000' xorwf PORTC,3 ;LED1 toggeln GOTO Start_ end Mein signal das ich anlege ist... +Versorgungsspannung und GND ohne beschaltung.
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...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.