Timer 1
Montag, 21. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  Programmiersprache Assembler  |  Timer (Assembler)  |  Timer 1 « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: Timer 1  (Gelesen 3669 mal)
 
MZorni
Newbie
*
Offline Offline

Beiträge: 3


Profil anzeigen
« am: Oktober 15, 2007, 20:53:33 »

Hallo
ich bin neu im PIC Segment.
Ich habe versucht einen Interrup per Timer 1 auszulösen der alle 500ms ausgelöst wird. Leider gelingt mir das nicht.
PIC 16F876
Habe mein Programm angehängt.
Ich hoffe es kann mir einer der Profis weiterhelfen und mir meinen Fehler zeigen.
DANKE

* Timer1.asm (8.71 KB - runtergeladen 239 Mal.)
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #1 am: Oktober 15, 2007, 23:35:55 »

Zitat
Ich habe versucht einen Interrup per Timer 1 auszulösen der alle 500ms ausgelöst wird. Leider gelingt mir das nicht.

Welches Verhalten erwartest Du überhaupt vom Programm? Der Timer-Interrupt löscht RB2 und bewirkt damit keine Veränderung (RB2 wird an keiner anderen Stelle gesetzt).

Zitat
Code:
bcf PORTB,2

Abgesehen davon ist mir folgendes aufgefallen:

Code:
w_copy Equ 0x2E              ; w_copy liegt in Bank0, muß aber unbanked sein (0x70 - 0x7F).
                              ; denn
;W Retten
movwf w_copy       ; Sicherung kann fehlschlagen, da RAM-Bank zu diesem Zeitpunkt
                              ; unbekannt ist
 
 
Code:
intvec
bcf INTCON, GIE   ; unnötig, beim Einsprung in die ISR werden weitere Interrupts
                              ; automatisch deaktivert

Code:
; Interrupt Flag löschen
bsf INTCON, GIE   ; GIE darf niemals in der ISR gesetzt werden, das
                              ; geschieht automatisch durch retfie

Code:
; PCLATH Retten
movf pc_copy,1     ; darf nicht nach dem Retten von STATUS stehen, denn
                              ; movf verändert das Z-Flag im Status-Register
                              ; abgesehen davon ist hier die ausgewählte Bank
                              ; unbekannt (STATUS vorher wiederhergestellt!)


Code:
    btfsc PIR1,TMR1IF         ; Das Interrupt-Flag wird in der ISR zurückgesetzt und ein
    bsf PORTB,5               ; gesetztes Flag bewirkt den Sprung in die ISR             
                              ; Abfrage in main kann daher nicht funktionieren

Außerdem ist an mehreren Stellen die "1" falsch (deshalb immer "W" oder "F" verwenden):

Code:
    swapf    STATUS,1 ; Status nach W kopieren

    movf     PCLATH,1

    movf     pc_copy,1

Alle Befehle schreiben in das File-Register selbst, nicht in W.


Viele Grüße

Bernd
« Letzte Änderung: Oktober 16, 2007, 05:24:32 von Bernd » Gespeichert

MZorni
Newbie
*
Offline Offline

Beiträge: 3


Profil anzeigen
« Antworten #2 am: Oktober 16, 2007, 22:38:22 »

Servus
Danke Bend für die Hinweise habe sie auch versucht umzusetzen.
Leider läuft das Programm noch nicht.
Zu deine Frage was dieses Programm machen soll:
Mit Timer1 soll alle 500ms ein Interrupt ausgelöst werden, dieser wird an RB2 wieder gespiegelt. Gleichzeitig läuft eine Endloschleife die RB7 im ca. Sekundentakt blinken lassen soll.
RB6 dient nur um zu sehen ob dieser Part des Programms durlaufen wird.
Mit diesem Programm wollte ich nur die Interruptfunktion kennenlernen.

* Timer1_1.asm (10.92 KB - runtergeladen 175 Mal.)
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #3 am: Oktober 17, 2007, 05:51:29 »

Sobald RB2 nach dem ersten Interrupt auf "1" gesetzt worden ist, passiert in jedem weiteren Interrupt folgendes:

Code:
; angenommen, RB2 = 1
btfsc PORTB,2 ; nächster Befehl wird nicht übersprungen
bcf   PORTB,2 ; -> RB2 = 0
btfss PORTB,2 ; nächster Befehl wird nicht übersprungen
bsf   PORTB,2 ; -> RB2 = 1

RB2 wird also nur ganz kurz "0" und sofort wieder auf "1" gesetzt (an der LED nicht sichtbar). Das gilt auch für RB7 in main.

Zum Toggeln der LED kannst Du einfach eine XOR-Verknüpfung verwenden:

Code:
    movlw   B'00000100'
    xorwf   PORTB, F      ; toggle RB2

Zitat
Code:
; STATUS wieder herstellen
swapf s_copy, W ; s_copy nach W kopieren
movwf STATUS  ; W nach Status kopieren
; W wieder herstellen$
swapf w_copy, F ; Flags w_copy nach W
swapf w_copy, W ; Kopiere w_copy nach W

bcf PIR1, TMR1IF ; Timer1 Interrupt-Flag löschen

Das Interrupt-Flag muß vor der Wiederherstellung gelöscht werden. Nach der Wiederherstellung von STATUS ist die ausgewählte RAM-Bank unbekannt, der bcf-Befehl könnte hier also auf PIR1, PIE1, EEDATA oder EECON1 wirken (abhängig davon, welche Bank zum Zeitpunkt des Interrupts ausgewählt war).


Viele Grüße

Bernd
Gespeichert

MZorni
Newbie
*
Offline Offline

Beiträge: 3


Profil anzeigen
« Antworten #4 am: Oktober 17, 2007, 21:40:24 »

Servue Bernd
jetzt läuft das ganze!!!
Danke für die Hilfe
 :yahoo:
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.038 Sekunden mit 19 Zugriffen.
 
Top! Top!