Warteschleife mit C - wird von WinAVR wegrationalisiert!

Gast #1160140
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
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
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
>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 :-)
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
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.
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
>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

Eine eigene Frage? Dieser Thread ist über 17 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.