I am writing data to eeprom AT24C16 using PIC microcontroller pic18f4520. Every address of this eeprom can hold 8-bits while I am using long int's to store data that are 16-bit in size. How to break long int into 2 8-bit parts to write them and how to get them back together after reading from eeprom??

  • \$\begingroup\$ Write the first 8 bits first, then the second 8 bits? Or are you asking for actual code to be written for you? \$\endgroup\$
    – PlasmaHH
    Jun 30, 2015 at 13:20
  • \$\begingroup\$ Are you sure a long int is only 16 bits? \$\endgroup\$
    – JimmyB
    Jun 30, 2015 at 13:37
  • \$\begingroup\$ @HannoBinder He said that he was using a long int to store 16 bits of data. He could be not using the other 16 bits and still be 100% correct in his statement. Inefficient, sure, but still correct... \$\endgroup\$ Jun 30, 2015 at 17:39

3 Answers 3


In C, you can use bit-shift and masking to extract each byte of a longer number:

lower_8bits = value & 0xff;
upper_8bits = (value >> 8) & 0xff;

And you can 'reassemble' the number from bytes by doing the reverse:

value = (upper_8bits << 8) | lower_8bits;
  • \$\begingroup\$ I was tempted to start gibbering about unions, but this isn't the moment, is it? ;-) \$\endgroup\$
    – Asmyldof
    Jun 30, 2015 at 13:37
  • 1
    \$\begingroup\$ @Asmyldof It's tempting, but a good compiler will optimise bit shifting snippets to just a read of the relevant byte, without requiring you to worry about endianness. \$\endgroup\$ Jun 30, 2015 at 13:38
  • \$\begingroup\$ I know, but unions are awesomesauce :-D \$\endgroup\$
    – Asmyldof
    Jun 30, 2015 at 13:42
  • \$\begingroup\$ Some compilers are stupid enough to actually shift-by-8 and [OR/AND], exactly as stated in the source code, even on an 8-bit chip with all optimizations turned on. I've used unions and pointer notation to get around this, depending on how often I need to access each variable that way. \$\endgroup\$
    – AaronD
    Jun 30, 2015 at 19:03
long int my16bitdata = 0xEA51;

int MSB, LSB;

MSB = (my16bitdata>>8) & 0xFF;
LSB = my16bitdata & 0xFF;

In this case the outcome would be:

MSB = 0xEA


LSB = 0x51 


By perfoming a bit shift(>>) operation on the 16 bit value, we can slide the upper bits down to the lower section. All 8 of them. We then do a bitwise AND (&) with a 0xFF to apply that value to the 8 bits available in the 'int'.

For the lower 8 bits (LSB), no bit shift is required so we can just do the bitwise AND to get the data we need.


A higher level approach that lets the compiler do the shifting would look like this:

typedef union Int16
  int data;
    unsigned char lsb;
    unsigned char msb;
  }bytes __attribute__ ((packed));
}Int16 __attribute__ ((packed));
#define MSB bytes.msb    
#define LSB bytes.lsb    

Int16 myInt;
unsigned char msb, lsb;

myInt.data = 0x1234;
msb = myInt.MSB;
lsb = myInt.LSB;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.