Probleme beim shiftleft

OP #2273872
Lesenswert?

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
#2274006
Lesenswert?

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
OP #2274079
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren