Warteschleife mit C - wird von WinAVR wegrationalisiert!

Gast #1160140
Lesenswert?

Habe mich jetzt ewig damit rumgeschlagen um rauszufinden dass es die 
Optimierung des Codes war, der mir sämtlichen Spaß genommen hat.

Folgender Code ist mehr oder weniger aus dem Atmega-buch von G.Schmitt.

Er funktioniert standardmäßig nicht, auch der Debugger überspringt 
einfach die nms Befehle.

Nur wenn die Optimierungsstufe 0 ist, dann funktioniert es ungefähr. 
Bereits Stufe 1 (und voreingestelle S) rationalisieren die leere 
Schleife einfach weg.
Was kann ich jetzt tun ohne auf meine Optimierung zu verzichten?

Ich hatte es bereits mit __asm NOP; probiert, das kannte er nicht.

P.S: Ich versuche es bewusst ohne Timer zur Übung..
1
#include <avr/io.h>
2
//#include <avr/interrupt.h>
3
#define TAKT 16000000UL /* 16 Mhz-Takt; hier richtigen Wert eintragen */
4

5

6

7
//Subroutinen
8
void ms(void){unsigned int i; for (i=0; i<TAKT/6000; i++){};}
9
void nms(unsigned int count){unsigned int i; for(i=0;i<count;i++){ ms();}}
10

11

12

13

14

15

16
int main(void)
17
{
18
unsigned int hell;
19
hell=0;
20
    DDRD |= (1 << PD5); // PD0 als Ausgang festlegen
21
     DDRD |= (1 << PD6); // PD0 als Ausgang festlegen
22
        PORTD |= (1 << PD5); // PD0 aktivieren
23
       PORTD |= (1 << PD6); // PD0 aktivieren
24
 
25

26
    while(1) // Unendlich lang wiederholen
27
    {
28
PORTD |= (1 << PD5); // PD0 aktivieren
29

30
nms(1000);
31

32
PORTD &= ~(1 << PD5);
33
nms(1000);  
34

35
} 
36

37
}
Gast #1160145
Lesenswert?

Versuch's mal mit "volatile".
1
//Subroutinen
2
void ms(void){volatile unsigned int i; for (i=0; i<TAKT/6000; i++){};}
3
void nms(unsigned int count){volatile unsigned int i; for(i=0;i<count;i++){ ms();}}
Gast #1160147
Lesenswert?

Nachtrag 2: (nein, ich mag mich nicht anmelden!)

Eigentlich sollte einmal das Schlüsselwort "volatile" genügen.
1
//Subroutinen
2
void ms(void){volatile unsigned int i; for (i=0; i<TAKT/6000; i++){};}
3
void nms(unsigned int count){unsigned int i; for(i=0;i<count;i++){ ms();}}
Gast #1160189
Lesenswert?

>P.S: Ich versuche es bewusst ohne Timer zur Übung..

Wenn das Übungsziel war, selber zu erfahren, warum man für solche 
Verzögerungen die Funktionen aus delay.h nutzen soll, hast du bestanden.

Oliver
P.S. Eine Antwortautomatik, die auf einen Thread mit dem Wort "Schleife" 
und/oder "Optimierung" im Titel eine Beitrag mit dem Wort "volatile" 
erzeugt, wäre mal ein Fortschritt :-)
#1160197
Lesenswert?

Hat es sich immer noch nicht herumgesprochen, dass solche selbstgebauten 
Warteschleifen nicht nur Optimizer-Futter sind, sondern auch noch 
ausgesprochener Murks? Es gibt in der util/delay.h einen ganzen Haufen 
Funktionen für genau definierte Wartezeiten, die nicht wegoptimiert 
werden!

EDIT:
docean war schneller...

Aber korrekt: Die Funktionen müssen mit konstantem Parameter aufgerufen 
werden und die Optimierung muss eingeschaltet sein. Wenn man Variable 
delays braucht, kann man ein delay mit fester Zeit in einer Schleife 
mehrmals aufrufen.
Gast #1160661
Lesenswert?

Okay, da habe ich mal versucht vorbildlich zu sein und mich vorher 
belesen und das Buch macht es so. Schade.
Ohne OPtimierung ist die delay.h ein ganz schöner Ressourcenfresser, 3kb 
:-) Na gut dafür gibt es ja Optimierung.

Dankeschön.
#1160673
Lesenswert?

Alex wrote:
> Ohne OPtimierung ist die delay.h ein ganz schöner Ressourcenfresser, 3kb
> :-) Na gut dafür gibt es ja Optimierung.
Ohne Optimierung funktioniert die delay.h auch gar nicht richtig! Die 
Optimierung ist für die Funktionalität zwingend erforderlich. Wenn die 
delay.h eingebunden ist, aber die Optimierung deaktiviert ist, sollte 
normalerweise sogar eine Warnmeldung ausgegeben werden.
Gast #1160842
Lesenswert?

>void ms(void){unsigned int i; for (i=0; i<TAKT/6000; i++){};}

DAS steht so in einem Buch? Abgesehen von dem fehlenden volatile stellt 
sich da nämlich noch die Frage, wie lange eine "ms" sein soll. 
Millisekunden sind es auf jeden Fall nicht, und Mikrosekunden auch 
nicht.

Oliver

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren