Hallo, ich bin Programmieranfänger und programmiere derzeit einen MC9S12XF512 von freescale in C. Ich möchte Sensordaten, die ich über CAN bekomme an einem Display ausgeben. Dazu werden die Sensordaten in einer unsigned int Variable gespeichert. Mein Problem ist jetzt, dass diese Variable jetzt noch wie folgt umgerechnet werden muss: Displaywert = ((Sensorwert / 4095)-0.5)*300 Der Wertebereich des Sensorwertes liegt zwischen 0 und 4000. Am Display bekomme ich dann falsche Werte zu sehen. Liegt wohl daran, dass der Datentyp unsigned integer nicht für so eine Umrechnung geeignet ist, oder? Aber float oder double Typen unterstützt der µC anscheinend leider nicht, da mir der Linker Fehlermeldungen wirft, wenn ich versuche diese anzulegen. Was könnte ich tun?
Flo schrieb: jetzt überlege doch mal ... > Displaywert = ((Sensorwert / 4095)-0.5)*300 > > Der Wertebereich des Sensorwertes liegt zwischen 0 und 4000. d.h. (Sensorwert / 4095) ergibt (int = ganzzahl) immer 0 du must erst die Multiplikation und danach die Division durchführen! Sascha
hi, wenn du ein wert als unsigned int gespeichert. Wird von Compiler automatisch unsigned interpretiert. Ein wert ist ja nix anderes als nur ein Bitmuster. Lg buddy
> Liegt wohl daran, dass der Datentyp unsigned integer nicht für so > eine Umrechnung geeignet ist, oder? Genau daran liegt. Rechne doch einfach mal schrittweise von Hand durch was da passiert. Und dann ueberlegst du dir bei jedem Schritt wie der wohl in deinen Datentyp passt und was du verbessern kann. > Aber float oder double Typen unterstützt der µC anscheinend > leider nicht, da mir der Linker Fehlermeldungen wirft, wenn > ich versuche diese anzulegen. Ich kenne deinen Prozessor nicht. Aber es kann sein das du dafuer noch einen Header einfuegen musst und deinen Code gegen eine Mathelibary linken musst. Das wird dann aber dazu fuehren das dein Programm sehr fett und natuerlich deutlich langsamerwird. > Was könnte ich tun? Du musst deine Zahlen skalieren. Dann reicht dir vielleicht ein 32Bit Integer aus. Es kann auch sein das es sinnvoll ist deine obige Formel umzustellen. Also erst multiplizieren und dann divideren. Es kann sinnvoll sein deinen Endwert in Abhaengigkeit der Groesse deines Sensorwertes auf unterschiedliche Weise zu berechnen. Und mach dir klar welche Genauigkeit du in der Anzeige brauchst. Es bringt nichts deutlich genauer rechnen als man es letztlich anzeigt. Vielleicht laesst sich deine Formel ja unter etwas Verlust an Genauigkeit noch kuerzen. Olaf
ah, ok. D.h. die Nachkommastelle wird also immer weggeschnitten, wenn ich das richtig verstehe. Hab jezt auch schon folgendes versucht, funktioniert aber immer noch nicht: i_Sensorwert = ui16_Sensorwert; i_Sensorwert = ( ( (i_Sensorwert * 300) - (150*4095) ) / 4095); Am Display erhalte ich nur Werte zwischen -7 und 7, obwohl ich ohne Umrechnung Sensorwerte von 3000 und mehr erreiche. Da stimmt leider immer noch etwas nicht.
Wahrscheinlich, weil du es nicht so machst, wie ich es sagte? :-) Klaus Wachtler schrieb: > Oder einfach: > Displaywert = ((Sensorwert / 4095.0)-0.5)*300
Klaus Wachtler schrieb: > Wahrscheinlich, weil du es nicht so machst, wie ich es sagte? :-) > > Klaus Wachtler schrieb: >> Oder einfach: >> Displaywert = ((Sensorwert / 4095.0)-0.5)*300 Naja du castest hier ja implizit. Und wie ich schon sagte, float wird nicht unterstützt. Die Lösung funktioniert also auch nicht! i_Sensorwert = ui16_Sensorwert; // ui16_Sensorwert aus CAN. Wert von ca. 2025 entspricht Displaywert 0 i_Sensorwert = ( ( (i_Sensorwert * 300) - (150*4095) ) / 4095); Den Sensorwert hab ich jetzt mal als long int ausgeführt. Funktioniert aber immer noch nicht. Statt 0 zeigt mir das Display in 148 an. Werd noch wahnsinnig...
Da es sich bei dem MC9S12XF512 um eine 16Bit Controller handelt denke ich mal das sein unsigned int auch nur 16bit groß sein wird. somit liegt die maximale Größe der Zahl bei 65536. Angenommen dein Sensorwert wäre nun 2025 erhältst du folgende ergebnisse: 2025*300=607500 Das ist natürlich wesentlich größer als der mögliche Darstellbare Zahlenraum durch dein unsigned int (16 Bit). Damit hast du variablenüberläufe und auch vollkommen falsche Zahlen mit denen du weiterrechnest. du brauchst also eine 32 Bit variable.
Flo schrieb: > Und wie ich schon sagte, float wird > nicht unterstützt. Die Lösung funktioniert also auch nicht! Wenn du das weißt, wieso ziehst du dann 0.5 ab? Na, egal. Dann musst du halt die ganze Rechnung in Festkomma machen. Dazu gibt es hier die eine oder andere Anleitung.
>i_Sensorwert = ( ( (i_Sensorwert * 300) - (150*4095) ) / 4095);
/\/\/\/\/\
wie kommst du denn jetzt darauf ??
sollten die -0.5 was mit dem runden zu tun haben, dann müsste es aber
+0.5 heisen und für die obige Formel +2047
Sascha
Sascha Weber schrieb: >>i_Sensorwert = ( ( (i_Sensorwert * 300) - (150*4095) ) / 4095); > /\/\/\/\/\ > wie kommst du denn jetzt darauf ?? hab ausmultipliziert und dann mit dem Nenner erweitert. Das passt schon so. Ich habs jetzt einfach wie geraten zu Lasten der Genauigkeit gemacht: i_Sensorwert = ( ( (i_Sensorwert * 300) - (150*4095) ) / 4095); wird dann zu i_Sensorwert = ( ( (i_Sensorwert * 3) - (150*41) ) / 41); Dann hat auch alles ganz schön in nem int Platz und feddisch...
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.