Reputation: 1233
How do you properly convert 4 byes into one unsigned long variable ?
I am programming PIC18 on MPLAB C18 and this is my code.
unsigned long theseconds = 0x00;
BYTE timeToSave[4];
timeToSave[0] = 0xFF;
timeToSave[1] = 0xFF;
timeToSave[2] = 0x01;
timeToSave[3] = 0x01;
theseconds = timeToSave[0] & 0xFF;
theseconds |= (timeToSave[1] << 8) & 0xFFFF;
theseconds |= (timeToSave[2] << 16) & 0xFFFFFF;
theseconds |= (timeToSave[3] << 24) & 0xFFFFFFFF;
printf("\r\nSeconds:%lu",theseconds);
This is the output I keep getting, Seconds:255
Thanks!
Upvotes: 1
Views: 481
Reputation: 82307
This should work
unsigned long theseconds = 0x00;
BYTE timeToSave[4];
timeToSave[0] = 0xFF;
timeToSave[1] = 0xFF;
timeToSave[2] = 0x01;
timeToSave[3] = 0x01;
theseconds = timeToSave[3];
theseconds <<= 8;
theseconds |= timeToSave[2];
theseconds <<= 8;
theseconds |= timeToSave[1];
theseconds <<= 8;
theseconds |= timeToSave[0];
printf("\r\nSeconds:%lu",theseconds);
Your code fails with two reasons.
I suppose int
is 16bit, therefore the shift of 16 or 24 will result to 0, as the the rule in ANSI-C is that the BYTE
of timeToSave[x]
(in reallity an unsigned char) should be expanded to an int.
Obviously shifting a 16bit value more than 15 times will also result to 0.
But why do you get 255 not 65535?
I suppose the compiler isn't ANSI compliant and will not expand your unsigned char in a proper way.
To get your code working, it should be enough to cast each line.
theseconds = timeToSave[0];
theseconds |= ((unsigned long)timeToSave[1] << 8);
theseconds |= ((unsigned long)timeToSave[2] << 16);
theseconds |= ((unsigned long)timeToSave[3] << 24);
The &
mask is nonsens as the value can't be outside of the range
Upvotes: 3