mit Optimieung im Compiler fehler bei while Schleife

Gast #984841
Hallo,

ich bräuchte einen Tipp:

Ein bischen code fehlt noch, aber das Problem ist das mit 
eingeschalteter Optimierung am Compiler der Prozessor in der while 
Schleife fest hängt und die Bedingung nicht mehr vergleicht. Ohne 
Optimierung läuft es.

  TIMSK |= (1 << TOIE2);        // Timer2 Overflow Interrupt frei

ISR(TIMER2_OVF_vect)
{
timer2++;
}

int warteschleife (oft) {          // Timer 2 gesteuerte Warteschleife
TCNT2=0b00000000;              // Timer 2 Zähler Reset
TCCR2=0b00000101;              // Timer 2 Prescaler / 128

  while (timer2<oft) {          // Schleife
  ;
  }

timer2=0;                  // Schleife zurücksetzen
TCCR2=0b00000000;              // Timer 2 Zähler Reset
TCNT2=0b00000000;              // Timer 2 Prescaler/Timer aus

return 0;
}

wie könnte ich es zum laufen bekommen ?

viele Grüße
Mario
Gast
ist volatile, funkioniert nicht, nur wenn die Compileroptimierung aus 
ist.

timer2 zählt über "oft" hinaus, habe ich mit printf ausgegeben und 
getestet.
Gast
>Ein bischen code fehlt noch, aber das Problem ist das mit

Dann mach den Code komplett und stell dann deine Frage.

>int warteschleife (oft) {          // Timer 2 gesteuerte Warteschleife

Da ballert dir der Compiler eins rein.

Was soll dieser Unsinn mit irgendwelchen Pseudocodes
die sich nicht einmal kompilieren lassen?
Gast
hier compilierbar:

#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
//#define F_CPU 8000000UL  // 8 MHz


int volatile timer2;


ISR(TIMER2_OVF_vect)
{
timer2++;
}



int main (void)
  {

  // Digitale Ausgänge definieren
  PORTB |= (1 << DDB0);
    DDRB |= (1 << DDB0);                          //0 LED Störung



//Vereinfachung Ausgänge
#define StoerungEIN (PORTB &= ~( ( 1 << PB0 ) ))
#define StoerungAUS PORTB |= (1<<PB0)


  TIMSK |= (1 << TOIE2);        // Timer2 Overflow Interrupt frei

  sei();                    // Interrupts Global einschalten


warteschleife(1000);
StoerungEIN;
}



int warteschleife (oft) {          // Timer 2 gesteuerte Warteschleife
TCNT2=0b00000000;              // Timer 2 Zähler Reset
TCCR2=0b00000101;              // Timer 2 Prescaler / 128



  while (timer2<oft) {          // Schleife
  ;
  }
//StoerungEIN;                // zum testen

timer2=0;                  // Schleife zurücksetzen
TCCR2=0b00000000;              // Timer 2 Zähler Reset
TCNT2=0b00000000;              // Timer 2 Prescaler/Timer aus

return 0;
}
Gast
Mario wrote:
> hier compilierbar:
blablabla

> int volatile timer2;
Oki.

> ISR(TIMER2_OVF_vect)
> {
> timer2++;
> }
Auch ok, wenn auch ungünstig.

> int main (void)
>   {
>
>   // Digitale Ausgänge definieren
>   PORTB |= (1 << DDB0);
>     DDRB |= (1 << DDB0);                          //0 LED Störung
>
> //Vereinfachung Ausgänge
> #define StoerungEIN (PORTB &= ~( ( 1 << PB0 ) ))
> #define StoerungAUS PORTB |= (1<<PB0)
>
>
>   TIMSK |= (1 << TOIE2);        // Timer2 Overflow Interrupt frei
Oki.


>   sei();                    // Interrupts Global einschalten
Wichtig.

> warteschleife(1000);
> StoerungEIN;
> }
Jo.


> int warteschleife (oft) {          // Timer 2 gesteuerte Warteschleife
Klassisches C nimmt per Standard "int" als Datentyp an, wenn nix 
drannesteht grübel

> TCNT2=0b00000000;              // Timer 2 Zähler Reset
> TCCR2=0b00000101;              // Timer 2 Prescaler / 128
Timer läuft los.

>   while (timer2<oft) {          // Schleife
>   ;
>   }
> //StoerungEIN;                // zum testen
>
> timer2=0;                  // Schleife zurücksetzen
Wie wärs denn, wennde den zurücksetz, bevor du anfängs, ihn 
hochzuzählen? Und: Warum nochn Timer? In TCNT2 wird doch schon gezählt.

> TCCR2=0b00000000;              // Timer 2 Zähler Reset
> TCNT2=0b00000000;              // Timer 2 Prescaler/Timer aus
>
> return 0;
> }
Jo.
Gast
> Schreib' mal 'volatile int' statt 'int volatile'. Der Modifier ist so
> evtl. wirkungslos.

Nein, das macht hier keinen Unterschied. Einen Unterschied kann die 
Position des Qualifiers (so nennt der Standard das) eigentlich nur bei 
Zeiger-Deklarationen machen:
1
volatile int* x1;  // (1)
2
int volatile* x2;  // (2)
3
int * volatile x3; // (3);
Deklarationen (1) und (2) haben die gleiche Bedeutung, (3) ist anders. 
Bei (3) bezieht sich das volatile im Gegensatz zu (1) und (2) auf den 
Zeiger selbst und nicht auf das, worauf der Zeiger zeigt.

Der Punkt ist aber, dass (1) und (2) absolut gleichwertig sind, kein C- 
oder C++-Compiler darf diese Typen als unterschiedlich ansehen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.