Hallo,
Ich habe heute einen Fehler festgestellt undzwar, wenn ich eine uint32_t
variable mit *1.5 rechnen möchte, spielt der ganze µC verrückt.
Gibt es dafür eine logische erklärung?
Ebenso wollte er nicht zuerst *15 und danach /10 rechnen. Ich denke es
hat wieder was mit Float zu tun.
Danke schonmal
Hansen
Wenn du deinen Frust nun erfolgreich abgeladen hast, dann hast du
vielleicht wieder die Ruhe, mal drüber nachzudenken, wie jemand auf
deinen Beitrag reagieren soll, angesichts dessen was alles nicht
erwähnt wird.
Ich denke die Frage war gut formuliert, ob ein spezialfall eintritt wenn
eine 32 Bit Integer Variable mit einer Float konstante multipliziert
wird.
verwendet wird avr gcc und Atmega 32
Hansen
Hansen schrieb:> Ich denke die Frage war gut formuliert, ob ein spezialfall eintritt wenn> eine 32 Bit Integer Variable mit einer Float konstante multipliziert> wird.
Was soll daran speziell sein?
Das passiert in PC-Programmen tagtäglich.
Naja, so einen Integer nimmt man ja auch so *1.5:
i += (i>>1);
Aber das ändert an Deinem Problem wohl wenig. Was interessant wäre: Was
meinst Du mit "spielt der ganze µC verrückt"?
Hansen schrieb:> Ich denke die Frage war gut formuliert,
Nein, denn du hast die essentiellen Informationen über Prozessor und
Compiler vergessen und hast die falsche Frage gestellt, weil du
tatsächlich eine eigene völlig falsche Vermutung/Diagnose aufgestellt
hast, die du bestätigt haben wolltest. Besser wäre es gewesen, das
konkrete Problem zu schildern, d.h. was genau du getan hast (Code) und
was dabei überraschenderweise herauskam ("spielt verrückt" ist eine
nutzlose Information).
Tatsächlich gibt es beim avr-gcc bei Fliesskommarechnung zwei Dinge zu
beachten. Man muss die richtige Lib für die Laufzeitfunktionen einbinden
und man muss ebenfalls etwas beachten wenn man printf mit
Fliesskommwerten verwenden will. Beides ist in der Doku zur avr-libc
aufgeführt.
Hallo!
Du behauptest ich habe eine völlig falsche vermutung/Diagnose
aufgestellt. Kannst du doch garnicht wissen oder?
Also Mein Programm funktioniert ganz normal, doch sobald ich irgendwo im
Programm x*=1.5; einfüge gehts nichtmehr.
selbst wenn der ablauf so ist:
int main(void)
{ ...
...
...
while(1);
x*=1.5;
}
Selbst wenn er es nie erreicht, funktioniert das Programm danach
nichtmehr.
MfG
Hansen schrieb:> Du behauptest ich habe eine völlig falsche vermutung/Diagnose> aufgestellt.
Soooo sensibel?
> Kannst du doch garnicht wissen oder?
Es ist ganz einfach so, dass offenbar nur DU das Problem hast, und
deshalb hat es nichts mit C an sich zu tun, sondern mit deiner
speziellen Konstellation (Compilerschalter, Libs,...)
> Also Mein Programm funktioniert ganz normal, doch sobald ich irgendwo im> Programm x*=1.5; einfüge gehts nichtmehr.
WAS geht dann nicht mehr?
Das Compilieren?
Was sagt der Debugger?
> Selbst wenn er es nie erreicht, funktioniert das Programm danach> nichtmehr.
Wenn er die Stelle nie erreicht, funktioniert da vorher schon was
nicht... :-o
Hansen schrieb:> x*=1.5;>> Selbst wenn er es nie erreicht, funktioniert das Programm danach> nichtmehr.
Passt das Programm noch in den Controller? Der Fliesskomma-Code ist
recht groß. Poste mal die vollständigen Compilermeldungen.
Sebastian
AVR Memory Usage
----------------
Device: atmega32
Program: 8886 bytes (27.1% Full)
(.text + .data + .bootloader)
Data: 794 bytes (38.8% Full)
(.data + .bss + .noinit)
Build succeeded with 0 Warnings...
Also das past alles noch rein!
Ich meine, alles was nach while(1); steht, wird doch 100%ig nie
aufgerufen.
Compilieren und alles geht, doch wenn ich das Programm auf den µC lade,
funktioniert es nichtmehr.
Wenn ich dagegen statt *1.5 schreibe *12 und danach >>3 funktioniert es.
Lothar Miller schrieb:>> Selbst wenn er es nie erreicht, funktioniert das Programm danach>> nichtmehr.> Wenn er die Stelle nie erreicht, funktioniert da vorher schon was> nicht... :-o
Da ist ein Semikolon (Strichpunkt). ;-)
Hansen schrieb:> Wenn ich dagegen statt *1.5 schreibe *12 und danach >>3 funktioniert es.
Zeig jetzt doch einfach endlich mal deinen Code!
Und beschreibe, WAS da nicht mehr funtktioniert.
> Ich meine, alles was nach while(1); steht, wird doch 100%ig nie> aufgerufen.
Es sei denn, da wäre ein break in der Schleife, oder ein goto...
ich verspreche dir, in einem while(1); kann kein goto oder break stehen
;) weil der Strichpunkt gleich nach dem while is, und somit ist es nur
eine sinnlose endlosschleife!
Hansen schrieb:> ich verspreche dir
Gut, da hast du Recht... :-o
Aber wo ist der Rest vom Code? Was ist die Minimalausführung
(Dreizeiler) der das von dir beschriebene fehlerhafte Verhalten zeigt?
Ok es scheint nun doch zu funktionieren !?
aber ne andere Frage, goto in gcc funktioniert ? könnte ich damit
mittels eines Interrupts aus einer Endlosschleife hinausspringen?
Hansen
Ganz im Ernst, ich kann hier nur allen Beteiligten dazu raten nicht
weiter darauf einzugehen. Es wird zig mal nach dem Code gefragt, darauf
wird nicht eingegangen und schließlich ist das Problem wie durch
Zauberei behoben.
Oberlehrer, dein Name triffts exakt ;)
Ich habe den Code mit absicht nicht angefügt, da die Diskussion ÜBER den
Code ( ohne das Problem von dem ich anfangs geschildert habe ) über
mehrere Tage gelaufen wäre, und schlussendlich hätte niemand was davon.
Ob wer antwortet oder nicht, muss er eh selbst entscheiden.
Wenn du aus einem Interrupt direkt in einen anderen Programmteil
springen würdest, dann müsstest du den Programm-Stackpointer selber
korrigieren.
Geht das in C überhaupt?
Das wäre aber schlechter Code. Setz doch in deinem Interrupt eine
Variable die in deiner Schleife abgefragt wird. Wenn die dann z. B. 1
ist, dann machst du einen ganz "normalen" Abbruch der Schleife.
Mein Tipp: Das Problem ist ein ganz anderes. Manchmal wird ein Fehler
erst durch das einfügen einer Zeile "aktiviert". Deshalb versucht man
den Fehler zu isolieren.
Also z.B. ein neues Programm, was nur die fragliche Zeilen enthält. Wenn
der Fehler dann immer noch auftritt hat man zumindest nicht soviele
Parameter an denen man spielen muss um den Fehler vielleicht zu
verstehen.
Ausserdem, mach doch * 3 / 2 (oder noch besser was Eddy Current
vorgeschlagen hat), ist auch viel schneller als mit float rumzurechen,
und anschliessend wieder alle Nachkommastellen wegzuwerfen !
Helmut S. schrieb:> Wenn du aus einem Interrupt direkt in einen anderen Programmteil> springen würdest, dann müsstest du den Programm-Stackpointer selber> korrigieren.> Geht das in C überhaupt?
Im Prinzip ja, mit setjmp/longjmp. Allerdings ist das nicht aus ISRs
vorgesehen, da es dafür nicht selten spezieller Handlungen zur
Beendigung des Handlers bedarf, die nicht Bestandteil von longjmp sind.
> Das wäre aber schlechter Code.
Allerdings. Davon ist auch dann abzuraten, wenn es mit longjmp möglich
sein sollte.
Normalerweise macht man das so:
Eine Variable als volatile deklarieren und initialisieren, z.b. als 0.
Im Interrupt die variable auf 1 setzen.
In der Schleifenbedingung abfragen, ob die variable 1 ist, wenn ja dann
raus gehen.
Hansen schrieb:> Oberlehrer, dein Name triffts exakt ;)>> Ich habe den Code mit absicht nicht angefügt, da die Diskussion ÜBER den> Code ( ohne das Problem von dem ich anfangs geschildert habe ) über> mehrere Tage gelaufen wäre, und schlussendlich hätte niemand was davon.
Aha.
Du meinst also wenn wir dir zeigen, wie man die Dinge richtig macht,
dann hat niemand was davon.
Du hast insofern recht, als wir uns dann Arbeit sparen. Aber abgesehen
davon liegst du falsch.
Die Frage nach dem goto macht mich allerdings stutzig.
Und noch was:
Scheint zu funktionieren bedeutet in vielen Fällen, dass sich ein oder
mehrere Fehler ganz einfach noch nicht bemerkbar gemacht haben. Nicht
mehr. Scheint zu funktionieren bedeutet auf keinen Fall, dass alles
richtig ist.
Bernd schrieb:> Hansen, den Namen muss ich mir merken,> nicht dass ich da aus Versehen mal antworte ...
Jau, da hatte ich auch schon dran gedacht. Aber wie es sich für die
heutige Zeit gehört automatisiert, als Verbesserungsvorschlag für
Andreas. Eine persönliche Blacklist fürs Forum.
Hansen schrieb:> Bittesehr, es funktioniert alles.>> Nun alle zufrieden oder was ?
Ich ja. Hat das Trauerspiel hier endlich ein Ende. Viel Glück noch,
wirst Du brauchen bei Deiner Kompetenz im technischen wie im
kommunikativen Bereich.
>Nun alle zufrieden oder was ?
Was hast Du für einen Eindruck?
Wir hätten Dir gerne geholfen und das so, das auch anderen mit dem
selben Problem geholfen ist.
Du kannst davon ausgehen, das die Fragen der kompetenteren Antworter
hier, nicht völlig blödsinnig sind. Deine Beurteilung der Frage, ob und
welche Informationen zur Lösung Deines Problems nötig sind kollidiert
naturgemäß mit der Beurteilung derjenigen die Dir hier helfen wollen.
Das ist mehr oder weniger zwangsweise so, denn ganz klar: Probleme
beruhen entweder auf ungenügender, d.h. unvollständiger oder
irrelevanter Information oder auf Fehler in ihrer Darstellung.
Deswegen fragen potentielle Helfer nach Informationen.
Umgekehrt, wenn Du in der Lage wärst (ich meine einfach nur Deinen
Kenntnisstand und nicht Deine grundsätzliche Fähigkeit dazu) die
Informationen vollständig und relevant zu geben und darzustellen,
hättest Du das Problem schon selbst erkannt, weil es irgendwo einen
Widerspruch gegeben hätte.
In Anbetracht dessen halte ich Deine Empfindlichkeit nicht angebracht.