-         

Ergebnis 1 bis 8 von 8

Thema: PIC 16f628 -> Timer2 Interrupt

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.05.2007
    Beiträge
    5

    PIC 16f628 -> Timer2 Interrupt

    Anzeige

    Hi

    Der Timer2 soll nach dem erreichen des gewünschten Wertes einen Interrupt auslösen.

    Wie kann ich PEIE setzten?

    Wie löse ich einen Interrupt aus?

    Vielen Dank schon mal

    MFG

    EGSLER

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.12.2005
    Ort
    Euskirchen-Großbüllesheim
    Alter
    67
    Beiträge
    2.063
    Das Ein- / Ausschalten des peripheren und globalen Interrupts kann per DEFINE
    Code:
    #DEFINE	D_GlobIntEin	bsf	INTCON,GIE	; Globaler Interrupt Ein
    #DEFINE	D_GlobIntAus	bcf	INTCON,GIE	; Globaler Interrupt Aus
    #DEFINE	D_PeriIntEin	bsf	INTCON,PEIE	; Peripherer Interrupt Ein
    #DEFINE	D_PeriIntAus	bcf	INTCON,PEIE	; Peripherer Interrupt Aus
    oder durch die Befehle
    Code:
    	bsf	INTCON,GIE	; Globaler Interrupt Ein
    	bcf	INTCON,GIE	; Globaler Interrupt Aus
    	bsf	INTCON,PEIE	; Peripherer Interrupt Ein
    	bcf	INTCON,PEIE	; Peripherer Interrupt Aus
    erfolgen.

    Timer werden incrementiert / um 1 erhöht und setzen bei jedem Überlauf von 255 / 0xFF nach 0 das Interrupt-Flag T?IF. Diese Flags müssen per Software zurück gesetzt werden.
    Wieviel Zeit zwischen jedem Timer-Increment vergeht, wird durch die Quarz-Frequenz und die Initialisierung der Prescaler bestimmt,
    wie lange es bis zum Auslösen eines Interrupts dauert = 256 - Timer-Wert mal Increment-Zeit.

    Zum Auslösen eines Interrupts / Aufruf der ISR (Interrupt-Service-Routine) muß das entsprechende IE-Flag und die globale Int-Freigabe GIE gesetzt sein. Für einige Timer muß zusätzlich die periphere Int-Freigabe PEIE gesetzt sein (im Datenblatt nachlesen).
    In der ISR muß abgefragt werden, wer den Int ausgelöst hat.
    MfG Karl-Heinz
    HobbyElektronik hier klicken ....

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    23.05.2007
    Beiträge
    5
    Vielen Dank erstmal für die Antwort . Ich habe das Programm schon mal soweit aufgebaut, aber es scheint irgendwie nen Fehler zu haben, da es nicht aus der Schleife rausspringt . Vieleicht kannst du mir ja helfen den Fehler zu finden. MFG Nils (EGSLER)

    ;config
    list p=16f628
    #include <P16f628.INC>
    __CONFIG _PWRTE_ON & _WDT_OFF & _HS_OSC & _LVP_OFF
    ;************************************************* *******
    ; Variablennamen vergeben

    w_copy Equ 0x20 ; Backup für Akkuregister
    s_copy Equ 0x21 ; Backup für Statusregister

    ;************************************************* *************
    ; los gehts mit dem Programm

    org 0
    goto Init

    ;************************************************* *************
    ; die Interruptserviceroutine

    org 4
    intvec bcf INTCON, GIE ; disable Interrupt

    movwf w_copy ; w retten
    swapf STATUS, w ; STATUS retten
    movwf s_copy ;

    movlw D'131' ; 256-125=131 ((1MHz : 32 ): 125 = 250 Hz)
    movwf TMR2

    ; Intrrupt servic routine
    Int_serv

    incf PORTA, f


    ;hier folgt die eigentliche Interrupt-Routine,
    ;die 250 mal pro Sekunde aufgerufen wird


    Int_end swapf s_copy, w ; STATUS zurück
    movwf STATUS
    swapf w_copy, f ; w zurück mit flags
    swapf w_copy, w

    bcf INTCON, PEIE ; Interrupt-Flag löschen
    bsf INTCON, GIE ; enable Interrupt

    retfie

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

    ;Initialisierung am Anfang des Programms

    Init

    bsf STATUS, RP0 ; auf Bank 1 umschalten
    movlw B'11110000' ; PortA RA0 output
    movwf TRISA
    bcf STATUS, RP0 ; auf Bank 0 zurückschalten
    BSF CMCON, CM0 ;

    Comparatoreingang auf Digital umschalten
    BSF CMCON, CM1
    BSF CMCON, CM2

    ; Vorteiler 16:1 und Timer2 einschalten
    BSF T2CON,T2CKPS1 ; Vorteiler 16:1
    BSF T2CON,TMR2ON ; Timer2 ein

    ; Frequenz auf 10 kHz einstellen
    BSF STATUS,RP0 ; Bank1
    MOVLW D'124'
    MOVWF PR2 ; 2,5 kHz
    BCF STATUS,RP0 ; Bank1


    bsf INTCON, PEIE ;
    bsf INTCON, GIE ; Interrupt erlauben
    loop goto loop ; eine Endlosschleife

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


    end

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.12.2005
    Ort
    Euskirchen-Großbüllesheim
    Alter
    67
    Beiträge
    2.063
    Das GIE-Flag wird bei Auslösung eines Interrupts automatisch auf 0 und bei Verlassen durch RETI wieder auf 1 gesetzt; es sollte deshalb in der ISR nicht verändert werden.
    Die xxIE-Flags (IE=Int-Enable) sollten auch nicht verändert werden.
    bcf INTCON, PEIE ; Interrupt-Flag löschen
    schaltet die peripheren Int's (dazu gehört vermutlich auch der benutzte Timer) am Ende der ISR aus !!!
    Die xxIF-Flags (IF=Int-Flag) müssen in der ISR geprüft (wer hat ausgelöst) und vom Programm zurückgesetzt werden: bcf xxxxxxx, xxIF ; Interrupt-Flag löschen
    MfG Karl-Heinz
    HobbyElektronik hier klicken ....

  5. #5
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.969
    Hallo EGSLER!

    Dein Fehler ist im "Init" das mit endlose Schleife endet. Ein ASM Programm mit Interrupts, in dem ISR ein Hauptprogramm darstellt, sieht generell so aus:

    org 0x0000
    call Init
    goto Main
    org 0x0004
    ISR...
    retfie
    Main goto Main
    Init...
    return
    end

    Siehe dazu "Interrupts" im "PIC Assembler" in Wiki.

    MfG

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.12.2005
    Ort
    Euskirchen-Großbüllesheim
    Alter
    67
    Beiträge
    2.063
    @PICture
    Was ist bei einem "goto Init" und abschließender Endlosschleife falsch ?
    Nach der Interrupt-Freigabe wird alles in der InterruptServiceRoutine erledigt.
    Init muß nicht zwingend als SubRoutine ausgeführt werden.
    "Main" ist ein beliebiger LabelName, genau wie "loop".
    Ich finde daran nichts falsch.
    MfG Karl-Heinz
    HobbyElektronik hier klicken ....

  7. #7
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.969
    Hallo kalledom!

    Sorry, es ist nichts falsch, ich habe bloss einen Fehler gesucht und nicht gefunden. Du hast recht, dass es egal ist, wo das Programm auf Interrupt wartet. Man weiss ja nicht was die eigentliche ISR machen sollte, die wurde leider nicht gepostet. Vielleicht tritt ein Interrupt ein und unterbricht die endlose Schleife, aber das ist nicht einfach festzustellen, wenn man nicht weiss, was geschiehen sollte. Ich gebe auf.

    Schöne Grüsse!

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.12.2005
    Ort
    Euskirchen-Großbüllesheim
    Alter
    67
    Beiträge
    2.063
    Der Fehler wurde doch schon gefunden; EGSLER hat als vorletzten Befehl (vor reti) in der ISR:
    Code:
    bcf INTCON, PEIE ; Interrupt-Flag löschen
    Damit wird aber nicht das Interrupt-Flag, sondern der Interrupt-Enabe für periphere Int's abgeschaltet.
    Da der Timer 2 beim PIC16F877 zu den peripheren Int's gehört, beim PIC16F628 sicherlich ebenso, wird nur 1 mal ein Int ausgelöst, weil dabei PEIE disabled wird .... dann kehrt Ruhe ein.
    MfG Karl-Heinz
    HobbyElektronik hier klicken ....

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •