2016-04-24 15 views
0

Ich benutze MPLAB, um PIC16F84A für mein Projekt zu programmieren. Ich habe einen Assembler-Code, wo RB4-7 Bits mit Tasten verbunden sind und somit als Eingänge verwendet werden. Ein Interrupt-Unterprogramm wird implementiert, um jeden neuen Interrupt zu behandeln (wenn eine Taste gedrückt wird). Alles funktioniert gut, wenn eine Taste gedrückt wird, geht das Bild zum angegebenen Unterprogramm. Aber jetzt, wenn ich in der Unterroutine bin, muss ich das Flag löschen (INTCON - RBIF), aber es wird nicht gelöscht, aber das Löschen eines anderen Bits im INTCON-Register funktioniert gut. Also was soll ich tun?MPLAB, versucht, ein bisschen zu löschen, aber es bleibt 1

Hier ist mein Code:

 ORG  0X00 
     GOTO START 
     ORG  0x04 
     BTFSC INTCON,RBIF 
     GOTO RBX_INT 
START CLRF PORTA 
     MOVLW B'10001000' 
     MOVWF INTCON 
     BSF  STATUS,RP0 
     CLRF TRISA 
     MOVLW B'11110000' 
     MOVWF TRISB 
     MOVLW B'10000111' 
     MOVWF OPTION_REG 
     BCF  STATUS,RP0 
MAIN GOTO MAIN 

Und das ist mein Unterprogramm:

RBX_INT BCF  INTCON,RBIF 
     MOVLW D'156' 
     CALL DELAY 
     RETFIE 
+1

Wenn dies ein "Interrupt bei Änderung" ist, müssen Sie den Port tatsächlich ** lesen **, auch wenn Sie den Status nicht kennen müssen. Wenn Sie das nicht tun, wird die Logik, die den Interrupt auslöst, weiter feuern. –

+0

@RogerRowland Ja das war das Problem. – kamal

Antwort

0

Sie das Bit löschen sollte rechts, bevor Sie von der Unterbrechung zurückzukehren, andernfalls wird ein neuer Interrupt bereits während passieren kann, in Die delay Schleife und RBIF werden wieder gelöscht. Dies geschieht, weil Tasten zurückspringen (https://en.wikipedia.org/wiki/Switch#Contact_bounce).

Auch das Datenblatt Staaten:

Die Eingangspins (von RB7: RB4) mit dem alten Wert auf den letzten Lesen von PORTB verrastet verglichen. Die "Mismatch" -Ausgänge von RB7: RB4 werden OR-verknüpft, um den RB-Portwechsel Interrupt mit Flag-Bit RBIF (INTCON < 0>) zu erzeugen.

Das heißt, Sie PORTB vor lesen RBIF Löschen der zwischengespeicherten Wert zu aktualisieren.

RBX_INT 

    MOVFW PORTB  ;Read PORTB to update the latch. 
    MOVLW D'156' 
    CALL DELAY 
    BCF  INTCON,RBIF ;Clear interrupt flag as close as possible to RETFIE. 
    RETFIE 

Sie sollten auch über Kontext Sichern/Wiederherstellen für Interrupt-Service-Routinen lesen. Für dieses Beispiel ist es nicht wichtig, weil die Hauptschleife nichts anderes tut, als ein Interrupt jederzeit passieren kann. Es sollte darauf achten, alle verwendeten Register und Ressourcen zu speichern und sie vor dem Beenden des Interrupts wiederherzustellen, damit keine Daten/Zustände beschädigt werden der Haupt-Codepath.

Siehe Abschnitt

6,9 Kontext Saving Während Interrupts

Im PIC16F84A Datenblatt.

+0

Die Verzögerung sorgt bereits für den De-Bounce-Effekt. Und ich habe bereits getan, was Sie vorschlagen, aber es hat nicht funktioniert. – kamal

+0

Sobald Sie RBIF löschen, wird jede Aktivität auf PORTB wieder in Hardware gesetzt. Die Verzögerung hilft nur, wenn sie vor dem Löschen von RBIF ausgeführt wird. – Unimportant

+1

Ja, was Sie sagen, ist richtig, aber das ist nicht mein Problem. Das Flag wird nicht auf Null gesetzt. Ich verwende den Stimulus, um den Interrupt auszulösen, und ich betrachte die Bits bei jedem Schritt, aber RBIF wird immer noch nicht gelöscht. – kamal