Interrupt bei 16F874A
Mittwoch, 23. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  Programmiersprache Assembler  |  Interrupt bei 16F874A « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: Interrupt bei 16F874A  (Gelesen 3282 mal)
 
DerFlo
Newbie
*
Offline Offline

Beiträge: 19



Profil anzeigen
« am: Oktober 17, 2011, 20:20:45 »

Hallo liebe Gemeinde,
ich bin momentan bei meiner BCD Uhr und wollte jetzt den Interrupt benutzen.
Meine idee ist folgende Timer2 soll mit 1:16 vorteilen,dann soll der Timer bis 250 zählen und nochmal mit 1:10 teilen,dadurch soll ein Interrupt ausgelöst werden (TMR2IF?)
Wenn der Interrupt ausgelöst wird soll der Pic schleife hochzählen.
Im Programm wird abgefragt ob schleife 25 ist und wenn ja, soll er 1 Sekunde hochzählen.
Zuvor habe ich es mit Nop schleifen gelöst und es hatte Erfolg, nun will er nichts mehr anzeigen.
Hoffe ihr könnt mir helfen.
Code:
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF







W_TEMP equ 0x20

STATUS_TEMP equ 0x21

Sekunden equ 0x22

Minuten equ 0x23

Stunden equ 0x24

schleife equ 0x25

PCLATH_TEMP equ 0x28



org 0

goto Start





org 4 ; Interrupt



MOVWF W_TEMP ;zum sichern der Daten

SWAPF STATUS,W

CLRF STATUS

MOVWF STATUS_TEMP

MOVF PCLATH, W

MOVWF PCLATH_TEMP

CLRF PCLATH ; Bank 0



incf schleife,f




MOVF PCLATH_TEMP, W

MOVWF PCLATH

SWAPF STATUS_TEMP,W

MOVWF STATUS

SWAPF W_TEMP,F

SWAPF W_TEMP,W

retfie ;Interrupt ende





Start

clrf PORTD

bsf STATUS,RP0

movlw b'00000000'

movwf TRISD

movlw b'00000000'

movwf TRISC

movlw b'00000000'

movwf TRISB

movlw b'11111010'

movwf 0x92

bcf STATUS,RP0



clrf PORTD

clrf PORTC

clrf PORTB

clrf Sekunden

clrf Minuten

clrf Stunden



movlw b'0101111'

movwf 0x12 ;Timer 2 anschalten,vorteiler auf 1:16 und nachteiler auf 1:10

bsf 0x0B,4

bsf 0x0B,7 ;Interrupts erlauben

bsf 0x0C,1 ;Interrupt bei Timer2 nachteiler überlauf




Anfang



movf schleife,w

sublw D'25'

btfss 0x03,2

goto Anfang

bcf 0x03,2

clrf schleife



incf Sekunden,f ; +1

movf Sekunden,w ; Sekunden ins Arbeitsregister

movwf PORTD ;vom Arbeitsregister in PORTD



movf Sekunden,w ;Sekunden ins Arbeitsregister laden

sublw D'60' ;59 - Sekunden

btfss 0x03,2 ;wenn Z = 1 nächster befehl wird übersprungen

goto Anfang ;gehe zum Anfang wenn Ergebnis verschieden von 0

bcf 0x03,2 ; Z=0



incf Minuten,f ;+1

movf Minuten,w ;minuten in Arbeitsregister laden

movwf PORTC ;Arbeitsregister in PortC verschieben

clrf Sekunden ;Sekunden auf 0 setzen

movf Sekunden,w ;Sekunden ins Arbeitsregister laden

movwf PORTD ;Sekunden ins Port D verschieben



movf Minuten ;Minuten ins Abreitsregister

sublw D'60' ;Minuten - 60

btfss 0x03,2 ;wenn Z verschienden 0 überspringe nächsten befehl

goto Anfang ;gehe zum anfang

bcf 0x03,2 ;Z=0



incf Stunden,f ;Stunden +1

movf Stunden,w

movwf PORTB

clrf Minuten

movf Minuten,w

movwf PORTC



movf Stunden

sublw D'24'

btfss 0x03,2

goto Anfang

bcf 0x03,2



clrf Stunden

movf Stunden,w

movwf PORTB





goto Anfang

* Neu Textdokument.txt (2.31 KB - runtergeladen 26 Mal.)
Gespeichert
Edson
Globaler Moderator
Sr. Member
*****
Offline Offline

Beiträge: 373



Profil anzeigen
« Antworten #1 am: Oktober 17, 2011, 21:30:34 »

Hallo Flo,

Zitat
Hoffe ihr könnt mir helfen.

Ich werds mal versuchen: Du hast vergessen das vom Timer2 ausgelöste Interrupt-Flag in der ISR zurückzusetzen und dein Programm bleibt in der ISR hängen.

Code:
MOVWF W_TEMP
SWAPF STATUS,W
CLRF STATUS
MOVWF STATUS_TEMP
MOVF PCLATH, W
MOVWF PCLATH_TEMP
CLRF PCLATH ; Bank 0

incf schleife,f
bcf   PIR1, TMR2IF    ;<-- fehlende Zeile

MOVF PCLATH_TEMP, W

MOVWF PCLATH
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W

retfie

Gruß,
Edson
Gespeichert
DerFlo
Newbie
*
Offline Offline

Beiträge: 19



Profil anzeigen
« Antworten #2 am: Oktober 18, 2011, 06:44:46 »

Danke für die schnelle hilfe aber das Programm funktioniert noch nicht.
Gespeichert
Edson
Globaler Moderator
Sr. Member
*****
Offline Offline

Beiträge: 373



Profil anzeigen
« Antworten #3 am: Oktober 18, 2011, 17:02:00 »

Danke für die schnelle hilfe

Gern geschehen.

Zitat
aber das Programm funktioniert noch nicht.

Es ist nicht so, dass ich dir nicht helfen will, aber ein wenig Eigenleistung musst du schon bringen. Dein Code ist nicht gut zu lesen, weil du absolute Adressen in Sedezimaldarstellung schreibst anstatt den Bezeichner aus dem offensichtlich (in der ISR verwendest du teilweise Bezeichner aus der P16F874A.inc) eingebundenen #include-Header zu verwenden. Daher wäre es nett von dir und in deinem Sinne, wenn du das änderst und gegebenenfalls nochmal genauer beschreibst, was denn eigentlich nicht funktioniert.
 
Sonst machst du es denen, die dir helfen wollen, nicht gerade leicht.

Gruß,
Edson
Gespeichert
DerFlo
Newbie
*
Offline Offline

Beiträge: 19



Profil anzeigen
« Antworten #4 am: Oktober 18, 2011, 17:31:39 »

ja das ist wohl war hab nochmal ein wenig verändert, das Problem ist das ich nicht weis was der PIC macht, auf jeden fall macht er momentan nichts in meiner Zielschaltung. Meine Idee war es den Timer 2 zu benutzen,ich habe eine 4MHz Quarz, das dürfte 1MHz internen Takt machen. 1.000.000 :16= 62.500 ; 62.500 : 250= 250 ; 250:10=25 .Der Pic sollte also also in einer Sekunde 25 einen Interrupt auslösen,dabei die Variable "schleife" um 1 erhöhen und dann wieder den Interrupt verlassen und im Programm "Anfang" immer wieder gucken ob "schleife" = 25 . Überprüft wird dies indem "schleife" minus 25 null ergibt und dadurch im STATUS Register Z setzt.

Code:
list        p=16f874a   ; list directive to define processor

    #include    <p16f874a.inc>  ; processor specific variable definitions

   

    __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF







W_TEMP equ 0x20

STATUS_TEMP equ 0x21

Sekunden equ 0x22

Minuten equ 0x23

Stunden equ 0x24

schleife equ 0x25

loops equ 0x26 ; Wartezeit für WAIT in Millisekunden

loops2 equ 0x27

PCLATH_TEMP equ 0x28



