- LiFePO4 Speicher Test         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: If-Schleife wird nicht ausgeführt

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    05.04.2008
    Beiträge
    40

    If-Schleife wird nicht ausgeführt

    Anzeige

    Powerstation Test
    Hi Community,

    ich habe ein Problem mit einer If-Schleife in meinem Code:

    Die Bedingung ist erfüllt, aber der Code der in der If-Schleife steht wird einfach nicht ausgeführt.

    Die IF-Schleife ist ganz am Ende des Codes.

    Code:
    /*
     * main.c
     *
     *  
     *     
     */
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define F_CPU       2048000UL
    
    #define BAUD        9600UL
    #define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)
    
    #define LED_DDR		DDRD
    #define LED_PORT	PORTD
    #define LED_PORTPIN	PD7
    
    volatile unsigned int Zaehlerstand;
    
    volatile struct sek										//vereinbart eine neue struktur vom Typ sek
    	{
    	unsigned char bit;									//ist entweder 1 oder 0 - Bit für die Sekunde ist gesetzt oder auch nicht
    	unsigned char wert;									//zeigt an welche Information über das Bit verschlüsselt ist
    	};
    
    volatile struct sek sekunde[60];						//erzeugt ein Feld aus 60 Variablensätzen die wie in sek definiert organisiert sind
    
    volatile unsigned char counter , start;					//counter zeigt an welche die aktuelle Sekunde ist
    
    
    void uart_init(void)
    {
        // Baudrate einstellen (Normaler Modus)
        UBRRH = (uint8_t) (UBRR_BAUD>>8);
        UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);
    
        // Aktivieren von receiver und transmitter
        UCSRB = (1<<RXEN)|(1<<TXEN);
    
        // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
        UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    }
    
    void struct_init(void)
    {
    	while ( !( UCSRA & (1<<UDRE)) );					// Warten bis der Sendepuffer frei ist
    	UDR = '!';											// Daten in den Puffer schreiben und damit senden
    
    
    	sekunde[21].wert = 1;								//Sekunde 21-27 verschlüsselt die Minute
    	sekunde[22].wert = 2;
    	sekunde[23].wert = 4;
    	sekunde[24].wert = 8;
    	sekunde[25].wert = 10;
    	sekunde[26].wert = 20;
    	sekunde[27].wert = 40;								//
    
    	sekunde[29].wert = 1;								//Sekunde 29-34 verschlüsselt die Stunde
    	sekunde[30].wert = 2;
    	sekunde[31].wert = 4;
    	sekunde[32].wert = 8;
    	sekunde[33].wert = 10;
    	sekunde[34].wert = 20;								//
    }
    
    
    ISR (INT1_vect)
    {
    	LED_PORT |= (1<<LED_PORTPIN);
    
    	Zaehlerstand = TCNT1;								//den aktuellen Zaehlerstand auslesen
    
    	TCNT1 = 0;											//den Zaehlerstand zuruecksetzen
    
    	if (Zaehlerstand >= 1000)							//die Zeit zwischen zwei Low-Pegeln wurde gemessen
    		{
    			if (Zaehlerstand >= 3400)					//die Pause vor der nächsten Minute wurde gemessen
    				{
    				counter = 0;							//counter wird resetet
    
    				start++;
    
    				while ( !( UCSRA & (1<<UDRE)) );					// Warten bis der Sendepuffer frei ist
    				UDR = '?';											// Daten in den Puffer schreiben und damit senden
    
    				while ( !( UCSRA & (1<<UDRE)) );					// Warten bis der Sendepuffer frei ist
    				UDR = start;											// Daten in den Puffer schreiben und damit senden
    
    				while ( !( UCSRA & (1<<UDRE)) );		// Warten bis der Sendepuffer frei ist
    
    				UDR = '2';								// Daten in den Puffer schreiben und damit senden
    				}
    		}
    	else												//die Zeit eines Low-Pegel wurde gemessen
    		{
    			if (Zaehlerstand >= 300)					//Low-Pegel > 150ms -> 1
    				{
    					sekunde[counter].bit = 1;			//setzt in der aktuellen Sekunde das Bit auf 1
    
    					counter = counter + 1;				//stellt counter auf die nächste Sekunde
    
    					while ( !( UCSRA & (1<<UDRE)) );	// Warten bis der Sendepuffer frei ist
    
    					UDR = '1';							// Daten in den Puffer schreiben und damit senden
    				}
    			else										//Low-Pegel < 150ms -> 0
    				{
    					sekunde[counter].bit = 0;			//setzt in der aktuellen Sekunde das Bit auf 0
    
    					counter = counter + 1;				//stellt counter auf die nächste sekunde
    
    					while ( !( UCSRA & (1<<UDRE)) );	// Warten bis der Sendepuffer frei ist
    
    					UDR = '0';							// Daten in den Puffer schreiben und damit senden
    				}
    		}
    }
    
    void auswertung(void)
    {
    	unsigned char i;
    	unsigned char minute = 0;
    	unsigned char stunde = 0;
    
    	LED_PORT &= ~ (1<<LED_PORTPIN);
    
    	while ( !( UCSRA & (1<<UDRE)) );					// Warten bis der Sendepuffer frei ist
    	UDR = '3';											// Daten in den Puffer schreiben und damit senden
    
    	start = 1;												// Flag für Auswertung zurückgesetzt
    
    	if ( (sekunde[28].bit == 1) && (sekunde[35].bit == 1) )	//Auswertung nur wenn beide Prüfbits gesetzt
    		{
    		for (i = 21 ; i <= 27 ; i++)						//Auswertung der Minuten
    			{
    			if (sekunde[i].bit == 1) minute = ( minute + sekunde[i].wert );
    			}
    		for (i = 29 ; i <= 34 ; i++)						//Auswertung der Stunden
    			{
    			if (sekunde[i].bit == 1) stunde = ( stunde + sekunde[i].wert );
    			}
    
    		while ( !( UCSRA & (1<<UDRE)) );					// Warten bis der Sendepuffer frei ist
    		UDR = minute;											// Daten in den Puffer schreiben und damit senden
    
    		while ( !( UCSRA & (1<<UDRE)) );					// Warten bis der Sendepuffer frei ist
    		UDR = stunde;											// Daten in den Puffer schreiben und damit senden
    		}
    	else													//Prüfbits nicht gesetzt
    		{
    		while ( !( UCSRA & (1<<UDRE)) );					// Warten bis der Sendepuffer frei ist
    
    		UDR = '!';											// Daten in den Puffer schreiben und damit senden
    		}
    }
    
    
    
    void main(void)
    	{
    	uart_init();										//UART initialisieren
    
    	struct_init();										//Strukturen initialisieren
    
    	counter = 0;
    
    	start = 0;
    
    	GICR |= (1<<INT1);									//externer Interrupt an INT1 (PD3) aktiviert
    
    	MCUCR |= (0<<ISC11) | (1<<ISC10);					//Interupt bei jeder logische Veränderung an INT1 (PD3)
    
    	TCCR1B |= (1<<CS12) | (1<<CS10);					// Prescaler auf 1024 -> 2.048MHz/1024 -> 2000Hz
    
    	sei();												//Interrupts freischalten
    
    	LED_DDR |= (1<<LED_PORTPIN);						//LED Port als Ausgang
    
    	LED_PORT &= ~ (1<<LED_PORTPIN);						//LED Port auf High -> LED leuchtet
    
    
    	while(1);
    		{
    		if (2==start) <================================
    			{
    			auswertung();
    			}
    		}
    	}
    Wie man sieht wird die Variable start im Laufe des Programmes gleich 2.

    Das funktioniert auch. Ich habe mir den Wert über RS232 schicken lassen. Aber die IF-Schleife wird nicht ausgeführt.

    Hat jemand vielleicht eine Idee woran das liegen könnte?

    Ich Programmiere unter Ubuntu mit Eclipse und AVR-Plugin.

    Vielen Dank

    Knipser

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Ich habs jetzt zwar nicht selbst getestet und auch nichts im Internet auf die Schnelle zu volatile gefunden, aber ich habe die Vermutung, das volatile immer nur für die folgende Variable gilt. In allen Beispielen wird jede Variable separat als volatile deklariert. Dann würde das bedeuten, dass start gar nicht von den Registern fern gehalten wird und deshalb im Hauptprogramm der Status nicht aktuell ist. Außerdem sollte eine ISR so kurz wie möglich sein. Besonders UART Sendungen verlängern die ISR Abarbeitung unverhältnismäßig. Rein Interessehalber wäre es interessant, die Variable start einmal so stehen zu lassen, aber dafür die UART Sachen in das Hauptprogramm auszulagern und damit zu sehen, ob sich start verändert. Wenn nicht, dann spendiere der Variable ein eigenes volatile Schlüsselwort.

    sast

    雅思特史特芬
    开发及研究

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    05.04.2008
    Beiträge
    40
    hey sast,

    erstmal danke für deine Antwort.

    Ich habe start jetzt mal als volatile deklariert, aber es funktioniert immer noch nicht.

    Ich habe es auch schonmal mit einem Zeiger auf start probiert, aber das funktioniert auch nicht...

    Das das UART in der ISR nicht ideal ist weiß ich, aber es soll auch nur zu Testzwecken sein und bis jetzt hat es immer einwandfrei funktioniert. Da der UART nur von diesem mC benutzt wird, ist das UART auch immer frei.

    Vielleicht fällt dir ja sonst noch was auf, oder auch jemand anderem.

    Danke an alle die sich in meinen Code vertiefen.

    mfg Knipser

  4. #4
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Wie schnell kommen denn die Interrupts hintereinander?
    Versuchs doch mal mit dem Ausgeben der start Werte in der Hauptschleife und nicht in der ISR

    sast

    雅思特史特芬
    开发及研究

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.04.2010
    Beiträge
    1.249
    Es gibt keine IF-Schleifen!

    start=0;
    Und dann wunderst du dich das die Bedingung (2==start) nicht erfüllt ist?!
    Bevor der Interrupt die Chance bekommt start zu verändern, ist das Programm schon zuende.

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    33
    Beiträge
    1.192
    Der Fehler liegt kurz vor dem if:
    Code:
    while(1);
    Damit bleibt das Programm an dieser Stelle stehen. Der Strichpunkt muss unbedingt weg! \/
    Bin schon öfters in diese Falle getappt, deswegen schau ich da genauer hin.
    Grüße
    Bernhard

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    19.04.2005
    Ort
    Minden
    Alter
    39
    Beiträge
    227
    Kann es sein das bei
    Code:
    while(1);
    das ";" weg muss?

    edit: zu langsam =)
    gruß ceekay \/

  8. #8
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Ja das Semikolon ist natürlich tötlich. Aber die Aussage von TobiKa ist nicht richtig, dass das Programm schon vor dem Interrupt zuende ist. Es ist eher so, dass es bis zum Stromausfall oder Reset in der while-Schleife hängt.
    Den Interrupt interessiert es nicht, ob das Hauptprogramm im Kreis rennt, der kommt trotzdem.
    So etwas wie If-Schleife überlese ich eigentlich, aber wenn man einmal mit der Nase drauf gestoßen wird. Das ist ja nicht nur ein Flüchtigkeitsfehler sondern zieht sich wie ein roter Faden durch den ganzen ersten Beitrag. Es handelt sich hierbei nicht um eine Schleife, sondern um eine bedingte Anweisung.

    Jetzt habe ich für mich allerdings immer noch nicht geklärt, ob volatile nun für alle Variablen gilt die dahinter stehen, oder nur für die direkt folgende. Hat da jemand eine belastbare Aussage dazu? Alle Beispiele und Beschreibungen arbeiten immer nur mit einer volatilen Variable oder verwenden pro Variable eine separate Zeile.

    sast

    雅思特史特芬
    开发及研究

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    05.04.2008
    Beiträge
    40
    Ja beim nächsten mal schreibe ich If-Anweisung...

    Das Semikolon war auf jeden Fall der Fehler!

    Danke an alle die geholfen haben.

    mfg Knipser

    PS das mit dem volatile würde mich auch noch interessieren...

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    48
    Beiträge
    1.146
    Zitat Zitat von sast
    Jetzt habe ich für mich allerdings immer noch nicht geklärt, ob volatile nun für alle Variablen gilt die dahinter stehen, oder nur für die direkt folgende. Hat da jemand eine belastbare Aussage dazu?
    Das volatile gilt für alle dahinter stehenden variablen.
    Hab das mit einem relativ einfachen Test verifiziert:
    Code:
    //Test1:
    volatile int foo1,foo2;
    int *foo3;
    foo3 = &foo2;
    
    //Test2:
    volatile int foo1,foo2;
    volatile int *foo3;
    foo3 = &foo2;
    Bei Test1 meckert der Compiler:
    warning: assignment discards qualifiers from pointer target type
    Bei Test2 macht er das nicht. Also ist foo2 auch als volatile deklariert.

    Gruß,
    askazo

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad