Timer0 Interrupt
Samstag, 19. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  Programmiersprache Assembler  |  Timer (Assembler)  |  Timer0 Interrupt « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: Timer0 Interrupt  (Gelesen 2803 mal)
 
bastiz
Gast
« am: Juni 13, 2006, 21:20:27 »

Hallo,
ich möchte an PortB Pin 1 eine LED toggeln lassen, jeweils 2s Sekunden an, 1 Sekunde aus.
Beim Überlauf des Timer0 wird ein Interrupt ausgelöst der den Pin entsprechend schaltet.
Nach meiner Logik müsste der Code funktionieren. Das Problem ist kommt nach der CarryBit Abfrage.
Nach retfie (siehe Code) müsste der Programmzähler eigentlich wieder zur Hauptroutine zurückkehren, tut er aber nicht, stattdessen springt er wieder an Adresse 0x04 und führt die Interrupt Routine nochmal aus.

Hat irgendjemand eine Idee wo das Problem liegen könnte?

Viele Grüße

Basti


Code:
;************************************************

List p=16f877
include <p16f877.inc>

;************************************************
;Variablen

flag equ 0x20

;************************************************

org 0x00
goto main

IR_Service
org 0x04

bcf STATUS,C         ;Carry loeschen
btfss PORTB,1 ;Fallunterscheidung:
goto setzeBit         ;Wenn PortB,1 nicht gesetzt
        ;dann in jedem Falle setzen

rrf flag,F ;Wenn PortB,1 gesetzt, dann Flag ¸berpruefen
btfsc STATUS,C         ;Wenn Flag=1 abbrechen und naechsten Ueberlauf
retfie         ;abwarten

goto loescheBit         ;Wird erreicht wenn PortB,1=1 und Flag=0

setzeBit
bsf PORTB,1 ;Pin1 auf High setzen
incf flag,F ;Flag fuer zweiten Durchlauf inkrementieren
bcf INTCON,T0IF ;Zuruecksetzten des IR-Flags muss manuell erfolgen
retfie

loescheBit
bcf PORTB,1 ;Pin1 auf Low
bcf INTCON,T0IF ;Zuruecksetzten des IR-Flags muss manuell erfolgen
retfie

main

clrf PORTB
clrf TMR0 ;Loesche Timer um sicherzustellen das kein IR
        ;beim Konfigurieren ausgeloest wird
movlw 0x00
movwf flag
bsf STATUS,RP0 ;ADCON1 ist in Bank1
movlw 0x07 ;Konfiguriere alle PORTS als Digitale I/Os
movwf ADCON1 ;
bsf TRISB,0        ;PORTB,0 ist Eingang
bcf TRISB,1       ;PORTB,1 ist Ausgang
clrf OPTION_REG ;
movlw 0x01         ;TMR0: internen Takt verwenden
movwf OPTION_REG ;TMR0: Vorteiler 1:4 verwenden

bcf STATUS,RP0        ;INTCON ist in Bank0
movlw 0xEF        ;Timer mit Wert vorinitialisieren
movwf TMR0 ;
movlw 0xA0 ;IR-Konfiguration: GIE=1, TMR0IF=1
movwf INTCON ;T0IF=0

endlos goto endlos

End

Edit: Bitte Code-Tags verwenden.
Bernd
« Letzte Änderung: Juni 13, 2006, 21:42:28 von Bernd » Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #1 am: Juni 13, 2006, 21:42:59 »

Zitat
Das Problem ist kommt nach der CarryBit Abfrage.
Nach retfie (siehe Code) müsste der Programmzähler eigentlich wieder zur Hauptroutine zurückkehren, tut er aber nicht, stattdessen springt er wieder an Adresse 0x04 und führt die Interrupt Routine nochmal aus.

Code:
IR_Service
   org   0x04

   bcf     STATUS,C     
   btfss   PORTB,1     
   goto    setzeBit     
                       
   
   rrf     flag,F         
   btfsc   STATUS,C     
   retfie               ; Interrupt-Flag nicht gelöscht

Du hast vergessen, daß Interrupt-Flag vor diesem "retfie" zu löschen. Generell sollte man das Interrupt-Flag am Anfang der ISR löschen. Zum einen vermeidet man damit das mehrmalige Löschen, wie in Deinem Code, zum anderen vermindert das die allgemeine Gefahr, Interrupts zu "verpassen".


Viele Grüße

Bernd
Gespeichert

bastiz
Gast
« Antworten #2 am: Juni 14, 2006, 19:32:22 »

Klar, Danke für den Tipp.

Basti
Gespeichert
Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.063 Sekunden mit 19 Zugriffen.
 
Top! Top!