Forum: Mikrocontroller und Digitale Elektronik Casten funktioniert nicht


von dost0011 (Gast)


Lesenswert?

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.

von Udo S. (urschmitt)


Lesenswert?

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!

von Kan a. (Firma: Basta) (kanasta)


Lesenswert?

versuch mal

unsigned short temp_us = (unsigned short)78;
unsigned char temp_uc = (unsigned char)(unsigned int)temp_us;

von Rolf Magnus (Gast)


Lesenswert?

Kein einziger dieser Casts ist notwendig.

von dost0011 (Gast)


Lesenswert?

Tja, ändert aber auch nichts.
Wenn ich denn Cast weglasse, dann funktioniert es ebenso wenig...

von Markus (Gast)


Lesenswert?

Versuch's mal mit volatile. Ggf. wird das ja wegoptimiert.

von Grübler (Gast)


Lesenswert?

Markus schrieb:
> Versuch's mal mit volatile. Ggf. wird das ja wegoptimiert.

oder nimm zum Testen die Codeoptimierung raus.

von Simulator (Gast)


Lesenswert?

Grübler schrieb:
> oder nimm zum Testen die Codeoptimierung raus.

Nicht oder!
Wenn er simuliert, muss er die Optimierung ausschalten. Das ist 
Grundvoraussetzung.

von Thomas E. (thomase)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von dost0011 (Gast)


Angehängte Dateien:

Lesenswert?

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.

von dost0011 (Gast)


Lesenswert?

Niemand eine Idee, warum der angehängte Code nicht funktioniert?

von Peter II (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von dost0011 (Gast)


Lesenswert?

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...

von Karl H. (kbuchegg)


Lesenswert?

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
Noch kein Account? Hier anmelden.