Da ich in den Anleitungen zu IAR und dem dazugehörigen C-Compiler nur wenig zur Multiplikation mit Gleitkommazahlen gefunden habe bzw. auch nicht alles verstanden habe, muss ich mal die Experten fragen. Folgendes Problem: Nach einer A/D Wandlung steht im ADC12MEM0 Register eine 16(12) Bit zahl. a) Diese Zahl soll mit z.B. mit 3,76 multipliziert werden, dann gerundet (damit wieder ein ganzzahliger Wert entsteht) und dann byteweise parallel an z. B. an P4 ausgegeben werden. b) Wie kann man den vor der Rundung entstandenen Gleitkommawert byteweise parallel an P4 ausgeben ? Hat jemand zu meinen Problemen evtl. Programmschnipsel (vorzugsweise in `C und mit viel Kommentar) ? MfG Wolfgang
Sowas rechnet man nur dann mit Fliesskomma-Arithmetik, wenn man unbedingt das Flash mit der entsprechenden Library vollkriegen will. Ansonsten mit 376 multiplizieren, durch 100 dividieren und abhängig vom Rest runden. Das 32bit Zwischenergebnis auszugeben sollte kein Problem sein.
Vor der Division nicht vergessen 50 zu addieren und die Division rundet automatisch richtig.
Noch schneller und codesparender ist: (X * 963 + 128) / 256 Peter
Dank an alle. Leider bin ich noch nicht viel schlauer geworden, da meine Programmierkenntnisse noch zu unvollkommen sind. @ A.K. , wenn ich x*376/ 100 rechne, kommt bei mir wieder eine Gleitkommazahl heraus, die ich, ohne auf einen ganzahligen Wert zu runden, m.E. nicht an P4 ausgeben kann. Wo mache ich einen Denkfehler? Wie kann ich runden ? gibt es eine Funktion dazu? <Das 32bit Zwischenergebnis auszugeben sollte kein Problem sein.> für mich ist es ein Problem, sonst würde ich nicht danach fragen. wie wird z.B. das Komma ausgegeben? Oder wie muss ich mir das vorstellen? @ Peter, wie kommt man auf die von Dir vorgeschlagenen Zahlen? < Noch schneller und codesparender ist:> für mich nicht so wichtig, da ich noch nicht mal die langsamen Methoden kenne. Vielleicht hat doch jemand ein Programmschnipsel mit Erläuterungen MfG Wolfgang
Kleine Tips: 963 = 256 * 3,76 128 = 256 * 0,5 Multiplikation mit Zweierpotenzen ist einfach und schnell durch Schiebebefehle zu realisieren.
"wenn ich x*376/ 100 rechne, kommt bei mir wieder eine Gleitkommazahl heraus" Nur wenn Du den Taschenrechner nimmst. Nicht wenn Du das den Micocontroller in ganzzahliger Rechung machen lässt. Aber Peter hat hatürlich recht, durch 2er-Potenz zu dividieren ist noch simpler. 376/100 = 963/256. Und die Rundung ergibt sich, indem vorher die Hälfte noch drauf addiert und bei der ganzzahligen Division (bzw. der Schiebeoperation) abgeschnitten, d.h. der Rest ignoriert wird.
Nun hab ich es begriffen. Aber jetzt tritt ein neues Problem auf: Wenn ich mit dem µC rechne U1= ADC12MEM0*963; U2 = U1+128; U3=U2 >> 8; // Division / 256 wobei die Variablen U1,U2,U3 als unsigned long deklariert worden, wird das obere Byte vom 16Bit Endergebnis zu Null. Kann es sein, dass die Demoversion von IAR Kickstart V.2.21B mit dem Compiler V 2.21.2.2 unsigned long (32Bit) nicht kennt? Muß noch eine *.h-Datei einbezogen werden ? Was mache ich falsch? MfG Wolfgang
Habe das selbe Problem auch mit meinem IAR Compiler (Renesas H8). Möchte einen Wert von 90000 in eine unsigned Long Variable schreiben, aber es wird nur 33464 angenommen. Bei einem älteren Projekt konnte ich das Problem mit einer erzwungenen Typenumwandlung: - (unsigned long)U2 = (unsigned long)U1+128 beheben können. Bei meinem erneuten Problem komme ich aber auch damit nicht weiter. Hoffe Dir damit geholfen zu haben und wäre sehr froh, wenn jemand ein Typ hat für mein aktuelles Problem. Danke
. "Möchte einen Wert von 90000 in eine unsigned Long Variable schreiben, aber es wird nur 33464." Ist sizeof (long) == 4? Wenn ja, dann hilft das hintanstellen eines großen 'L' an die Konstante: unsigned long wert = 90000L; Die Konstante ist sonst nämlich eine int-Konstante ...
Danke für Deine rasche Antwort! Der Wert 90000 ist leider keine Konstante, sondern eine Variable, welche im Programm verändert wird. Die Funktion sizeof liefert mir auch den korrekten Wert 4. Habe ein kleines Testprogramm geschrieben in dem alles problemlos läuft. Es liegt also nicht grundsätzlich am IAR Compiler. Für einen weiteren Typ bin ich sehr dankbar.
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.