Forum: Compiler & IDEs mit Optimieung im Compiler fehler bei while Schleife


von Mario (Gast)


Lesenswert?

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

von Sven P. (Gast)


Lesenswert?

timer2 muss volatile sein.

von Mario (Gast)


Lesenswert?

ist volatile, funkioniert nicht, nur wenn die Compileroptimierung aus 
ist.

timer2 zählt über "oft" hinaus, habe ich mit printf ausgegeben und 
getestet.

von holger (Gast)


Lesenswert?

>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?

von Mario (Gast)


Lesenswert?

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;
}

von holger (Gast)


Lesenswert?

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

Träum weiter.

von Mario (Gast)


Lesenswert?

dein Kommentar hilft mir nicht weiter, ich würde nicht umsonst hier 
fragen. Ich weiß nicht was du meinst.

von Andreas W. (Gast)


Lesenswert?

Datentyp von oft ?

von Mario (Gast)


Lesenswert?

wingcc macht daraus ein int

../test.c:43: warning: type of 'oft' defaults to 'int'

von Sven P. (Gast)


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mario wrote:
>
> wie könnte ich es zum laufen bekommen ?
>

Wenn ich mir den Code so anschau, solltest Du erstmal die Frage lösen

"Wie könnte ich es zum Compilieren bekommen?"

von Schwurbl (Gast)


Lesenswert?

Schreib' mal 'volatile int' statt 'int volatile'. Der Modifier ist so 
evtl. wirkungslos.

von Chris (Gast)


Lesenswert?

> 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.

von jl (Gast)


Lesenswert?

wie siehts denn mit dem assembler output (lst - file) aus?

der gibt zusätzlich bestimmt nützliche Infos was der Compiler 
drausmacht.



JL

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.