Forum: Mikrocontroller und Digitale Elektronik Timer0 -Interrupt-Pic16F88


von Sabine M. (zizo)


Lesenswert?

Hallo
ich habe ein Programm geschrieben, in dem ein LED blinken lassen , und 
der Timer0 zählt die Anzahl von Bliken, wenn der Anzahl der Blinken den 
wert 6 Erreicht löst diese Timer ein Interrupt diese Interrupt schaltet 
ein andere LED ein.
Wenn ich mein Pic mit der Testplatine anschließe blinkt nur der erste 
LED ständig und es wird keine Interupt glöst?
kann mir Jemand helfen!
  #include <P16F88.inc>
LED equ 0
LED1 equ 1
Wait1 equ 0x25
Wait2 equ 0x26

W_TEMP  equ 0x30
STATUS_TEMP equ 0x31
PCLATH_TEMP equ 0x32

  org 0x0000



  ;bsf STATUS, RP0
;  bcf OSCTUNE, 0x00  Oscillator Initialisierung

;__CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & 
_WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & 
_PWRTE_ON & _WDT_OFF & _EXTRC_IO
;__CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF
__CONFIG   _CONFIG1,     _PWRTE_ON & _WDT_OFF

goto MainInit

Interrupt
  MOVWF W_TEMP ;Copy W to TEMP register
  SWAPF STATUS, W ;Swap status to be saved into W
  CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
  MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP register
  MOVF PCLATH, W ;Only required if using page 1
  MOVWF PCLATH_TEMP ;Save PCLATH into W
  CLRF PCLATH ;Page zero, regardless of current page
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  bcf STATUS, RP0
  bsf PORTA, LED1  ; LED Leuchten
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  MOVF PCLATH_TEMP, W ;Restore PCLATH
  MOVWF PCLATH ;Move W into PCLATH
  SWAPF STATUS_TEMP, W ;Swap STATUS_TEMP register into W
  ;(sets bank to original state)
  MOVWF STATUS ;Move W into STATUS register
  SWAPF W_TEMP, F ;Swap W_TEMP
  SWAPF W_TEMP, W ;Swap W_TEMP into W
  bcf     STATUS, RP0
  bcf     INTCON, TMR0IF    ; Interrupt-Flag löschen
    bsf     INTCON, GIE     ; enable Interrupt (macht RETFIE aber auch 
allein)
  retfie
MainInit

  bsf STATUS, RP0
  movlw 0x00
  movwf ANSEL
  movlw   B'10100000'     ; Timer0 für Pin RA4 wählen
    movwf   OPTION_REG


  bsf     INTCON, TMR0IE    ; Timer0 interrupt erlauben
    bsf     INTCON, GIE       ;Interrpt erlauben
  bcf TRISA, LED
  bcf STATUS, RP0    ;Bank 0
  movlw   d'250'          ; TImer ab 250 zählt
    movwf   TMR0
  bsf PORTA, LED  ;LED leuchtet
  call Warten    ;zum Unterprogramm;


  bcf STATUS, RP0
  bcf PORTA, LED  ;LED leuchtet nicht
  call Warten    ;zum Unterprogramm;

  goto MainInit
Warten
      ;Wartezeit initialisierung
  movlw 0x25
  movwf Wait2
loop2

  movlw 0x25    ;Wartezeit initialisierung
  movwf Wait1

loop

  decfsz Wait1,1
  goto loop
  decfsz Wait2,1
  goto loop2
  retlw   .0



  end

von Sven S. (stepp64) Benutzerseite


Lesenswert?

Mal ins blaue: Deine Interruptroutine fängt nicht auf der Adresse 0x04 
an.
Da fehlt ein org 0x04 vor der Interruptroutine.

Sven

von Chris S. (schris)


Lesenswert?

