- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 30

Thema: [erledigt] globale Variable in ISR ändern + im Hauptprogramm

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Benutzer Stammmitglied
    Registriert seit
    20.07.2007
    Beiträge
    38

    [erledigt] globale Variable in ISR ändern + im Hauptprogramm

    Hai,

    ich hab ein Problem mit einer Interrupt-Routine. Ich habe folgenden Code (Ausschnit).

    Code:
    #include <../include/avr/io.h>
    #include <../include/avr/interrupt.h>
    #include <../include/stdlib.h>
    #include <../include/util/delay.h>
    
    volatile uint16_t Zeittick = 0 ;
    
    SIGNAL (TIM1_OVF_vect)
    {
       // ISR-Code
    	 //PORTB ^= (1<<PB2);
    	 PORTB |= (1 << PB2);    /* setzt Bit 3 an PortB auf 1 */
    	 //PORTB &= ~(1 << PB2);   /* loescht Bit 3 an PortB */
    	 Zeittick++;
    
    }
    
    int main (void) {
    //Zeittick = 0;
    	 if (Zeittick >= 20)
    	 {
          //PORTB ^= (1<<PB3);
    			//Zeittick = 0;
    			PORTB |= (1 << PB3);    // setzt Bit 3 an PortB auf 1
    	 }
    Die ISR "TIM1_OVF_vect" wird angesprungen, der Timer läuft, alles prima. Aber die If-Abfrage im Hauptprogramm wird einfach nich ausgeführt. Stecke ich diese Abfrage in die ISR gehts. Wo hab ich da einen Fehler drin ? Wie kann ich eine Variable in einer ISR sonst manipulieren und im Hauptprogramm abfragen ?
    Ist die If-Agbfrage in der ISR taucht das Problem auf, dass die Variable Zeittick bei einem Softreset nicht zuverlässig auf Null gesetzt wird. ICh versteh aber nicht warum....

    Internette Grüße
    Stefan

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    31.08.2005
    Ort
    bei Graz
    Alter
    34
    Beiträge
    225
    Hallo,
    ist das wirklich dein ganzer Source Code? Denke nicht, so würde das ja nicht mal kompilieren. . .

    Das if ist denke ich in ner Endlosschleife drin, oder?

    und warum hast du sachen die zeittick=0 auskommentiert?

    lg MoFe

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    20.07.2007
    Beiträge
    38
    Hallo Moritz,

    natürlich ist das nicht mein ganzer Code. Es ist nur der interessante Ausschnitt. Vom Rest weiß ich, dass es läuft. Du hast recht hinter der If-Abfrage kommt noch eine Endlosschleife. Mir geht es auch nur darum erst mal zu sehen, dass die entsprechende LED (PB3) überhaupt reagiert wenn die if-Abfrage im Hauptprogramm ist. Die auskommentierten Stellen sollen ein wenig zeigen, was ich schon versucht hab. Das Programm macht so, wie es da steht keinen Sinn, da geb ich dir Recht. Das Problem mit der globalen Variable kann man aber denke ich nachvollziehen. Bei Interesse poste ich auch den gesamten Code, der ist aber denke ich erstmal unwichtig.

    Internette Grüße
    Stefan

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Mit 16bit / 2 byte Variablen ist das so eine Sache zwischen ISR und Main.
    Ich persönlich mache meist solche "if"s in der ISR und setze nur einen Flag für die Mainroutine

    Eigentlich aber seh ich keinen Fehler. Versuch wirklich einfach mal ein uint8_t , also nur ein Byte
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Du hast recht hinter der If-Abfrage kommt noch eine Endlosschleife.
    Wenn die Endlosschleife nach der if-Schleife beginnt, kann sie ja nicht angesprungen werden.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    20.07.2007
    Beiträge
    38
    Hallo an alle,

    danke für eure prompten Antworten. Leider bin ich immer noch nicht weiter. Die If-Abfrage muss natürlich in die Endlosschleife. Ich hatte vorher da stehen Zeittick = 0 und in der if-Abfrage if Zeittick == 1
    Habe die Abfrage jetzt wieder in die Endlosschleife genommen, aber ohen Erfolg. Auch die Verwendung einer unit8_t Variable brachte keinen Unterschied
    Ich poste mal den gesamten Code, vielleicht hab ich ja doch anderer Stelle einen Denkfehler.....

    Code:
    #include <../include/avr/io.h>
    #include <../include/avr/interrupt.h>
    #include <../include/stdlib.h>
    #include <../include/util/delay.h>
    
    #define UPPPER_BOUND   10
    
    volatile uint8_t Zeittick ;
    
    
    
    
    int myRand( int UpperBound )
    {
      int x;
    
      while( (x = rand()) >= RAND_MAX - (RAND_MAX % UPPPER_BOUND) )
        ;
      return x % UPPPER_BOUND;
    }
    
    // Eine nichtunterbrechbare Interrupt-Service-Routine
    SIGNAL (TIM1_COMPA_vect)
    {
       // ISR-Code
       //PORTB ^= (1<<PB2);
    	 //PORTB |= (1 << PB2);    // setzt Bit 3 an PortB auf 1
    	 PORTB &= ~(1 << PB2);   // loescht Bit 3 an PortB
    Zeittick = Zeittick + 1;
    
    }
    
    SIGNAL (TIM1_OVF_vect)
    {
       // ISR-Code
    	 //PORTB ^= (1<<PB2);
    	 PORTB |= (1 << PB2);    /* setzt Bit 3 an PortB auf 1 */
    	 //PORTB &= ~(1 << PB2);   /* loescht Bit 3 an PortB */
    	 Zeittick = Zeittick + 1;
    
    }
    void long_delay(uint16_t ms) {
    		for(uint16_t temp=0; temp<=ms; temp++){ _delay_ms(1);}
    }
    int main (void) {
    //Zeittick = 0;
    
    
    
    // allgemein
    		GTCCR 	= 0b11100001; 	// Timer anhalten
    		SREG 	 |= (1 << 7);
    		GIMSK   = 0b00100000;
    		PCMSK   = 0b00000100;
    // Timer 0
    		TCCR0A 	= 0b11100001;   // Timer0 A und B auf Phasecorrect PWM-Mode
    		                        // und löschen bei erreichen des Werte in OC0A bzw.
    		                        // OC0B
    		TCCR0B	= 0b00000010;   // WGM02-Bit löschen für PWM-POhase-Correct-Mode
    														// OC0A-Ausgang wird beim hchzählen gesetzt und
    														// beim runterzählen gelöscht
    		                        // und Prescaler auf clk/1024 einstellen
    
    		OCR0A   = 0b01100011;   // Output-Compare-Register einstellen
     		OCR0B   = 0b00101111;   // Output-Compare-Register einstellen
    
    // Timer 1
    		TCCR1   = 0b01000101;
    		OCR1A 	= 0b11000000;
    		OCR1B 	= 0b00011111;
    		OCR1C 	= 0b11111111;
    
    
    		TIMSK   = 0b01000100;
    //		sei();
    
    //		OCR1A   = 0b01111111;
    //		OCR1B   = 0b00111111;
    
    		DDRB    = 0b11111111;   // PortB auf Ausgabe stellen
    		GTCCR 	= GTCCR & 0b11111110 ;//0b00000000; 	// Timer starten
    
     uint8_t Dauer_LED1 			= 2;//myRand(255);
     uint8_t Helligkeit_LED1 	= 255;//myRand(255);
     uint8_t LED1;
    
    while(1) {
    	 if (Zeittick >= 3)
    	 {
          //PORTB ^= (1<<PB3);
    			//Zeittick = 0;
    			PORTB |= (1 << PB3);    // setzt Bit 3 an PortB auf 1
    	 }
    
    
    
    /*
     for (LED1 = 0; LED1<Helligkeit_LED1;LED1++)
    		 {
    				OCR1B=LED1;
    				_delay_ms(Dauer_LED1);
    		 }
    //PORTB |= (1 << PB2);    // setzt Bit 3 an PortB auf 1
    //long_delay(1000);
     for (LED1 = 0; (Helligkeit_LED1-LED1)>0;LED1++)
    		 {
    				OCR1B=255-LED1;
    				_delay_ms(Dauer_LED1);
    		 }
    */
    //PORTB &= ~(1 << PB2);   // loescht Bit 3 an PortB
    
    //long_delay(1000);
    
    /*
     OCR0A = 100;
     long_delay(1000);       // Eine Sekunde warten...
     OCR0A = 1;
     long_delay(1000);       // Eine Sekunde warten...
    */
    //PORTB |= (1 << PB2);    /* setzt Bit 3 an PortB auf 1 */
    }
       
       return 0;
    }
    Ich verstehs nicht. Wenn noch jemand eine Idee hat wäre das klasse. Nur noch als Info, mit diesem Code könnt ihr alle vier PWM Kanäle des Tiny25 nutzen, klappt prima. Nur eben bis auf die Geschichte mit der globalen Variable.

    Internette Grüße
    Stefan

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    55
    Beiträge
    524
    Hallo,

    deine Schreibweise finde ich immer noch nicht schön. Aber das muss ich ja auch nicht. Einige Zeilen sind aber ganz ansehnlich und da fällt mir auf den ersten Blick auf:
    in der ISR
    PORTB &= ~(1 << PB2); // loescht Bit 3 an PortB
    in main
    PORTB |= (1 << PB3); // setzt Bit 3 an PortB auf 1

    Da passt doch was nicht.

    Einen Reset mit Software löst du am besten über den Watchdog aus oder du ziehst über einen Pin den Reset auf 0. Dann wird auch auch alles richtig initialisiert.

    Gruß

    Jens

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    20.07.2007
    Beiträge
    38
    Hallo Jens,

    hast recht, die Kommentare stimmen nicht ganz, was vor den // steht zählt, in sofern ist das schon korrekt. Ändert aber auch nichts an dem Problem der Variablenübergabe von ISR zu Main mittels globaler Variable. Das mit dem Reset hat mich auch verwundert. Ich nutze ein STK500 zum entwickeln. Wenn ich dort die Reset-Taste drücke, wird die Variable Zeittick anscheinend nicht initialisiert. Durch die Reset-Taste bin ich ja erst auf die Sache überhaupt aufmerksam geworden.

    Internette Grüße
    Stefan

  9. #9
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Ist die Groß-Kleinschreibung sicher korrekt ?
    TIM1_OVF_vect

    (GCC macht sich da ins Halstuch)
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    20.07.2007
    Beiträge
    38
    Hai,

    die Schreibweise ist korrekt, ich hab sie direkt aus dem Header-File kopiert und die ISR werden ja auch angesprungen.

    Internette Grüße
    Stefan

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress