Pergunta

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!

Foi útil?

Solução

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top