Casting integer to character

I am using PIC18f microcontroller. I have to write a 16 bit integer variables (2 bytes) which was cast into two character variable i.e to write each byte in a consecutive adrressess of EEPROM. By first I have to write a upper byte(8bit data) in the EEPROM. I am unable to get the higher 8 bit of the integer variable by the following code (where I am able to write the lower eight bit of the integer variable ). My code is

void int_EEPROM_putc(unsigned char address, unsigned char data);
unsigned char c;
unsigned int d;
unsigned char* e;
unsigned char f;

void main()
{
d=0xffff;
e=(unsigned char*)&d;
//f=*e
f=*(e+1);
int_EEPROM_putc(0x02,f);
delay_ms(100);
c=int_EEPROM_getc(0x02);
while(true)
{
if(c==255)
{
PORTB=~PORTB;
}
else
{
PORTB=0xff;
}
}

• Even if you seem to over complicate things, the pointer arithmetic looks correct at a first glance. You expect c to be 0xFF, but it isn't? – Rev1.0 Aug 21 '14 at 11:49
• And are you sure your EEPROM routines are working at all? How did you verify that with the lower byte? Remember that default EEPROM content is 0xFF, I would use some initial value like d=0xAABB; to differentiate the values. – Rev1.0 Aug 21 '14 at 11:52
• ya I have checked the lower byte with other values it works fine @Rev1.0 – KATHIR kamu Aug 21 '14 at 11:55
• What do you have connected to PORTB? LEDs? Since you just toggle that PORT continuously without any delay, you may not be able to see the flickering. Can you use a programmer to read out the EEPROM contents? – Rev1.0 Aug 21 '14 at 11:59
• I am using a digital oscilloscope for checking the toggling of the portB – KATHIR kamu Aug 21 '14 at 12:02

The most general approach for extracting pieces of an integer value is to shift and mask. So:

d = whatever;
c = d & 0xff; // extract low 8 bits
c = (d >> 8) & 0xff; // extract next 8 bits


If, as here, you know that the value in d is 16 bits, you can make the code for the next 8 bits a little simpler by writing

c = d >> 8; // extract high 8 bits of 16-bit value

• While this is correct, it does not answer the question why the OPs proposed code isn't working. – Rev1.0 Aug 23 '14 at 9:48

Generally... it's not terrific practice to assume any bit size or "endian-ness" for any int, for portability reasons. Depending upon the processor and the compiler, and int may be anything from 8-bit to 64-bit, or even some other odd size, and may be stored in either little-endian or big-endian format.

What happens if you do either of these two?

if(d==255)
{
}

// or

int d = 0xffff;
d >> 8;
char c = d;
if (c==255)
{
}

• I am using MPLAB8.70 and Pic18f45k80. d>>8 is not working, the division operator also not working. – KATHIR kamu Aug 21 '14 at 12:12
• d>>8; will not have any effect. It's purely a right-hand value, not assigned to anything. You probably want d=d>>8; – Dzarda Aug 21 '14 at 12:13
• @Dzarda - good catch; I dropped a character. It SHOULD have been "d>>=8;". Depending upon the compiler, that's often cheaper (in terms of CPU cycles) than "d=d>>8;". – TDHofstetter Aug 21 '14 at 12:46
• @TDHofstetter, do you have an actual example of such a compiler? I'd consider it very weird if d >>= 8; and d = d >> 8; compiled to different code. – Medo42 Aug 21 '14 at 13:08
• I don't have a specific compiler in mind at the moment, but I do know that some compilers will perform a d>>=8 in-place, shifting the value within the register, while other compilers will shift the value, rewrite the variable into memory, then reread that memory and rewrite it with the same value. Given some little time, I could probably show you three or four compile-to-assembly examples from real-world compilers. I've been optimizing code for a very long time... 8) – TDHofstetter Aug 21 '14 at 13:25