# MPLABX : How to Read/Write 4 bytes unsigned integer to EEPROM?

My question looks simple but still I lost my way to get the issue resolved. Discussion might show me the way.

I am using Pic16f877A microcontroller to write EEPROM using I2C ( 1 Byte at a time ). I need to write 4Bytes integer value (lets say 4284967295 ~ 0xFF67697F). I want to write this value to the EEPROM and Read this value from EEPROM whenever needed. I am unable to find best possible ways to write/read this value.

I tried approaching following way :

unsigned int a = 4284967295;
unsigned int result1, result2, result3, result4;
result1 = (( a & 0x000000FF ) ); \\ result1 = 127
result2 = (( a & 0x0000FF00 ) ); \\ result2 = 26880
result3 = (( a & 0x00FF0000 ) ); \\ result3 = 6750208
result4 = (( a & 0xFF000000 ) ); \\ result4 = 4278190080


but lost the way. And reference, link, and your guidance will be appreciated.

• The relevant product's datasheet contains valuable example code: ww1.microchip.com/downloads/en/DeviceDoc/39582C.pdf (page 35). If something's unclear, ask what specifically. EDIT: Ah, I misunderstood the question. Luckily two quick answerers already solved the problem for you. – Linards Sep 21 '15 at 6:44

One problem is that you're not shifting the bits along as you read them into the result and also depending on the compiler an unsigned int might not be large enough for a 32-bit value. The following code is from a non-Microchip project but should show you one idea. Using the stdint.h header in your projects is generally a good idea because you can easily see the size of the data types and not rely on compiler dependant sizes.

#include <stdint.h>

{
write_eeprom(addr + 1, data >> 8 & 0xFF);
write_eeprom(addr + 2, data >> 16 & 0xFF);
write_eeprom(addr + 3, data >> 24 & 0xFF);
}

{
uint32_t result;

result <<= 8;
result <<= 8;
result <<= 8;
return result;
}

• For my solution with CodeVisionAVR, it works using [&0xFF] after ALL shifting (data&0xFF, data>>8&0xFF, data>>16&0xFF, and data>>24&0xFF) – Oka Sep 21 '15 at 7:12
• That code came from a project where the value was an 8-bit so it would be truncated, but thanks it was worth updating to make it more generic because that's not guaranteed behavior between compilers and libraries. – PeterJ Sep 21 '15 at 7:25

One simple solution is to use a union to redefine your unsigned long to 4 bytes (note that your unsigned int is only 2 bytes in XC8):

union
{
uint32_t      uNumber;  // exactly 4 bytes, no larger
unsigned char uByte[4];
} myUnion;

// write to eeprom ...
myUnion.uNumber = 4284967295;
for (unsigned char i = 0; i < 4; ++i)
{
// write myUnion.uByte[i] to eeprom here
}

for (unsigned char i = 0; i < 4; ++i)
{
// read myUnion.uByte[i] from eeprom here
}

unsigned long int a = 4284967295;

unsigned char result[4];

result[0]=a;

result[1]=a>>8;

result[2]=a>>16;

result[3]=a>>24;

j=0;