www.mikrocontroller.net

Forum: Compiler & IDEs Frequenzmessung und Optimierung -Os


Autor: Timer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir für meine Codesammlung mal eine Frequenzmessung 
programmiert um später evtl. auch ein LC-Meter zu bauen.
Ich programmiere grundsätzlich immer mit der Optimierung -O0. Das 
Programm funktioniert damit auch schon sehr gut. Nun habe ich mal die 
Optimierung auf -Os umgestellt, da ich ja die delay.h verwende und in 
der Hilfe zu der lib steht, dass man unbedingt die Codeoptimierung 
einschalten soll. Nun hab ich aber das Problem, dass mein Programm nicht 
mehr funktioniert, also wird irgend etwas wegoptimiert, was ich 
eigentlich bräuchte. Da denk ich mir, stellen wir die Optimierung eben 
wieder auf -O0, aber das Programm läuft immer noch nicht!?!?!
Kann mir das einer erklären?
Ich bin froh, dass ich zufällig noch ein BackUp auf dem Stick hatte.

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach so, ich bin leider nicht zu Hause - kann also nicht genau sagen 
welche Version ich von AVR Studio (irgend eine 4.x Version) bzw von 
WinAVR (irgend was von 2007) nutze.
Das Programm läuft auf einem ATMega32 mit 16Mhz Quarz.

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

Bewertung
0 lesenswert
nicht lesenswert
Was funktioniert nicht? Läuft gar nichts?

BTW: Bist Du sicher, dass die Zahlen hier
zeitdiff=(65535-zeit1)+65635*(ueberlauf-1)+zeit2;
stimmen? Zumindest die zweite Zahl würde ich instinktiv anzweifeln...

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bekomme nach der Optimierung einfach keine Anzeige auf dem Display.
In
zeitdiff=(65535-zeit1)+65635*(ueberlauf-1)+zeit2;
ist natürlich die 2. Zahl falsch (Tippfeler^^, muss 65535 sein). Erklärt 
aber immer noch nicht das Problem mit der Optimierung, da der 
Schreibfehler ja nur eine konstante Abweichung der Frequnz hervorrufen 
sollte.
Mein "Gedankengang" zu der Codezeile steht als Kommentar auch darüber, 
falls du es nachvollziehen möchtest.
Trotzdem schon mal dickes DANKE für die Entdeckung des Tippfehlers ;)
Würde mich freuen wenn noch mehr Vorschläge zur Verbesserung meines 
Codes kommen. Man lernt ja nie aus und gerade bei Frequenzmessung kommt 
es auf sauberen Code an um genaue Messungen durchführen zu können.

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

Bewertung
0 lesenswert
nicht lesenswert
Nun, da ich die lcd.h (und die vermutlich dazugehörige lcd.c) nicht 
kenne, kann ich dazu nix sagen...

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>zeitdiff=(65535-zeit1)+65635*(ueberlauf-1)+zeit2;

Und wenn du eine der Variablen nach unsigned long castest, damit die 
ganze Rechnung in long ausgeführt wird? So rechnet der µC ja nur in 
unsigned int. Kann es da zu Überläufen kommen?

MW

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

Bewertung
0 lesenswert
nicht lesenswert
Michael Wilhelm wrote:
> du eine der Variablen nach unsigned long castest, damit die
> ganze Rechnung in long ausgeführt wird? So rechnet der µC ja nur in
> unsigned int. Kann es da zu Überläufen kommen?
Das würde aber auch ohne Optimierung passieren...

Autor: Timer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Die LCD Routinen sind von Peter Fleury aus der HD44780U LCD library.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>zeitdiff=(65535-zeit1)+65635*(ueberlauf-1)+zeit2;
>
> Und wenn du eine der Variablen nach unsigned long castest, damit die
> ganze Rechnung in long ausgeführt wird? So rechnet der µC ja nur in
> unsigned int.

Nein. So wie es oben steht, wird das in long gerechnet.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, was ich vergaß:
zeitdiff=(65535-zeit1)+65535*(ueberlauf-1)+zeit2;
//umgestellt--> zeitdiff=65635*ueberlauf+zeit2-zeit1;

Wieso schreibst du die einfachere Formel in den Kommentar statt direkt 
in den Code?

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, wenn ich Glück habe, liegt es nur an der LCD libery. Kann ja sein, 
dass da delay Pausen drin sind welche für mein Display zu kurz sind 
(ohne Optimierung sind die delays ja zu groß und könnten so gerade 
passen).
Ich probier das heute Abend mal mit einer simplen LCD Ausgabe aus und 
sag dann morgen bescheid.

