- LiTime Speicher und Akkus         
Ergebnis 1 bis 9 von 9

Thema: Interrupt Routine

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    05.05.2013
    Beiträge
    22

    Interrupt Routine

    Anzeige

    Praxistest und DIY Projekte
    Hallo Guten Nabend,

    Ich steige von C auf Assembler um und verstehe hier was nicht.

    Viele Tutorials gibt es zu Assembler AVR nicht, die nicht kopiert worden sind.
    Ich habe alles ausprobiert was ich in irgendwelchen Anleitungen und Tutorials fand.
    Die Interrupt Vectoren per .org, weglassen, mit reti, etwas gemischt....
    Das Handbuch über den Atmega 8 sagt:
    When the SREG I-bit, TOIE0 (Timer/Counter0 Overflow
    Interrupt Enable), and TOV0 are set (one), the Timer/Counter0 Overflow interrupt is executed.
    Genau dieser Zustand tritt auch in der Simulation von Atmel Studio 6.2 ein.
    Allerdings wird dann nicht die Routine ausgeführt, es wird nichts zurück gesetzt...
    Ich komme mit den Tutorials und meinem eigenen Latein nicht mehr weiter und hoffe ihr könnt mich auf den rechten Pfad zurück bringen.
    Mein Übungscode sieht wie folgt aus:

    Code:
    .include "m8def.inc"
    
    rjmp main ; Reset Handler
    reti ; IRQ0 Handler
    reti ; IRQ1 Handler
    reti ; Timer2 Compare Handler
    reti ; Timer2 Overflow Handler
    reti ; Timer1 Capture Handler
    reti ; Timer1 CompareA Handler
    reti ; Timer1 CompareB Handler
    reti ; Timer1 Overflow Handler
    rjmp interrupt ; Timer0 Overflow Handler
    reti ; SPI Transfer Complete Handler
    reti ; USART RX Complete Handler
    reti ; UDR Empty Handler
    reti ; USART TX Complete Handler
    reti ; ADC Conversion Complete Handler
    reti ; EEPROM Ready Handler
    reti ; Analog Comparator Handler
    reti ; Two-wire Serial Interface Handler
    reti ; Store Program Memory Ready Handler
    
    
    main:
    		;Initializiere Stackpointer
    
    		ldi r17, HIGH(RAMEND)
    		out SPH, r17
    		ldi r17, LOW(RAMEND)
    		out SPL, r17
    		sei
    
    		ldi r17, 0xFF	;setze B als Ausgang
    		out DDRB, r16
    
    		ldi r16, 0x01	; setze Pin 1 als High.
    
    		ldi r17, (1<<CS00) ; Setze Vorteiler
    		out TCCR0, r16
    		ldi r17, (1<<TOIE0) ; Setze Overflow Interrupt
    		out TIMSK, r16
    
    loop:
    		rjmp loop ; Ewiger Loop
    
    interrupt:
    		out PORTB, r16
    		com r16
    		reti
    Geändert von Saturas077 (23.04.2014 um 13:46 Uhr) Grund: Erledigt, hoffentlich

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.702
    Blog-Einträge
    133
    Zitat Zitat von Saturas077 Beitrag anzeigen
    When the SREG I-bit, TOIE0 (Timer/Counter0 Overflow
    Interrupt Enable), and TOV0 are set (one), the Timer/Counter0 Overflow interrupt is executed.
    Genau dieser Zustand tritt auch in der Simulation von Atmega 6.2 ein.
    Allerdings wird dann nicht die Routine ausgeführt,es wird nichts zurück gesetzt...
    Was soll Atmega 6.2 sein? Was soll den das Programm machen und was meinst Du mit "es wird nichts zurück gesetzt..."?

    Ich habe keinen Simulator für Dein Programm installiert und bin nur gedanklich durchgegangen:
    Meiner Meinung nach sollte die ISR schon ausgeführt werden allerdings wird PORTB nicht auf Ausgang geschaltet und die Konfiguration von Interrupt und Vorteiler scheint mir eher zufällig zu klappen.
    Hab Deinen Code kopiert und mit weiteren Kommentaren versehen:
    Code:
            .include "m8def.inc"
    
            rjmp main ; Reset Handler
            reti ; IRQ0 Handler
            reti ; IRQ1 Handler
            reti ; Timer2 Compare Handler
            reti ; Timer2 Overflow Handler
            reti ; Timer1 Capture Handler
            reti ; Timer1 CompareA Handler
            reti ; Timer1 CompareB Handler
            reti ; Timer1 Overflow Handler
            rjmp interrupt ; Timer0 Overflow Handler
            reti ; SPI Transfer Complete Handler
            reti ; USART RX Complete Handler
            reti ; UDR Empty Handler
            reti ; USART TX Complete Handler
            reti ; ADC Conversion Complete Handler
            reti ; EEPROM Ready Handler
            reti ; Analog Comparator Handler
            reti ; Two-wire Serial Interface Handler
            reti ; Store Program Memory Ready Handler
    
            main:
                    ;Initializiere Stackpointer
    
                    ldi r17, HIGH(RAMEND)
                    out SPH, r17
                    ldi r17, LOW(RAMEND)
                    out SPL, r17
                    sei
    
                    ldi r17, 0xFF    ;setze B als Ausgang             (alle Bits in r17 werden gesetzt)
                    out DDRB, r16                                    (r16 ist nicht initialisiert und wird defaultmäßig 0x00 enthalten
                                                                              Ausgabe nach DDRB wird keinen einen Effekt haben, PORTB bleibt auf Eingang)
    
                    ldi r16, 0x01    ; setze Pin 1 als High.          (Bit 0 in R16 wird gesetzt)
    
                    ldi r17, (1<<CS00) ; Setze Vorteiler             (Bit 0 in r17 wird gesetzt, alle anderen gelöscht)
                    out TCCR0, r16                                   (r16 soll den Vorteiler setzen? Soll nicht r17 nach TCCR0 ausgegeben werden?)
                    ldi r17, (1<<TOIE0) ; Setze Overflow Interrupt   (Bitnummer von TOIE0 wird in r17 gesetzt - Maske für TIMSK?) 
                    out TIMSK, r16                                   (r16 wird nach TIMSK geschrieben. Sollte das nicht r17 sein?)
    
            loop:
                    rjmp loop ; Ewiger Loop
    
            interrupt:
                    out PORTB, r16                                   (r16 hat beim ersten interrupt noch Bit 0 gesetzt
                                                                              und schaltet hier nur den Pullup für PB0 ein, da PORTB noch auf
                                                                              defaultmaessigem Eingang ist, siehe oben)
                                                                             (beim zweiten Interrupt wird Pullup für PB0 wieder ausgeschaltet und
                                                                              und für alle anderen Pins auf PORTB eingeschaltet)
                                                                             (Nur die Pullups werden getoggelt wg. nachfolgendem COM r16) 
                    com r16                                          (alle Bits in R16 werden invertiert und SREG verändert)
                    reti
    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    05.05.2013
    Beiträge
    22
    Ich danke dir für deine schnelle Ausführung Searcher.

    Ich meinte selbstverständlich Atmel Studio 6.2, das Programm soll rein dazu dienen mir im Simulator anzuschauen wie die Interruptroutine angesprungen wird.
    Das die falschen Register im out stehen, liegt daran das ich gestern die einmal anders angeordnet hatte, hatte zuvor nur das Register 16 benutzt. Leider habe ich den Wald vor...

    Der Simulator macht eigentlich genau das was ich mir auch im Kopf vorgestellt habe.
    Hier nochmal der Code:
    Code:
    .include "m8def.inc"
    
    rjmp main ; Reset Handler (Hier sollte das Programm direkt zum main target springen! TUT er auch.)
    reti ; IRQ0 Handler (Schaut sich das Programm nicht mehr an)
    reti ; IRQ1 Handler
    reti ; Timer2 Compare Handler
    reti ; Timer2 Overflow Handler
    reti ; Timer1 Capture Handler
    reti ; Timer1 CompareA Handler
    reti ; Timer1 CompareB Handler
    reti ; Timer1 Overflow Handler
    rjmp interrupt ; Timer0 Overflow Handler
    reti ; SPI Transfer Complete Handler
    reti ; USART RX Complete Handler
    reti ; UDR Empty Handler
    reti ; USART TX Complete Handler
    reti ; ADC Conversion Complete Handler
    reti ; EEPROM Ready Handler
    reti ; Analog Comparator Handler
    reti ; Two-wire Serial Interface Handler
    reti ; Store Program Memory Ready Handler
    
    
    main:
    		;Initializiere Stackpointer
    
    		ldi r17, HIGH(RAMEND)
    		out SPH, r17
    		ldi r17, LOW(RAMEND)
    		out SPL, r17
    		sei
    
    		ldi r16, 0xFF	;setze B als Ausgang
    		out DDRB, r16
    
    		ldi r16, 0x01	; setze Pin 1 als High.
    
    		ldi r17, (1<<CS00)
    		out TCCR0, r17
    		ldi r17, (1<<TOIE0)
    		out TIMSK, r17
    
    loop:
    		rjmp loop (Hängt dann hier fest obwohl TOV0 und TOIE0 ausgelöst wurden. I Bit ist gesetzt durch sei)
    
    interrupt:
    		out PORTB, r16
    		com r16
    		ret
    Die zwei () Kommentare sind meine Meinungen, was das Programm tut und was es wirklich macht.

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.702
    Blog-Einträge
    133
    Zitat Zitat von Saturas077 Beitrag anzeigen
    Code:
    interrupt:
            out PORTB, r16
            com r16
            ret
    Hi, böse Falle oder nur Tippfehler?
    Es muß RETI und nicht nur RET sein.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    05.05.2013
    Beiträge
    22
    Hallo,
    habe beides Ausprobiert, aber dachte mir das reti richtiger sei.

    Trotz deiner Anmerkungen keine Funktion. :/
    Gruß

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.702
    Blog-Einträge
    133
    Es muß RETI sein. Sonst wird das Global Interrupt Enable Bit in SREG nicht mehr gesetzt, daß ja zur Ausführung der ISR vom µC gelöscht wurde. Effekt: Interrupt tritt nur einmal auf und dann nicht mehr.

    Zitat Zitat von Saturas077 Beitrag anzeigen
    Trotz deiner Anmerkungen keine Funktion. :/
    Keine Funktion (Invertieren der Bits im PORTB?) im Simulator? Woran erkennst Du das? Keine Funktion im Atmega (LEDs, Oszilloskop). Liegts am Simulator (kann ich selbst nicht testen)?

    Mit welchem Takt läuft der Atmega? Bei Vorteiler 1 würde eine LED schon irre schnell blinken, so daß man das nicht sehen kann.

    Diese Zeile hier "ldi r16, 0x01 ; setze Pin 1 als High." ist irreführend kommentiert. Damit wird Bit 0 in r16 gesetzt. Später in der ISR wird damit PB0 getoggelt (mal abgesehen davon, daß auch alle anderen PBs in der ISR getoggelt werden.)

    Beschreib genau was Du wie erwartest und wo (Simulator, in der Schaltung, ...) und was da nicht geht.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    05.05.2013
    Beiträge
    22
    Ich habe gehofft, dass wenn der Interrupt auslöst die Pins an Port B alle einen High-Pegel bekommen bis auf der Pin0. Sobald dann die Hauptschleife anläuft soll wieder nur Pin 0 leuchten.

    Das Bild zeigt wie es im Simulator aussieht:
    Klicke auf die Grafik für eine größere Ansicht

Name:	Simulator.jpg
Hits:	5
Größe:	23,9 KB
ID:	28050
    Auf dem Bild siehst du auch die Taktrate von 8Mhz, statt 1 Mhz

    Es wird durch das Programm alles gesetzt wie im Zitat am Anfang des Threades beschrieben.
    Er springt aber einfach nicht in die Interrupt Routine, deshalb wird auch der Code nicht ausgelöst

    E: Was mir noch auffällt, das der Programm Counter bei der Adresse 13 bei main ankommt.
    Im Speicher steht : 0x0000 dann kommt direkt 0x0013.

    Kurz Offtopic, wieso stehen die Zahlen in 0x0013? Wäre das nicht 0x0D?
    Geändert von Saturas077 (23.04.2014 um 10:50 Uhr)

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.702
    Blog-Einträge
    133
    Zitat Zitat von Saturas077 Beitrag anzeigen
    Ich habe gehofft, dass wenn der Interrupt auslöst die Pins an Port B alle einen High-Pegel bekommen bis auf der Pin0. Sobald dann die Hauptschleife anläuft soll wieder nur Pin 0 leuchten.
    Ich denke, daß das Programm zuerst die Hauptschleife erreicht, bevor der erste Interrupt auftritt - der Timer0 muß ja erstmal bis 255 hochlaufen nachdem er mit dem CS00 Bit gestartet wurde. (Könnte in einer Simulation schon einiges dauern)

    Tritt dann der erste Interrupt auf, wird PB0 auf high (1) gelegt und r16 invertiert. Beim zweiten Interrupt wird dann PB0 auf low (0) gesetzt. usw.

    Im Programmablauf sehe ich keinen Grund, warum der PB0 nicht toggeln sollte (wenn RETI am Ende der ISR steht) und das rjmp Interrupt auch auf dem OVF0 Interruptvektor steht - also die syntax auch vom übrigen Code paßt.

    E: Was mir noch auffällt, das der Programm Counter bei der Adresse 13 bei main ankommt.
    Im Speicher steht : 0x0000 dann kommt direkt 0x0013.

    Kurz Offtopic, wieso stehen die Zahlen in 0x0013? Wäre das nicht 0x0D?
    Der Programmcounter umfasst 2 Byte! - Könnte es das sein? Wie gesagt kann ich das leider nicht nachtesten.

    Ich vermute eventuell einen Simulator Bug oder Einstellung wie zB:
    http://www.mikrocontroller.net/topic/292982

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    05.05.2013
    Beiträge
    22
    Danke für deine Bestätigung, das der Code eigentlich funktionieren sollte.
    Genau das beschriebene Phänomen aus deinem Link habe ich "manchmal" auch.
    Ich habe mein MK II geschrottet, kann mir als Student diesen Monat keinen neuen Leisten, werde es also erst im Mai an einem AVR ausprobieren können.
    Danke für deine Hilfe.

Ähnliche Themen

  1. Tastaturabfrage innerhalb der Interrupt Service Routine
    Von Sven2013 im Forum Arduino -Plattform
    Antworten: 2
    Letzter Beitrag: 16.03.2013, 20:51
  2. Programm verlässt Interrupt-Routine nicht
    Von Björn im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 15.11.2008, 12:06
  3. Interrupt Routine
    Von luvat im Forum Schaltungen und Boards der Projektseite Mikrocontroller-Elektronik.de
    Antworten: 4
    Letzter Beitrag: 16.03.2008, 21:54
  4. Interrupt in ISR-Routine freigeben
    Von dj5am im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 10.08.2007, 09:44
  5. uart interrupt routine
    Von Computerkora im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 25.11.2006, 14:45

Berechtigungen

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

LiTime Speicher und Akkus