-
        

Ergebnis 1 bis 6 von 6

Thema: Interrupt Timer1

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    29.01.2006
    Beiträge
    21

    Interrupt Timer1

    Anzeige

    Guten Tag!
    Ich hab bei einem Projekt mit einem Atiny 2313 folgendes Problem:

    Das Programm sollte eine Zeit von (ca.) 6 Minuten runter zählen. Dafür wollte ich den Timer1 verwenden der bis 7812 zählen sollte und dann einen Interrupt auslösen soll um dann eine Sekunde abzuziehen.

    Der Timer1 zählt auch wie geplant hoch, bei 7812 beginnt er von vorne und setzt das OCF1A Bit auf 1 aber dadruch wird kein Interrupt ausgelöst.

    Der Timer wurde wie folgt konfiguriert:
    Code:
     
        ;Timer einstellen-------------------------------
        ;--Vergleichswert
        ldi tmp1, 0b00011110
        out ocr1ah, tmp1
        ldi tmp1, 0b10000100
        out ocr1al, tmp1
    
        ;--TCCR1a & TCCR1c werden nicht gebraucht
        clr tmp1
        out tccr1a, tmp1
        out tccr1c, tmp1
    
        ;--CTC aktivieren und den Teiler auf 1024 stellen
        ldi tmp1, 0b00001101
        out tccr1b, tmp1
    
        ;--Timer1 Output Compare A Match interrupt enabled
        ldi tmp1, 0b01000000
        out timsk, tmp1
    
        ;Interrupt einschalten
        sei
        ;-----------------------------
    Kann mir vielleicht jemand sagen was falsch gelaufen ist? Ich hab das Datenblatt jetzt x-mal durchgelesen und ich konnte aber keinen Fehler entdecken.

    Danke.
    mfg
    Stefan

  2. #2
    Unregistriert
    Gast
    Sieht alles richtig aus. Zeige den kompletten Code. Interessant ist es, wie du überprüfst, ob ein Interrupt aufgetreten ist. Wie überprüfst du das?

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    29.01.2006
    Beiträge
    21
    Code:
    .include "tn2313def.inc" 
    
    ;--KONSTANTENDEKLARATION--------------------------------------------- 
       ; status register bits 
    .equ CarryFlag      = 0 
    .equ ZeroFlag       = 1 
    .equ NegativeFlag   = 2 
    .equ TwosFlag       = 3 
    .equ SignFlag       = 4 
    .equ HalfCarryFlag   = 5 
    .equ TransferFlag   = 6 
    .equ GlobalFlag     = 7 
    .equ Frequenz       = 8000000
    .equ Teiler         = 4000
    
    ;--VARIABLENDEKLARATION---------------------------------------- 
    
    .CSEG            
    .org 0x0000        
    
    rjmp MAIN                 ;Reset
    rjmp taster            ;Ext. Int0
    rjmp UnusedInt_ISR;takt        ;Ext. Int1 
    rjmp UnusedInt_ISR         ;Timer1 Capture Event
    rjmp takt              ;Timer1 Compare Match A
    rjmp UnusedInt_ISR         ;Timer1 Overflow
    rjmp UnusedInt_ISR         ;Timer0 Overflow 
    rjmp UnusedInt_ISR        ;USART Rx Complete    
    rjmp UnusedInt_ISR         ;USART Data Reg. Empty
    rjmp UnusedInt_ISR         ;USART Tx Complete
    rjmp UnusedInt_ISR         ;Analog Comperator
    rjmp UnusedInt_ISR         ;Pin Change Int
    rjmp UnusedInt_ISR        ;Timer1 Compare MatchB
    rjmp UnusedInt_ISR        ;Timer0 Compare MatchA
    rjmp UnusedInt_ISR        ;Timer0 Compare MatchB
    rjmp UnusedInt_ISR        ;USI Start Cond
    rjmp UnusedInt_ISR        ;USI Overflow
    rjmp speichern            ;EEPRom Ready
    rjmp UnusedInt_ISR         ;Watchdog Timer Overflow
    UnusedInt_ISR:   reti 
    
    
    ;Variabelen
    .def sreg_save =  R16
    .def set_zeit = R17
    .def set_klasse = R18
    .def minu = R19
    .def sek = R20
    .def tmp1 = R21
    .def tmp2 = R22
    .def tmp3 = R23
    .def pos_klasse = R24
    
    ;--Hauptprogramm------------------------------------------------
    MAIN: 
       ;Stackpointer initialisieren 
       ldi   tmp1,low (RAMEND)         ; RAMEND ist eine im include file vorgegebene Konstante, 
       out   SPL,tmp1 
    rjmp init
    
    main_loop:
        clr tmp1
        cpse minu, tmp1
    rjmp main_loop
        ldi tmp1, 0b00011110 ;30Sek vor Ende
        cpse sek, tmp1
        rjmp main_loop
            summer_ein:
                ldi tmp1, 0b010
                out porta, tmp1
                ldi tmp1, 0b00011001 ;25Sek vor Ende
                cpse sek, tmp1
            rjmp summer_ein
                summer_aus:
                    ldi tmp1, 0b000
                    out porta, tmp1
                    clr tmp1
                    cpse sek, tmp1
                rjmp summer_aus
            rcall umschalten
    rjmp main_loop
    
    
    init:
        ;Setup Beschreibung
        ;Anzahl der Klassen:
            ;Dip 1-2
            ;00 = 2
            ;01 = 3
            ;10 = 4
            ;11 = 5
        ;Zeit
            ;Dip 3-5
            ;000 = 6 Min
            ;001 = 9 Min
            ;010 = 12 Min
            ;011 = 15 Min
            ;...
        ;-----------------------------------------------
        clr sek
        clr minu
        ;Eingänge setzen--------------------------------
        clr tmp1
        out ddrb, tmp1
        ;Ausgänge setzen--------------------------------
        ldi tmp1, 0b11110011
        out ddrd, tmp1 ; Lampen
        ser tmp1
        out ddra, tmp1 ; Summer
        ;Reset------------------------------------------
        ;--FF--Speicher resten
    
        ;Interrupt einstellen--------------------------
        ldi tmp1, 0b00001010 ;Bit2&3 Int1 @ Fallende Flanke
        out mcucr, tmp1
        ldi tmp1, 0b11000000 ;Bit7 Int1 ein;
        out gimsk, tmp1
        ;Timer einstellen-------------------------------
        ;--Vergleichswert
        ldi tmp1, 0b00011110
        out ocr1ah, tmp1
        ldi tmp1, 0b10000100
         out ocr1al, tmp1
        ;--TCCR1a & TCCR1c werden nicht gebraucht
        clr tmp1
        out tccr1a, tmp1
        out tccr1c, tmp1
        ;--CTC aktivieren und den Teiler auf 1024 stellen
        ldi tmp1, 0b00001101
        out tccr1b, tmp1
        ;--Timer1 Output Compare A Match interrupt enabled
        ldi tmp1, 0b01000000
        out timsk, tmp1
        ;Interrupt einschalten
        sei
        ;-----------------------------
    
        ;-----------------------------
        ;Einstellungen einlesen
        ;Anzahl Klassen
        in set_klasse, pinb
        andi set_klasse, 0b00000011
        inc set_klasse
        inc set_klasse
        ;Zeitintervall
        in set_zeit, pinb
        andi set_zeit, 0b00011100
        lsr set_zeit
        lsr set_zeit
        clr tmp1
        cp set_zeit, tmp1
            breq zeitintervall_ende
                clr tmp1
                add tmp1, set_zeit
                clr set_zeit
                rep_zeit:
                    dec tmp1
                    inc set_zeit
                    inc set_zeit
                    inc set_zeit
                    clr tmp2
                    cpse tmp1, tmp2
                rjmp rep_zeit
            zeitintervall_ende:
        ldi tmp1, 0b00000110
        add set_zeit, tmp1
        ;Klassenposition------------------------
            ;--FF--Pos_Speicher lesen und pos_klasse zuteilen
        cp set_klasse, pos_klasse
        brlo error1
        clr tmp1
        cp tmp1, pos_klasse
        breq error1
        ;Zeit starten---------------------------
        rcall umschalten
    rjmp main_loop
        error1:
            clr pos_klasse
            add pos_klasse, set_klasse
            ;--FF--speichern pos_klasse
        rjmp main
    ;Init Ende---------------------------------------------------
    takt:
        in sreg_save, sreg
        ;Sekunden
        clr tmp1
        cpse sek, tmp1
        ldi sek, 0b00110010
        dec sek
        ;Minuten
        ldi tmp1, 0b00110001
        cpse sek, tmp1
        dec minu
        out sreg, sreg_save
    reti
    
    taster:
        in sreg_save, sreg
            clr minu
            ldi sek, 0b00000011
            ;--FF-- Entprellen und direkt umschalten
        out sreg, sreg_save
    reti
    
    speichern:
        in sreg_save, sreg
        out sreg, sreg_save
    reti
    
    umschalten:
        clr minu
        clr sek
        add minu, set_zeit
        cp set_klasse, pos_klasse
        breq umschalt1
        inc pos_klasse
        ldi tmp1, 0b00000010
        cp tmp1, pos_klasse
            breq umschalt2
        ldi tmp1, 0b00000011
        cp tmp1, pos_klasse
            breq umschalt3
        ldi tmp1, 0b00000100
        cp tmp1, pos_klasse
            breq umschalt4
        ldi tmp1, 0b00000101
        cp tmp1, pos_klasse
            breq umschalt5
        umschalt1:
            ldi pos_klasse, 0b00000001
            ldi tmp1, 0b00000001
            out portd, tmp1
            rjmp umschalt_ende
        umschalt2:
            ldi tmp1, 0b00000010
            out portd, tmp1
            rjmp umschalt_ende
        umschalt3:
            ldi tmp1, 0b00010000
            out portd, tmp1
            rjmp umschalt_ende
        umschalt4:
            ldi tmp1, 0b00100000
            out portd, tmp1
            rjmp umschalt_ende
        umschalt5:
            ldi tmp1, 0b01000000
            out portd, tmp1
        umschalt_ende:
        ;--FF--Position speichern
    reti
    Naja. Habs nur so im AVR Studio getestet. Hab auf den Timer gewartet und die Register beobachtet (mit F11 durchgedrückt). Der Interrupt wurde nicht ausgeführt.
    Der Code ist noch eine Baustelle. Daher wurde er nicht am Controller getestet.

    mfg
    Stefan
    Geändert von Stefan_84 (05.12.2015 um 23:00 Uhr)

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.897
    Irgendwie fehlt mir da die generelle Interruptfreigabe mit "SEI".
    Habs aber vieleicht auch übersehen.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    29.01.2006
    Beiträge
    21
    Kurzes Update:
    Hab das Programm auf den Controller geladen und steure jetzt mit dem Interrupt ein Relais an (einmal ein, beim nächsten aus...), zum Testen ob es funktioniert. Erst klappte es nicht.
    Hab die Software nochmals überflogen und einen Fehler gefunden. Jetzt klappts. Auch wenn es noch keine Sekunde ist. Da hab ich mich wohl verrechnet.
    Aber danke erstmal.

    mfg
    Stefan

    - - - Aktualisiert - - -

    Der SEI Befehl kommt direkt nach dem einstellen der Timer.

    mfg

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    29.01.2006
    Beiträge
    21
    Noch kurz als Ergänzung.

    Bin jetzt drauf gekommen warum die Interrupts im AVR Studio nicht ausgeführt werden. "Mask interrupt while stepping" muss in den Optionen auf "False" gesetzt werden. Dann klappt es auch beim simulieren.

    mfg
    Stefan

Ähnliche Themen

  1. Interrupt Timer1/2 (0) problem, Anfängerfrage
    Von wiebel im Forum Assembler-Programmierung
    Antworten: 0
    Letzter Beitrag: 23.06.2007, 15:32
  2. Timer1 Uhr
    Von orph im Forum PIC Controller
    Antworten: 9
    Letzter Beitrag: 16.09.2006, 16:44
  3. Problem mit Capture-Interrupt beim TIMER1 (IR-Empfaenger)
    Von Ulfens im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 20.03.2006, 12:46
  4. atmega32 - Timer1 - Capture Interrupt
    Von Jeluca im Forum AVR Hardwarethemen
    Antworten: 4
    Letzter Beitrag: 27.02.2006, 20:00
  5. Probleme Mega16 Timer1 Interrupt
    Von skyrider im Forum AVR Hardwarethemen
    Antworten: 0
    Letzter Beitrag: 16.04.2005, 15:49

Berechtigungen

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