Hallo, warum ist das Ergebnis immer null? (laut AVRStudio Simulator2, ATTINY85) unsigned short temp_us = (unsigned short)78; unsigned char temp_uc = (unsigned char)temp_us; --> Ergebnis von temp_uc = 0 ?!?! Was mache ich falsch? In meinem Programm ist das natürlich etwas komplizierter und die 78 können berechnete Werte von 0-255 sein. Danke für eure Hilfe.
dost0011 schrieb: > In meinem Programm ist das natürlich etwas komplizierter und die 78 > können berechnete Werte von 0-255 sein. Dann wird in dem etwas komplizierteren der Fehler sein. Was passiert wenn du es genau so wie oben eingibst? Bitte Netiquette beachten. Es nützt nix, wenn du ein ähnliches Programm hier zeigst, das hat deinen Fehler nicht!
versuch mal unsigned short temp_us = (unsigned short)78; unsigned char temp_uc = (unsigned char)(unsigned int)temp_us;
Tja, ändert aber auch nichts. Wenn ich denn Cast weglasse, dann funktioniert es ebenso wenig...
Markus schrieb: > Versuch's mal mit volatile. Ggf. wird das ja wegoptimiert. oder nimm zum Testen die Codeoptimierung raus.
Grübler schrieb: > oder nimm zum Testen die Codeoptimierung raus. Nicht oder! Wenn er simuliert, muss er die Optimierung ausschalten. Das ist Grundvoraussetzung.
dost0011 schrieb: > unsigned short temp_us = (unsigned short)78; > unsigned char temp_uc = (unsigned char)temp_us; Natürlich funktioniert das. Da das aber nichts weiter macht, als mit sich selbst beschäftigt zu sein, wird es wegoptimiert. Daran ändert auch das unsinnige Casten nichts. dost0011 schrieb: > In meinem Programm ist das natürlich etwas komplizierter und die 78 > können berechnete Werte von 0-255 sein. Das ist vollkommen egal. Entscheidend ist, was danach damit passiert. Mach die erste Variable global und volatile, dsnn siehst du auch, ob deine Funktion das richtige zurück gibt. Die zweite Variable ist ja ohnehin nur zum Testen der ersten. Simulator schrieb: > Wenn er simuliert, muss er die Optimierung ausschalten. Das ist > Grundvoraussetzung. Damit geht man zwar auf Nummer sicher. Aber ein Muss ist das nicht. mfg.
dost0011 schrieb: > In meinem Programm ist das natürlich etwas komplizierter und die 78 > können berechnete Werte von 0-255 sein. Ich würde mich sogar soweit aus dem Fenster lehnen, um zu behaupten das das Problem in der Berechnung liegt. > Was mache ich falsch? Du postest irgendeinen Code, der nichts mit deinem Problem zu tun hat, anstelle deines richtigen Codes.
Hallo, also erst mal freue ich mich, dass jetzt so zahlreich geantwortet wurde. Da jetzt also (der vielleicht begründete Verdacht) vorliegt, dass das Problem wo anders liegt, habe ich jetzt den Code so runtergestrickt, dass man das Problem beobachten kann. Ich übergebe für diesen Test ein v_soll von 10000 (in der spätereren Version wird sie in einem Interrupt berechnet). Dieses v_soll wird dann in einer Rechnung verwendet. Ergebnis sollte 222 sein. Das ist es in Zeile 51 auch noch. In Zeile 52 steht dann plötzlich 0 drinnen. Doch auch wenn man die MIN Zeile auskommentiert, steht 0 drinnen. Bin mal gespannt, was ihr dazu meint. Weitere Verwendung: OCR0A und da steht auch null drinnen. Für alle die jetzt richtig bemerken, dass die PWM nicht initialisiert wurde. Stimmt. Ändert aber an der 0 auch nichts.
wie kommst du auf 222? > unsigned short temp_us = (unsigned short)((21UL * (unsigned long)v_soll) > / (unsigned short)v_max) + 1300U; (21 * 1000 / 85 ) + 1300 = 1547 > temp_us = (unsigned short)((unsigned long)temp_us * 59UL / 1000U); 1547 * 59 / 1000 = 91 hast du dir mal die zwischenergebnisse ausgeben lassen?
Peter II schrieb: > wie kommst du auf 222? > >> unsigned short temp_us = (unsigned short)((21UL * (unsigned long)v_soll) >> / (unsigned short)v_max) + 1300U; > > (21 * 1000 / 85 ) + 1300 = 1547 v_soll ist 10000 nicht 1000. Du hast eine 0 zu wenig. Seine Zwischenergbenisse decken sich mit dem was er schreibt. Ich kann auch keinen Overflow in den Berechnungen sehen. Ist m.A. nach alles OK. Ich hab keinen AVR-gcc auf meinem jetzigen Computer, sonst würd ich das mal laufen lassen und mir den Assembler Code ansehenm, wo die 0 als Ergebnis her kommt. Meiner Meinung nach ist der Code in Ordnung.
Die Erklärung des Problems ist gaz einfach: es gibt nämlich zwei Variable namens temp_us. Eine besitzt als Gültigkeitsbereich das Innere des else-Zweiges (Zeile 40-52) und die andere Variable im Rest von Calc_Ua() gültig. Dies kann man auch sehr schön beim Betrachten von main.lss erkennen.
Andreas Schweigstill schrieb: > Die Erklärung des Problems ist gaz einfach: es gibt nämlich zwei > Variable namens temp_us. stimmt sehr gut erkannt - viel mir bei den vielen cast überhaupt nicht auf.
Andreas Schweigstill schrieb: > Die Erklärung des Problems ist gaz einfach: es gibt nämlich zwei > Variable namens temp_us. Eine besitzt als Gültigkeitsbereich das Innere > des else-Zweiges (Zeile 40-52) und die andere Variable im Rest von > Calc_Ua() gültig. OMG. Jep. Das waren Tomaten auf den Augen.
Vielen vielen Dank. Keine Ahnung warum mir sowas passiert ist, aber ich habe ewig gesucht und habe irgendwann den Fehler beim Debugger gesucht - mangels derzeitiger Möglichkeit das ganze in der Schaltung zu testen...
Und wirf die Casts wieder raus. Du verschleierst mit den ganzen Casts viel zu viel. zb 21UL * (unsigned long)v_soll hier braucht es keinen Cast. 21 ist schon ein unsigned long. Damit ist klar, dass v_soll automatisch zumindest auf unsigned long 'angehoben' wird, wenn es nicht selbst schon unsigned long ist. (Ich kann mir vorstellen, dass du die Casts auf der Suche nach dem Fehler eingebaut hast, widersteh aber der Versuchung sie drinnen zu lassen. Bei Casts sollte man noch der Devise vorgehen: Casts sind Waffen! Sie werden nur dann benutzt, wenn es nicht anders geht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.