www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Warteschleife mit C - wird von WinAVR wegrationalisiert!


Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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..
#include <avr/io.h>
//#include <avr/interrupt.h>
#define TAKT 16000000UL /* 16 Mhz-Takt; hier richtigen Wert eintragen */



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






int main(void)
{
unsigned int hell;
hell=0;
    DDRD |= (1 << PD5); // PD0 als Ausgang festlegen
     DDRD |= (1 << PD6); // PD0 als Ausgang festlegen
        PORTD |= (1 << PD5); // PD0 aktivieren
       PORTD |= (1 << PD6); // PD0 aktivieren
 

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

nms(1000);

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

} 

}

Autor: *.* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch's mal mit "volatile".
//Subroutinen
void ms(void){volatile unsigned int i; for (i=0; i<TAKT/6000; i++){};}
void nms(unsigned int count){volatile unsigned int i; for(i=0;i<count;i++){ ms();}}

Autor: *.* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

Das kennt er bestimmt
asm volatile ("nop" ::);

Autor: *.* (Gast)
Datum:

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

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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Einer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wahrscheinlich nicht da das beide i lokal sind.

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.gnu.org/savannah-checkouts/non-gnu/avr-...

Du brauchst das Rad nicht neu erfinden...

Achtung aufpassen wenn du den Funktionen eine Variable übergibst wird 
die float lib eingebunden

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Alex (Gast)

>Ohne OPtimierung ist die delay.h ein ganz schöner Ressourcenfresser, 3kb
>:-) Na gut dafür gibt es ja Optimierung.

Nöö, siehe

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

MFG
Falk

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.