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.
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.
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.
>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
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...
>>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.
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^^).
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.
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.
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.
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.
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 ;)
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
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.
> 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.
"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?
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).
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"
Hast du nach den Änderungen immer wirklich alles neu übersetzt? Wenn
du im Makefile die Optimierungseinstellungen änderst, wird nicht
automatisch alles neu gebaut.
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
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.
>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
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
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
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.
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
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
> 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