Hallo Forum, ich hab mal wieder eine Frage, und zwar spreche ich einen Flashspeicher mit einem MSP430 an. Der Speicher hat Adressen mit einer Länge von 3Bytes. Über UART bekomme ich von extern Leseanfragen mit den Adressen die der MSP lesen soll. Also bekomme ich ja die Adressen als 3 einzelne Bytes. Im C-Code brauch ich die Adresse aber als eine Variable(nicht 3). Wollte sie durch shift left zusammenbauen, also etwa so: adresse = (add[1] *65536) | (add[2]*256) | add[3]; adresse ist eine unsigned long int, und ich erwarte nach dem shiften sowas wie 0x00FFFFFF. Allerdings bekomm ich falsche Adressen raus, sobald add[2] größer als 0x79 ist. add[1] und 3 allerdings können ohne Probleme 0xFF sein. drei Beispiele: adresse = (0x00 *65536) | (0x79*256) | 0x00; -->adresse = 0x00007900 <--Richtig adresse = (0x00 *65536) | (0x80*256) | 0x00; --> adresse = 0xFFFF8000 <--Falsch adresse = (0xff *65536) | (0x79*256) | 0xff; --> adresse = 0x00FF79FF <--Richtig wo genau liegt denn hier das Problem, und wie kann ich das umgehen? mfG
0x79 * 256 = 127 * 256 = 32512 0x80 * 256 = -128 * 256 = -32768 bob blob schrieb: > wie kann ich das umgehen? Datentypen auf 32Bit erweitern. (Cast der Variablen oder L an die Konstanten)
danke Dir, aber warum macht das hier in dem Beispiel bei add[1] nichts aus, es ist ja höherwertiger als add[2]? Kann ich bei einem 16bit Controller denn die datentypen überhaupt auf 32 bit erweitern?
bob blob schrieb: > danke Dir, aber warum macht das hier in dem Beispiel bei add[1] nichts > aus, es ist ja höherwertiger als add[2]? Weil 65536 nicht in "int" passt und daher ein "long" ist. > Kann ich bei einem 16bit Controller denn die datentypen überhaupt auf 32 > bit erweitern? Ja.
Ja im Array stehen noch andere, nicht für das Problem relevante, Sachen. Z.B. auch in add[0] ;) Wie genau kann ich denn eine 32bit Variable erstellen? Ich benutze die IAR Embedded Workbench IDE.
Ouh, vielen dank ... . BTW eine unsigned int long ist doch 4Byte, also 32 bit
bob blob schrieb: > Ouh, vielen dank ... . > BTW eine unsigned int long ist doch 4Byte, also 32 bit Das Ergebnis, aber nicht die Zwischenschritte, die werden mindestens in 'int' ausgeführt. Zusammenfassung: low-Byte -> alles in 'int' umgewandelt -> kein Problem, da wird ja nichts gerechnet, deshalb interessierts nicht weiter wenn 0x80 eigentlich -128 ist mid-Byte -> alles in 'int' umgewandelt -> ab 0x80 wirds negativ, weil der Compiler das Byte als -128 ansieht high-Byte -> alles in 'int' umwandeln geht nicht, da 65536 schon 'long' ist _->_ 256L sollte das Problem beheben
Dankeschön, die Erklärung leuchtet ein. Aber entweder haperts gerade an der Syntax, oder ich muss dafür noch einen zusätzlichen Header einbinden.
Ok, das mit dem "_->_ 256L" hat ich ja so meine Probleme ;) Aber mit der Erklärung, dass die Zwischenschritte in int und nicht long int gemacht werden, konnte ich das Problem scheinbar anderweitig lösen. unsigned int msb = 0xff; unsigned int mid = 0xee; unsigned int lsb = 0xdd; unsigned long int adresse; mid = mid*256 | lsb; startadresse = msb*65536 | mid; --> adresse = 0x00FFEEDD somit wird das mittlere Byte nicht über die Grenzen des ints verschoben.
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.