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
:
Verschoben durch Admin
verwendeter uC? Compiler? Codeauschnitt usw. usw. Hellseherforum ist irgendwo anders.
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.
Hier mal ein PC-Programm
1 | #include <stdio.h> |
2 | |
3 | int main(int argc, char *argv[]) |
4 | {
|
5 | int i = 28; |
6 | i *= 1.5; |
7 | printf("%d",i); |
8 | return 0; |
9 | }
|
Und was wird ausgegeben? Logisch: 42
Und wenn du davor eine Endlosschleife einfügst, funktioniert es nicht mehr. q.e.d.
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.
Hansen, den Namen muss ich mir merken, nicht dass ich da aus Versehen mal antworte ...
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.
Hansen schrieb: > Bittesehr, es funktioniert alles. Dann geh wieder spielen! Hansen schrieb: > Nun alle zufrieden oder was ? Wenn du es bist!