Frequenzmessung und Optimierung -Os

Gast #745598
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.
Angehängte Dateien:
Gast #745623
Lesenswert?

Ich bekomme nach der Optimierung einfach keine Anzeige auf dem Display.
In
1
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.
Gast #745635
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
Gast #745671
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.
Gast #745682
Lesenswert?

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

Wieso schreibst du die einfachere Formel in den Kommentar statt direkt 
in den Code?
Gast #745685
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^^).
Gast #745922
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.
#745925
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.
Gast #745949
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.
#745990
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.
1
while(1)
2
{  
3
  if (flanke_anz > 12) 
4
  { 
5
    cli();
6

7
    if (ueberlauf==0) 
8
    {
9
        zeitdiff=zeit2-zeit1;      //wenn kein �berlauf dann nur zeit zwischen timestamp's
10
    }
11
    else
12
    {
13
    //bsp f�r 2 �berlaufe:    
14
    //      t1  �1      �2  t2
15
    //    ...|-----|-----------|---|...
16
    //      65535-zeit1     zeit2
17
    //      65635*(ueberlauf-1)
18
        zeitdiff = (65535-zeit1) + 65535 * (ueberlauf-1) + zeit2;
19
    //umgestellt--> zeitdiff=65635*ueberlauf+zeit2-zeit1;
20
    //wenn �berlauf, dann zeit von 1.timestamp zu 1.�berlauf +zeit f�r alle �berl�ufe +zeit von letztem �berlauf bis 2.timestamp
21
    }
22

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

27
    ltoa( zeitdiff, s, 10 ); 
28
    lcd_clrscr();
29
    lcd_puts( zeitdiff );
30

31
    //lcd_puts("/n");
32
    //frequenz=cpu_takt/zeitdiff;
33
    //lcd_puts(dtostrf(frequenz,6,3,s));
34
  }
35
}
Gast #746008
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.
Gast #746050
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.
Gast #746127
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?
#746146
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).
Gast #746426
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"
Gast #746819
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
Gast #746993
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.
Angehängte Dateien:
Gast #747287
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
#747471
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
Gast #747850
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
Gast #748548
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.
Gast #749338
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
Gast #767887
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
Gast #767961
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

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