- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 8 von 8

Thema: Timer Interrupt wird nicht mehr ausgelöst

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.10.2013
    Beiträge
    6

    Timer Interrupt wird nicht mehr ausgelöst

    Anzeige

    Powerstation Test
    Hallo zusammen,

    habe ein Problem mit folgendem Quellcode:

    Code:
    #define F_CPU 1000000UL
    #include <avr/io.h>
    #include <avr/interrupt.h>			
    #include <util/delay.h>
    
    ISR(TIMER1_COMPA_vect)			//Interrupt service routine wenn Vergleichswert erreicht ist
    {	
    	static uint16_t vTeiler = 0;		//Deklarieren von vTeiler
    	swTeiler++;			//Zählschritt einstellen
    	if (vTeiler == 2)		              //Wert bis Interrupt ausgelöst wird
    	{
    		vTeiler = 0;		
    		PORTD |= (1<<PD6);	
    		_delay_ms(4000);	              //Schmierzeit
    		PORTD &= ~(1<<PD6);	
    	}
    }
    
    	int main (void)
    
    	{
    		
    		
    		DDRD |= (1<<PD6);		              
    		
    		
    		
    												                                                                                    //Timer konfigurieren
    		TCCR1B |= (1<<WGM12) | (1<<CS12);	//CTC-Mode und Vorteiler auswählen
    						              //Tabelle
    		
    		TIMSK |= (1<<OCIE1A);		              //Timer1 auswählen 
    							//Interrupt aufrufen, wenn Vergleichswert erreicht ist
    							//Tabelle
    		
    		OCR1A = 65499;				//Vergleichswert zur bestimmung einer Sekunde
    							//Interrupts aktivieren
    		
    		sei();
    		
    		
    		int i = 0;					//Schleifenvariable deklariert
    		while(i<2)				//Zwei mal wird die Schleife durchlaufen
    		{	
    			i++;
    			PORTD |= (1<<PD6);		
    			_delay_ms(3000);			//Schmierzeit
    			PORTD &= ~(1<<PD6);
    			_delay_ms(3000);
    			
    		}
                                return (0);
    
    		
    		
    	}
    Und zwar wird der Timer Interrupt nicht mehr ausgeführt, seitdem ich in die While-Schleife einen Code integriert habe.
    Es macht auf mich den Eindruck als würde, das komplette Programm stehen, nachdem die While-Bedingung nicht mehr erfüllt wird.
    Sorry für die Anfänger Frage, aber bin blutiger Anfänger, was das Programmieren betrifft.

    Gruß
    damnit

  2. #2
    shedepe
    Gast
    Ich vermute dass der Controller nach beenden der Schleife ins Nirvana springt und somit auch die Interrupts nicht mehr ausgeführt werden. Generell sollte man am Ende der Mainmethode bei einem Mikrocontroller eine endlos Schleife (while(true) einfügen.

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    21.06.2011
    Ort
    Dresden
    Beiträge
    219
    Hi,
    @shedepe: Die Schleife sollte ein guter Compiler selbst "einbauen".
    @damnit: Manche Compiler nehmen das "static" nicht sehr ernst, hast Du mal versucht,
    vTeiler global zu definieren ?
    mfg
    Achim

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Das Verlassen von main() ist eine ziemlich deutliche Willensbekundung des Programmierers, dass das Programm enden soll. Und daher macht der exit-Code der AVR-Libc auch genau das. Die Interrupts werden abgeschaltet, gefolgt von einer Endlosschleife, also quasi eine Deaktivierung des Controllers.

    - - - Aktualisiert - - -

    Zitat Zitat von seite5 Beitrag anzeigen
    @damnit: Manche Compiler nehmen das "static" nicht sehr ernst, hast Du mal versucht,
    vTeiler global zu definieren ?
    Sorry, aber was ist das denn für ein Quatsch?
    Ein C-Compiler, der das static für eine lokale Variable nicht korrekt implementiert, hätte den Namen "C-Compiler" schlicht nicht verdient. Kannst du auch nur ein konkretes Beispiel für dieses "manche Compiler" nennen?
    MfG
    Stefan

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    23.10.2013
    Beiträge
    6
    Hi @ all,

    erstmal danke für eure Unterstützung.
    @shedepe: thx, hab die while (1) - Schleife noch mit eingebaut und es funzt einwandfrei.

    mfg
    damnit

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.08.2008
    Ort
    DE
    Beiträge
    523
    Kleiner Hinweis. Ein delay_ms(4000); in einer ISR ist wirklich sehr sehr sehr sehr sehr sehr sehr sehr sehr schlecht und sollte um jeden Preis vermieden werden!!!! Du blockierst damit einfach alles.

    mfg

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    23.10.2013
    Beiträge
    6
    @Wsk8, bin mir dessen bewusst.
    Der Inhalt in der ISR dient aktuell nur zu Visualisierung (ob Magnetventil komplett durchschaltet).
    Kann leider nur Schritt für Schritt programmieren, da ich eben ein Neueinsteiger in diesem Themengebiet bin.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    23.10.2013
    Beiträge
    6
    Hallo,
    hab den Rat von Wsk8 beherzigt und habe in die Interrupt-Routine einen weiteren Timer eingebaut (ist das so üblich?).

    #define F_CPU 1000000UL
    #include <avr/io.h>
    #include <avr/interrupt.h> //Datei interrupt.h einbinden
    #include <util/delay.h>

    ISR(TIMER1_COMPA_vect) //Interrupt service routine wenn Vergleichswert erreicht ist
    {
    static uint16_t swTeiler = 0; //Deklarieren von swTeiler
    swTeiler++; //Zählschritt einstellen
    if (swTeiler == 30) //Wert bis Interrupt ausgelöst wird
    {
    swTeiler = 0; //Teiler wieder auf 0 setzen
    PORTD |= (1<<PD6); //PortD Strom an
    TCCR1B |= (1<<WGM12) | (1<<CS12);
    TIMSK |= (1<< OCIE1B);
    OCR1B = 3094;
    sei();


    }
    }
    ISR (TIMER1_COMPB_vect)
    {
    static uint8_t vTeiler = 0;
    vTeiler++;
    if (vTeiler == 4)
    {
    vTeiler = 0;
    PORTD &= ~(1<<PD6);

    }
    }

    int main (void)

    {


    DDRD |= (1<<PD6); //PD6 als Ausgang deklarieren




    //Timer konfigurieren
    TCCR1B |= (1<<WGM12) | (1<<CS12); //CTC-Mode und Vorteiler auswählen
    //Tabelle

    TIMSK |= (1<<OCIE1A); //Timer1 auswählen (Output Compare A Match Interrupt Enable
    //Interrupt aufrufen, wenn der Vergleichswert erreicht ist
    //Tabelle

    OCR1A = 3906; //Vergleichswert zur bestimmung einer Sekunde
    //Interrupts aktivieren

    sei();


    int i = 0; //Schleifenvariable deklariert
    while(i<2) //Zwei mal wird die Schleife durchlaufen
    {
    //Zu beginn des Programmstarts, sollen 2 Schmierungen druchgeführt werden
    i++;
    PORTD |= (1<<PD6);
    _delay_ms(3000); //Schmierzeit
    PORTD &= ~(1<<PD6);
    _delay_ms(3000); //Untebrechung der Schmierung

    }


    while(1)
    {

    }
    }
    Prinzipiell läuft das Programm, jedoch findet bei jedem zweiten Aufruf der ISR, schon nach ca. einer Sekunde ein Interrupt statt, wodurch PD6 wieder auf Low gesetzt wird.
    Sprich bei jedem ungeraden Interrupt findet der Overflow nach 4 Zählschritten statt und bei jedem geraden schon nach einem.
    Kann es mir nicht wirklich erklären?

    mfg
    Damnit

Ähnliche Themen

  1. Interrupt wird nicht ausgelöst.
    Von DarkSoldier im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 28.04.2013, 15:42
  2. Interrupt wird nicht ausgelöst
    Von Michael_am32 im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 02.08.2010, 01:37
  3. Es wird kein Interrupt ausgelöst
    Von MrTaco im Forum C - Programmierung (GCC u.a.)
    Antworten: 9
    Letzter Beitrag: 19.07.2010, 17:48
  4. Interrupt wird nicht ausgelöst
    Von einballimwas im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 01.09.2009, 15:29
  5. Interrupt wird nicht ausgelöst
    Von PcVirus im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 10.04.2008, 16:14

Berechtigungen

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

LiFePO4 Speicher Test