Die einfache Formel steht im Kommentar, weil ich das erst nachträglich 
geändert habe und noch nicht getestet ist. Quasi als Gedankenstutze, das 
ich das noch machen muss. Ich baue neuen Code immer erst nach dem Test 
ein - never change a running system.

Ist der Code der Frequenzmessung ansonsten so OK, oder kann der noch 
verbessert werden (geht bestimmt^^).

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mir beim Mittag noch mal gedanken darüber gemacht. An der LCD 
Libery kanns ja eigentlich auch nicht liegen, da das Programm beim 
zurückzetzen de Optimierung auf -O0 auch nicht mehr funktioniert.
Irgend einer ne Idee? Evtl. spinnt ja nur AVR Studio.

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

Bewertung
0 lesenswert
nicht lesenswert
Timer wrote:
> Ich hab mir beim Mittag noch mal gedanken darüber gemacht. An der LCD
> Libery kanns ja eigentlich auch nicht liegen, da das Programm beim
> zurückzetzen de Optimierung auf -O0 auch nicht mehr funktioniert.
Wie jetzt? Dann ist die Optimierung also doch nicht Schuld?

> Irgend einer ne Idee? Evtl. spinnt ja nur AVR Studio.
AVRStudio hat damit nichts zu tun. AVRStudio kann kein C und hat mit dem 
Compilieren an sich nichts am Hut.

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab im Ersten Beitrag geschrieben, dass ich -Os eingestellt habe und 
das Programm nicht mehr lief. Nach dem zurückstellen auf -O0 gings aber 
auch nicht mehr, obwohl der Code der gleiche geblieben ist. Nachdem ich 
das BackUp von meinem Stick gezogen hatte war alles wieder i.O. Bei 
jedem Versuch das gleiche Verhalten - keine Anzeige mehr auf dem 
Display.
Will aber eigentlich schon die Optimierung reinnehmen, da es schon einen 
Unterschied macht ob das Programm 6500kB oder 1200kB verbraucht. Soll 
evtl. mal auf nen ATMega8 oder 2321.

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

Bewertung
0 lesenswert
nicht lesenswert
Timer wrote:
> Ich hab im Ersten Beitrag geschrieben, dass ich -Os eingestellt habe und
> das Programm nicht mehr lief. Nach dem zurückstellen auf -O0 gings aber
> auch nicht mehr, obwohl der Code der gleiche geblieben ist.
EBEN. Das ist nämlich eigentlich so gut wie unmöglich.

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau deswegen denk ich ja, dass es evtl. an AVR STudio (da stell ich ja 
die Optimierung ein) oder WinAVR liegt
Ich kanns mir halt auch nicht erklären, deswegen frag ich ja ;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Irgend etwas muss dir beim Einschalten der Optimierung
noch passiert sein. Im Code sehe ich nichts was das
von dir beschriebene Verhalten erklären könnte (*). Auch wenn
ich manches anders machen würde, sehe ich eigentlich
nicht, warum da keine Ausgabe aufs LCD mehr erfolgen
sollte.
(*) Stimmt nicht ganz. Ich würde nicht auf flanke_anz == 13
abfragen, sondern auf größer. Wenn dein Programm aus irgend
einem Grund die 13.te Flanke verpasst dann kannst du das
mit einem > immer noch abfangen. Wenn die Variable aber
exakt 13 sein muss, dann kannst du ev. ein Problem haben.

Was ich an deiner Stelle jetzt tun würde:
Den Behandlungscode in main() mal kürzen, so dass die
Interrupts kürzer gesperrt sind.
while(1)
{  
  if (flanke_anz > 12) 
  { 
    cli();

    if (ueberlauf==0) 
    {
        zeitdiff=zeit2-zeit1;      //wenn kein �berlauf dann nur zeit zwischen timestamp's
    }
    else
    {
    //bsp f�r 2 �berlaufe:    
    //      t1  �1      �2  t2
    //    ...|-----|-----------|---|...
    //      65535-zeit1     zeit2
    //      65635*(ueberlauf-1)
        zeitdiff = (65535-zeit1) + 65535 * (ueberlauf-1) + zeit2;
    //umgestellt--> zeitdiff=65635*ueberlauf+zeit2-zeit1;
    //wenn �berlauf, dann zeit von 1.timestamp zu 1.�berlauf +zeit f�r alle �berl�ufe +zeit von letztem �berlauf bis 2.timestamp
    }

    ueberlauf=0;        //�berl�ufe f�r n�chste Messung r�cksetzen
    flanke_anz=0;        //R�cksetzen f�r n�chste Messung
    sei();

    ltoa( zeitdiff, s, 10 ); 
    lcd_clrscr();
    lcd_puts( zeitdiff );

    //lcd_puts("/n");
    //frequenz=cpu_takt/zeitdiff;
    //lcd_puts(dtostrf(frequenz,6,3,s));
  }
}           

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
von Karl heinz Buchegger:
"Was ich an deiner Stelle jetzt tun würde:
Den Behandlungscode in main() mal kürzen, so dass die
Interrupts kürzer gesperrt sind."