Weiterer Fehler,
  bsf     INTCON, GIE     ; enable Interrupt (macht RETFIE aber auch
Innerhalb dem Interrupt erlaubst du so nested Interrupts, hast aber 
keine SW, welche nested Interrupts bedienen kann, nichts fuer Anfaenger.

Weiters ist die Config auskommentiert, also koennte dir auch der WDT
reinpfuschen. Andere sache, schau nochmals im Datasheet nach, wie man
den Prescaler auf WDT rumaendert, denn sonst kann ein Reset daraus
resultieren, solltest du das falsch machen.

von Sabine M. (zizo)


Lesenswert?

ich danke euch, aber das funktioniert immer noch nicht...?

von Chris (Gast)


Lesenswert?

Weiterer Fehler, du setzt für LED1 nicht das TRIS als Ausgang, also
wird dir LED1 nicht funktionieren. Zudem invertierst du es nicht, also
schaltest du es nur ein. Ist das mit dem WDT geklärt ?

von Sabine M. (zizo)


Lesenswert?

Hallo,
ich habe mein Programm korrigiert, aber es leuchtet die zweite LED immer 
noch nicht , ich habe der Register OPTION_REG geändert in dem der Timer 
mit interne Takt arbeitet, das hat funktioniert, aber mit externe Takt 
(erste LED)funktioniert es nicht, bitte kann mir jemand helfen, das wäre 
nett
  #include <P16F88.inc>
LED equ 0
LED1 equ 1
Wait1 equ 0x25
Wait2 equ 0x26

W_TEMP  equ 0x70
STATUS_TEMP equ 0x31
PCLATH_TEMP equ 0x72

org 0x0000




__CONFIG   _CONFIG1,     _PWRTE_ON & _WDT_OFF

goto MainInit

Interrupt
  org  0x04
  bsf STATUS, RP0
  bcf     INTCON, GIE
  bcf   INTCON, TMR0IE
  bcf   INTCON, TMR0IF
  MOVWF W_TEMP ;Copy W to TEMP register
  SWAPF STATUS, W ;Swap status to be saved into W
  CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
  MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP register
  MOVF PCLATH, W ;Only required if using page 1
  MOVWF PCLATH_TEMP ;Save PCLATH into W
  CLRF PCLATH ;Page zero, regardless of current page
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  bsf STATUS, RP0
  bcf TRISA, LED1
  bcf STATUS, RP0
  bsf PORTA, LED1  ; LED Leuchten
  call Warten
  bcf PORTA, LED1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  MOVF PCLATH_TEMP, W ;Restore PCLATH
  MOVWF PCLATH ;Move W into PCLATH
  SWAPF STATUS_TEMP, W ;Swap STATUS_TEMP register into W
  ;(sets bank to original state)
  MOVWF STATUS ;Move W into STATUS register
  SWAPF W_TEMP, F ;Swap W_TEMP
  SWAPF W_TEMP, W ;Swap W_TEMP into W
  bcf     STATUS, RP0
  bcf     INTCON, TMR0IF    ; Interrupt-Flag löschen
  movlw   0xFA          ; TImer ab 250 zählt
     movwf   TMR0
  retfie
MainInit

  bsf STATUS, RP0
  movlw 0x00
  movwf ANSEL
  movlw   B'11100000'     ; Timer0 für Pin RA4 wählen
    movwf   OPTION_REG
  bcf STATUS, RP0    ;Bank 0
  movlw   0xFA          ; TImer ab 250 zählt
    movwf   TMR0
  bsf STATUS, RP0
  bcf TRISA, LED

  bcf STATUS, RP0    ;Bank 0

  bsf PORTA, LED  ;LED leuchtet
  call Warten    ;zum Unterprogramm;
  bsf STATUS, RP0
  bcf STATUS, RP0
  bcf PORTA, LED  ;LED leuchtet nicht
  call Warten    ;zum Unterprogramm;
  bsf     INTCON, TMR0IE    ; Timer0 interrupt erlauben
    bsf     INTCON, GIE       ;Interrpt erlauben

  goto MainInit
Warten
      ;Wartezeit initialisierung
  movlw 0x25
  movwf Wait2
loop2

  movlw 0x25    ;Wartezeit initialisierung
  movwf Wait1

loop

  decfsz Wait1,1
  goto loop
  decfsz Wait2,1
  goto loop2
  retlw   .0



  end

von Chris S. (schris)


Lesenswert?

org  0x04
Interrupt ; das kommt nach dem ORG, sonst ist der Label falsch

  MOVWF W_TEMP        ; save W
  SWAPF STATUS, W     ; save STATUS
  MOVWF STATUS_TEMP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
int_tmr0
  btfsc   INTCON, TMR0IE    ; check if tmr0 is enabled
  btfsc   INTCON, TMR0IF    ; check if tmr0 is triggered
  goto    int_done          ; goto to next interrupt check
  goto    $+1               ; time adjust for prescaler
  movlw   -244 ; -256+(12/PRESCALER)   ; TImer ab 250
     movwf   TMR0

  btfss PORTA,LED1
  bsf  PORTA,LED1
  btfsc PORTA,LED1
  bcf  PORTA,LED1

  bcf     INTCON, TMR0IF    ; Interrupt-Flag löschen

  ; !!! call Warten ; macht man nicht in einer Interrupt
int_done
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  SWAPF STATUS_TEMP, W
  MOVWF STATUS    ; restore W and STATUS
  SWAPF W_TEMP, F
  SWAPF W_TEMP, W

  retfie

MainInit

  movlw  ~3
  movwf PORTA
  bsf STATUS, RP0
  clrf ANSEL
  movwf TRISA
  movlw   B'11100000'     ; Timer0 für Pin RA4 wählen
    movwf   OPTION_REG
  bcf STATUS, RP0    ;Bank 0
  movlw   -250          ; TImer ab 250 zählt
    movwf   TMR0
  bsf     INTCON, TMR0IE    ; Timer0 interrupt erlauben
  bsf     INTCON, GIE       ;Interrpt erlauben

Main
  call Warten
  bcf PORTA, LED
  call Warten    ;zum Unterprogramm;
  bsf PORTA, LED
  call Warten    ;zum Unterprogramm;
  goto Main

Warten
      ;Wartezeit initialisierung
  movlw 0x25
  movwf Wait2
loop2

  movlw 0x25    ;Wartezeit initialisierung
  movwf Wait1

loop

  decfsz Wait1,1
  goto loop
  decfsz Wait2,1
  goto loop2
  retlw   .0



  end

von Sabine M. (zizo)


Lesenswert?

vielen Dank chris,
ich habe dein Programm auf meinen Pic gebrennt, aber es hat nicht 
funktioniert, dei LED blinkt 161 mal dann blikt er nicht mehr (bleibt am 
leuchten) und die LED1 blinkt nicht.

von chris (Gast)


Lesenswert?

poste dann nochmals den code

von Sabine M. (zizo)


Lesenswert?

Danke Chris
das ist nochmal den Code,
  #include <P16F88.inc>
LED equ 0
LED1 equ 1
Wait1 equ 0x25
Wait2 equ 0x26

W_TEMP  equ 0x70
STATUS_TEMP equ 0x31
PCLATH_TEMP equ 0x72

org 0x0000




__CONFIG   _CONFIG1,     _PWRTE_ON & _WDT_OFF

goto MainInit
org  0x04
Interrupt ; das kommt nach dem ORG, sonst ist der Label falsch

  MOVWF W_TEMP        ; save W
  SWAPF STATUS, W     ; save STATUS
  MOVWF STATUS_TEMP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
int_tmr0
  btfsc   INTCON, TMR0IE    ; check if tmr0 is enabled
  btfsc   INTCON, TMR0IF    ; check if tmr0 is triggered
  goto    int_done          ; goto to next interrupt check
  goto    $+1               ; time adjust for prescaler
  movlw   -250 ; -256+(12/PRESCALER)   ; TImer ab 250
     movwf   TMR0

  btfss PORTA,LED1
  bsf  PORTA,LED1
  btfsc PORTA,LED1
  bcf  PORTA,LED1

  bcf     INTCON, TMR0IF    ; Interrupt-Flag löschen

  ; !!! call Warten ; macht man nicht in einer Interrupt
int_done
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  SWAPF STATUS_TEMP, W
  MOVWF STATUS    ; restore W and STATUS
  SWAPF W_TEMP, F
  SWAPF W_TEMP, W

  retfie

MainInit

  movlw  ~3
  movwf PORTA
  bsf STATUS, RP0
  clrf ANSEL
  movwf TRISA
  movlw   B'11100000'     ; Timer0 für Pin RA4 wählen
    movwf   OPTION_REG
  bcf STATUS, RP0    ;Bank 0
  movlw   -250          ; TImer ab 250 zählt
    movwf   TMR0
  bsf     INTCON, TMR0IE    ; Timer0 interrupt erlauben
  bsf     INTCON, GIE       ;Interrpt erlauben

Main
  call Warten
  bcf PORTA, LED
  call Warten    ;zum Unterprogramm;
  bsf PORTA, LED
  call Warten    ;zum Unterprogramm;
  goto Main

Warten
      ;Wartezeit initialisierung
  movlw 0x25
  movwf Wait2
loop2

  movlw 0x25    ;Wartezeit initialisierung
  movwf Wait1

loop

  decfsz Wait1,1
  goto loop
  decfsz Wait2,1
  goto loop2
  retlw   .0



  end

von Sabine M. (zizo)


Lesenswert?

Übrigens ich habe mit

  movlw   -244 ; -256+(12/PRESCALER)   ; TImer ab 250
     movwf   TMR0
und mit

  movlw   -250 ; -256+(12/PRESCALER)   ; TImer ab 250
     movwf   TMR0
versucht aber es klapptnicht

Grüße

von schris (Gast)


Lesenswert?

das -244, sprich 12 ist als Korrektur für die Zeit da, welche bereits
für das ISR entry sowie context saving verbraucht wurden, damit der 
Timer  wieder in 500 uS nach dem letzten mal triggert, denn sonst sind 
es 250+die Zeit im ISR, also ein fehler von 2.4%, der aber kumulativ 
ist.

Das call Warten vor dem goto Main ist zu viel, das braucht es nicht.

Dachte vielleicht, daß du ev. ein - vor den Timerwerten vergessen hast,
was aber nicht der Fall ist.

füge ev. noch das rein, ev. ist dein Radix hex
  LIST P=16F88, R=DEC, n=61, c=78
  errorlevel 0,-305

sowie im ISR, ein
 movlw 1<<LED1
 xorwf PORTA

 anstatt der vier Zeilen die LED1 testen und setzen.

 Was ich gerade gesehen habe, im ISR entry fehlt for int_tmr0
 ein clrf STATUS, dadurch verändert sich auch das Timing, und du
 musst dann das folgende GOTO $+1 durch ein NOP ersetzen.

von Sabine M. (zizo)


Lesenswert?

Danke,
aber ich habe das nicht verstanden.
LIST P=16F88, R=DEC, n=61, c=78
  errorlevel 0,-305

von Sabine M. (zizo)


Lesenswert?

ich habe dein Code geschrieben aber das klappt nicht. der erste LED 
blinkt mehr als 6 mal dann irgendwann leuchtet weiter, und LED 2 blinkt 
nicht.
Grüße

von schris (Gast)


Lesenswert?

Dann test mal das, ohne Interrupts, um den Fehler einzugrenzen.
port_a equ 20 ; hidden port register
 kommentiere das folgende raus, und fergiss das radix dec nicht.
  ;bsf     INTCON, TMR0IE    ; Timer0 interrupt erlauben
  ;bsf     INTCON, GIE       ;Interrpt erlauben

Main veränderst du folgendermaßen:
Main
  call Warten
  movlw 1<<LED
  xorwf PORTA ; toggle led
  btfss INTCON, TMR0IF ; if !tmr0 expired
  goto Main
  movlw 1<<LED1
  xorwf PORTA ; toggle LED1
  bcf INTCON, TMR0IF ; clear tmr0 overflow
  goto Main

Ergebniss sollte sein, LED blinkt, und LED1 sollte langsamer blinken,
eigentlich wenn ich richtig geschätzt habe, LED mit 12ms ein/aus Zyklus
und LED1 mit 500ms ein/aus zyklus, +-12ms bei LED1.

Sollte das klappen, weiss man dann, der Fehler liegt im Interrupt code,
sonst ist es irgendetwas anderes.

Hast du eigntlich den clrf STATUS vor int_tmr0 eingefügt ?, sonst könnte
das das Problem darstellen.

von Sabine M. (zizo)


Lesenswert?

Hallo schris,

ich war die ganze Zeit am probieren, diese Code funktioniert ganz gut, 
aber ohne Interrupt,
  #include <P16F88.inc>
LED equ 0
LED1 equ 1
Wait1 equ 0x25
Wait2 equ 0x26
port_a equ 20

W_TEMP  equ 0x70
STATUS_TEMP equ 0x31
PCLATH_TEMP equ 0x72

org 0x0000
LIST P=16F88, R=DEC, n=61, c=78
  errorlevel 0,-305




__CONFIG   _CONFIG1,     _PWRTE_ON & _WDT_OFF

goto MainInit
MainInit

  movlw  ~3
  movwf PORTA
  bsf STATUS, RP0
  clrf ANSEL
  movwf TRISA
  movlw   B'11100000'     ; Timer0 für Pin RA4 wählen
  movwf   OPTION_REG
  bcf STATUS, RP0    ;Bank 0
Main1
  movlw   0xFE          ; TImer ab 250 zählt
    movwf   TMR0
  bcf INTCON, TMR0IF ; clear tmr0 overflow
Main
call Warten
  movlw 1<<LED
  xorwf PORTA ; toggle led
  btfss INTCON, TMR0IF ; if !tmr0 expired
  goto Main
 bsf PORTA, LED1  ; LED Leuchten
  call Warten
  bcf PORTA, LED1
  bcf INTCON, TMR0IF ; clear tmr0 overflow
  goto Main1
Warten
      ;Wartezeit initialisierung
  movlw 0x25
  movwf Wait2
loop2

  movlw 0x25    ;Wartezeit initialisierung
  movwf Wait1

loop

  decfsz Wait1,1
  goto loop
  decfsz Wait2,1
  goto loop2
  retlw   .0


  end

Wenn ich die Interrupt code rein bringe dann blinkt der LED immer weiter
 und es blinkt die LED1 nicht,der Code mit Interrupt


  #include <P16F88.inc>
LED equ 0
LED1 equ 1
Wait1 equ 0x25
Wait2 equ 0x26
port_a equ 20

W_TEMP  equ 0x70
STATUS_TEMP equ 0x31
PCLATH_TEMP equ 0x72

org 0x0000
LIST P=16F88, R=DEC, n=61, c=78
  errorlevel 0,-305




__CONFIG   _CONFIG1,     _PWRTE_ON & _WDT_OFF

goto MainInit
org  0x04
Interrupt

  bsf STATUS, RP0
  bcf     INTCON, GIE
  bcf   INTCON, TMR0IE
  bcf   INTCON, TMR0IF
  MOVWF W_TEMP ;Copy W to TEMP register
  SWAPF STATUS, W ;Swap status to be saved into W
  CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
  MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP register
  MOVF PCLATH, W ;Only required if using page 1
  MOVWF PCLATH_TEMP ;Save PCLATH into W
  CLRF PCLATH ;Page zero, regardless of current page
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  bsf STATUS, RP0
  bcf TRISA, LED1
  bcf STATUS, RP0
  bsf PORTA, LED1  ; LED Leuchten
  nop
  nop
  nop
  ;call Warten
  bcf PORTA, LED1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  MOVF PCLATH_TEMP, W ;Restore PCLATH
  MOVWF PCLATH ;Move W into PCLATH
  SWAPF STATUS_TEMP, W ;Swap STATUS_TEMP register into W
;(sets bank to original state)
  MOVWF STATUS ;Move W into STATUS register
  SWAPF W_TEMP, F ;Swap W_TEMP
  SWAPF W_TEMP, W ;Swap W_TEMP into W
  bcf     STATUS, RP0
  bcf     INTCON, TMR0IF    ; Interrupt-Flag löschen
  movlw   0xFE          ; TImer ab 250 zählt
    movwf   TMR0
  retfie
MainInit

  movlw  ~3
  movwf PORTA
  bsf STATUS, RP0
  clrf ANSEL
  movwf TRISA
  movlw   B'11100000'     ; Timer0 für Pin RA4 wählen
  movwf   OPTION_REG
  bcf STATUS, RP0    ;Bank 0
 bsf     INTCON, TMR0IE    ; Timer0 interrupt erlauben
  bsf     INTCON, GIE       ;Interrpt erlauben
Main1
  movlw   0xFE          ; TImer ab 250 zählt
    movwf   TMR0
  bcf INTCON, TMR0IF ; clear tmr0 overflow
Main
call Warten
  movlw 1<<LED
  xorwf PORTA ; toggle led
bsf PORTA, LED  ; LED Leuchten
  call Warten
  bcf PORTA, LED
  goto Main1
Warten
      ;Wartezeit initialisierung
  movlw 0x25
  movwf Wait2
loop2

  movlw 0x25    ;Wartezeit initialisierung
  movwf Wait1

loop

  decfsz Wait1,1
  goto loop
  decfsz Wait2,1
  goto loop2
  retlw   .0


  end

von gast (Gast)


Lesenswert?

Kritik an Code ohne Interrupt
org 0x0000
LIST P=16F88, R=DEC, n=61, c=78
da gehört ein Tab oder Leerzeichen davor.
LED1 würde ich Invertieren, gleich wie LED
  movlw 1<<LED1
  xorwf PORTA ; toggle led
an stelle von
 bsf PORTA, LED1  ; LED Leuchten
  call Warten
  bcf PORTA, LED1

denn dann veränderst du nicht das timing von LED.

Jetzt komme ich zum Code mit Interrupt
Diese Zeilen sind totaler blödsinn
  bsf STATUS, RP0          ; Du veränderst das Statusregister im Main 
!!!
  bcf     INTCON, GIE      ; Das passiert automatisch
  bcf   INTCON, TMR0IE     ; wieso deaktivierst du den TMR0 Interrupt ?
  bcf   INTCON, TMR0IF     ; Das solltest du nach dem behandeln des Tmr0 
int machen


  MOVWF W_TEMP ;Copy W to TEMP register
  SWAPF STATUS, W ;Swap status to be saved into W
  CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
  MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP register
Erst hier darfst du dann was verändern, da du W sowie Status des Main
gespeichert hast.
  MOVF PCLATH, W ;Only required if using page 1
  MOVWF PCLATH_TEMP ;Save PCLATH into W
  CLRF PCLATH ;Page zero, regardless of current page
Da du keine computed Goto in deiner Interrupt Routine verwendest, sind
die obigen Zeilen unnötig.
Eventuell, wenn du FSR verwenden solltest, mußt du das auch sichern,
aber nur als Bemerkung am Rande.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  bsf STATUS, RP0
  bcf TRISA, LED1
  bcf STATUS, RP0
Das ist schon initialisiert, also sind die obigen Zeilen Sinnlos.
hier sollte noch eine Abfrage auf tmr0if reinkommen, also
  btfsc INTCON, TMR0IE
  btfss INTCON, TMR0IF
  goto int_done
Es kann nähmlich passieren, daß ein unerwarteter Interrupt auftritt,
oder ein anderer Interrupt getriggert wird.
  bsf PORTA, LED1  ; LED Leuchten
  nop
  nop
  nop
  ;call Warten
  bcf PORTA, LED1
Die Led leuchtet für 4 uS, wäre es nicht sinnvoller, die Led einfach zu 
Invertieren, mit
  movlw 1<<LED1
  xorwf PORTA
Abgesehen davon, daß das Warten auskommentiert ist, ein ISR sollte nicht
solange laufen.
Das
  bcf INTCON, TMR0IF
sollte hier noch reinkommen.
int_done
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  MOVF PCLATH_TEMP, W ;Restore PCLATH
  MOVWF PCLATH ;Move W into PCLATH
  SWAPF STATUS_TEMP, W ;Swap STATUS_TEMP register into W
;(sets bank to original state)
  MOVWF STATUS ;Move W into STATUS register
  SWAPF W_TEMP, F ;Swap W_TEMP
  SWAPF W_TEMP, W ;Swap W_TEMP into W
Die obigen Befehle haben die Register für den Main Code 
wiederhergestellt,
wieso pfuscht du dann danach noch rein, danach darf nur noch ein RETFIE 
kommen. !!!
  retfie



  bcf     STATUS, RP0
  bcf     INTCON, TMR0IF    ; Interrupt-Flag löschen
Bei deinem Code hast du TMR0IE gelöscht, also wird kein weiterer 
Interrupt
generiert.
  movlw   0xFE          ; TImer ab 250 zählt
    movwf   TMR0
Das kommt am Anfang des INT_TMR0, denn du musst auch die im Interrupt
bereits verarbeiteten Befehle kompensieren, damit du ein konstanten TMR0
Interrupt hast.
Du lädst den Wert mit 250 und hast einen prescaler von 2, also
hast du den nächsten Interrupt in 12 Befehlen/uS. Deine Interruptroutine
ist ja größer, du wirst dann nie mehr in den Main kommen.
Ich dachte, du möchtest den Timer in 500uS haben, deshalb hatte ich
 movlw -250 ; beachte das Minus,
 movwf tmr0
geschrieben, sowie 12 Instruktionszyklen / prescaler abgezogen, um den
Timingfehler zu kompensieren. Daraus ist dann ein -244 geworden, mit
den zusätzlichen Nops, damit kein Timingfehler generiert wird, und somit
der Interrupt jede 500 uS ausgelöst wird.

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
Noch kein Account? Hier anmelden.