org 0

goto Start









org 4 ; Interrupt



MOVWF W_TEMP

SWAPF STATUS,W

CLRF STATUS

MOVWF STATUS_TEMP

MOVF PCLATH, W

MOVWF PCLATH_TEMP

CLRF PCLATH ; Bank 0



incf schleife,f

bcf PIR1 , TMR2IF





MOVF  PCLATH_TEMP, W

MOVWF PCLATH

SWAPF STATUS_TEMP,W

MOVWF STATUS

SWAPF W_TEMP,F

SWAPF W_TEMP,W

retfie ;Interrupt ende







Start

clrf PORTD

bsf STATUS,RP0

movlw b'00000000'

movwf TRISD

movlw b'00000000'

movwf TRISC

movlw b'00000000'

movwf TRISB

movlw b'11111010' ;bis 250 zählen

movwf PR2

bcf STATUS,RP0



clrf PORTD

clrf PORTC

clrf PORTB

clrf Sekunden

clrf Minuten

clrf Stunden





movlw b'0101111'

movwf T2CON ;Timer 2 anschalten,vorteiler auf 1:16 und nachteiler auf 1.10

bsf INTCON,INTE

bsf INTCON,GIE ;Interrupts erlauben

bsf PIR1,TMR2IF ;Interrupt bei Timer2 überlauf





Anfang





movf schleife,w

sublw D'25'

btfss STATUS,Z

goto Anfang

bcf STATUS,Z

clrf schleife



incf Sekunden,f ; +1

movf Sekunden,w ; Sekunden ins Arbeitsregister

movwf PORTD ;vom Arbeitsregister in PORTD



movf Sekunden,w ;Sekunden ins Arbeitsregister laden

sublw D'60' ;59 - Sekunden

btfss STATUS,Z ;wenn Z = 1 nächster befehl wird übersprungen

goto Anfang ;gehe zum Anfang wenn Ergebnis verschieden von 0

bcf STATUS,Z ; Z=0



incf Minuten,f ;+1

movf Minuten,w ;minuten in Arbeitsregister laden

movwf PORTC ;Arbeitsregister in PortC verschieben

clrf Sekunden ;Sekunden auf 0 setzen

movf Sekunden,w ;Sekunden ins Arbeitsregister laden

movwf PORTD ;Sekunden ins Port D verschieben



movf Minuten ;Minuten ins Abreitsregister

sublw D'60' ;Minuten - 60

btfss STATUS,Z ;wenn Z verschienden 0 überspringe nächsten befehl

goto Anfang ;gehe zum anfang

bcf STATUS,Z ;Z=0



incf Stunden,f ;Stunden +1

movf Stunden,w

movwf PORTB

clrf Minuten

movf Minuten,w

movwf PORTC



movf Stunden

sublw D'24'

btfss STATUS,Z

goto Anfang

bcf STATUS,Z



clrf Stunden

movf Stunden,w

movwf PORTB





goto Anfang



END
Gespeichert
DerFlo
Newbie
*
Offline Offline

Beiträge: 19



Profil anzeigen
« Antworten #5 am: Oktober 19, 2011, 11:03:17 »

Hallo,hatte ganz vergessen im PIE das bit zu setzen,dadurch wurde der ineterrupt nie ausgelöst.
Danke für die unterstützung  Smiley
Gespeichert
Edson
Globaler Moderator
Sr. Member
*****
Offline Offline

Beiträge: 373



Profil anzeigen
« Antworten #6 am: Oktober 19, 2011, 12:20:10 »

Hallo,hatte ganz vergessen im PIE das bit zu setzen,dadurch wurde der ineterrupt nie ausgelöst.
Danke für die unterstützung  Smiley

Freut mich, dass du es selbst herausgefunden hast und noch mehr freut mich, dass du Ursache und Lösung hier mitteilst. Danke dafür Smiley

Gruß,
Edson
« Letzte Änderung: Oktober 19, 2011, 12:25:26 von Edson » 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 17 Zugriffen.
 
Top! Top!