Ist es denn schlimm wenn die Interrupts längere Zeit gesperrt sind?
Gut, ich erhalte keine Messdaten, aber sobald ich die Interrupts wieder 
einschalte sollte doch alles wieder von vorne laufen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ist es denn schlimm wenn die Interrupts längere Zeit gesperrt sind?

Naja, ist eben so eine Grundregel, die Interrupts nie länger als absolut 
nötig zu sperren.

> Gut, ich erhalte keine Messdaten, aber sobald ich die Interrupts wieder
> einschalte sollte doch alles wieder von vorne laufen.

Es werden zumindest mit guter Wahrscheinlichkeit die Interrupt-Flags 
deiner beiden Interrupts gesetzt sein, so daß sofort nach dem sei() 
erstmal irgendwelche alten Interrupts von "früher" deine beiden ISRs 
auslösen werden.

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Es werden zumindest mit guter Wahrscheinlichkeit die Interrupt-Flags
deiner beiden Interrupts gesetzt sein, so daß sofort nach dem sei()
erstmal irgendwelche alten Interrupts von "früher" deine beiden ISRs
auslösen werden."

genau deswegen verwerfe ich auch die erstn 2 Flanken und fange erst mit 
der 3. an über 10T zu messen

Kann man die Interruppt-Flags denn nicht löschen bzw. kommen die 
überhaupt wenn Interrupts deaktiviert sind?
Das wäre ja sonst ein grundsätzliches Problem. Ich mache meine Interrupt 
Routinen immer extra klein, da der nächste Interrupt mir ja im Nacken 
hängt. Den Hauptteil von Berechnungen und Co. mache ich deswegen immer 
in der main und stelle vorher die Interruts ab, damit ich Zeit zur 
Rechnung habe.
Ist das jetzt doch nicht so günstig?

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

Bewertung
0 lesenswert
nicht lesenswert
Timer wrote:
> Kann man die Interruppt-Flags denn nicht löschen bzw. kommen die
> überhaupt wenn Interrupts deaktiviert sind?
Natürlich "kommen" die auch, wenn die Interrupts nicht freigegeben sind. 
Sonst könnte man kein Polling machen. Und natürlich kann man die auch 
von Hand löschen (von wenigen Ausnahmen abgesehen).

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, ich hab mir mal eine einfache Display Routine geschrieben und Os 
eingestellt, hat funktioniert

Dann hab ich mal ein Blinklicht gemacht mit O0 funktionierts mit Os geht 
das Display nicht, aber die LED's blinken. Wenn ich wieder auf O0 
zurückgehe geht das display auch nicht mehr aber die LED's blinken, 
klingt komisch, ist aber so

Dann hab ich mal mit dem Interrupt rumprobiert. hab einfach den int0 
genommen.
Mit O0 funktionierts mit Os nicht und wenn ich wieder auf O0 zurückgehe 
gehts auch nicht mehr. Diesmal hab ich aber die hex dateien 
zwischengespeichert und siehe da, beim ersten mal mit O0 sind einige hex 
werte geändert als beim 2. mal O0 nach Os???????

Irgend was läuft das schief. Ach so, meist wird die LCD init und das clr 
noch gemacht, zumindest zeigt das Display keine "schwarzen Quadrate"

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du nach den Änderungen immer wirklich alles neu übersetzt? Wenn 
du im Makefile die Optimierungseinstellungen änderst, wird nicht 
automatisch alles neu gebaut.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie und wo stellst du denn die Optimierungsstufen ein? In den 
AVRStudio-Projektoptionen, oder woanders?

Oliver

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag: Vergleiche doch auch mal den Konsolenoutput von Compiler und 
Linker, ob da bei den Läufen mit -O0 irgendetwas unterschiedlich ist. Am 
besten in externe Textfiles kopieren, und mit Winmerge o.ä. ansehen.

Oliver

Autor: Timer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Die Optimierungsstufen stell ich direkt bei AVR Studio ein. Ich hab kein 
extra makefile, sondern stell unter Projekt Options (oder so ähnlich) 
meinen ATMEga32, die 16MHz und halt die Optimierung ein. Dann bekomm ich 
mein *.hex file und "brenne" dann mit PonyProg mein ATMega32.

Habe jetzt kein AVR Studio zur Hand, aber zum Übersetzen nehme ich immer 
den linken der beiden Compilebuttons. Sollte auch so stimmen, denn von 
der Einstellung -O0 nach -Os wird ja auch alles neu Übersetzt, da sollte 
es umgekehrt ja genauso sein.

Konsolenoutput werd ich heut Abend mal anschauen.

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achte doch einfach mal darauf, welche Uhrzeit deine Hex hat. nicht das 
du die ganze zeit eine "andere" hex lädst...

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Mit O0 funktionierts mit Os nicht und wenn ich wieder auf O0 zurückgehe
>gehts auch nicht mehr. Diesmal hab ich aber die hex dateien
>zwischengespeichert und siehe da, beim ersten mal mit O0 sind einige hex
>werte geändert als beim 2. mal O0 nach Os???????

@Werner, also 3 verschienene *.hex Dateien. Die erste mit O0 geht die 
zweite mit Os nicht und die dritte wieder auf O0 eben komischer weise 
auch nicht

Autor: Timer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hier mal die Konsolenmitschnitte von AVR Studio

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

nur mal wegen des Effekts, daß das Display auch mit -O0 dann nicht mehr 
geht: Spannung mal ganz aus und wieder ein?

Das Display wird abgestürzt sein, das bekommt ja keinerlei Reset und 
verbleibt vermutlich in einem undefinierten Zustand nach dem Zugriff mit 
den falschen Timings bei -Os.

Gruß aus Berlin
Michael

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Sache mit der Spannung war mein erster Gedanke. Hat aber nicht 
geklappt.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
very strange, das alles.

Wenn die hex-Dateien der beiden -O0-"Versionen" unterschiedlich sind, 
gibt es auch Unterschiede in den .lss, .map, oder anderen Dateien?

Und wenn ja, welche?

Welche WinAVR-Version, welche Studio-Version (da der Consolenoutput 
keine size anzeigt, muß das alles ja schon was älter sein)

Schon mal mit frisch installierten, und/oder aktuelleren Versionen 
probiert?

Oliver

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte erst alles mir den neuen Versionen probiert, hab dann gedacht, 
dass es daran liegt und meine alten Versionen (AVR Studio 4.12, WinAVR 
von 01.2007) wieder installiert, aber war genauso. Zu der Zeit hab ich 
dann auch die Konsolenoutputs gemacht.

Autor: KB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
ich arbeite auch mit dem AVR Studio und nutze winavr über das GCC 
Plugin.
Was sein kann das du nach dem zurückstellen ur -O0 nur ein Teil der 
Objekt Files neu Compiliert wurden und somit avr-gcc da einfach nurks 
macht.

hilft eigentlich dann meistens wenn du dann über Build -> ein mal Clean 
sagst und dann klick ich immer Rebuild All an. Sollte eventuell helfen.
Hat mich zumindest auch hinundwieder nerfen gekostet.

MfG Kai

Autor: Timer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich werd mal probieren.

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Kai,

> hilft eigentlich dann meistens wenn du dann über Build -> ein mal Clean
> sagst und dann klick ich immer Rebuild All an. Sollte eventuell helfen.

danke für diesen wertvollen Tipp -- nach einigem Haareraufen mit einem 
ähnlichen Problem wie von "Timer" oben beschrieben hat er mich gerettet!

Gruß

Fred

Autor: OliverSo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> hilft eigentlich dann meistens wenn du dann über Build -> ein mal Clean
> sagst und dann klick ich immer Rebuild All an. Sollte eventuell helfen.

Wobei das Studio eigentlich sehr zuverlässig in der Bestimmung der 
dependencies ist. Wenn das Projekt mit allen benötigten Sourcen richtig 
angelegt ist, dürfte da nichts schiefgehen.

Oliver

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.