3
\$\begingroup\$

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 int_EEPROM_getc(unsigned char address);
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;
    }
}
\$\endgroup\$
7
  • \$\begingroup\$ 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? \$\endgroup\$
    – Rev
    Commented Aug 21, 2014 at 11:49
  • \$\begingroup\$ 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. \$\endgroup\$
    – Rev
    Commented Aug 21, 2014 at 11:52
  • \$\begingroup\$ ya I have checked the lower byte with other values it works fine @Rev1.0 \$\endgroup\$ Commented Aug 21, 2014 at 11:55
  • \$\begingroup\$ 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? \$\endgroup\$
    – Rev
    Commented Aug 21, 2014 at 11:59
  • \$\begingroup\$ I am using a digital oscilloscope for checking the toggling of the portB \$\endgroup\$ Commented Aug 21, 2014 at 12:02

2 Answers 2

3
\$\begingroup\$

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
\$\endgroup\$
1
  • \$\begingroup\$ While this is correct, it does not answer the question why the OPs proposed code isn't working. \$\endgroup\$
    – Rev
    Commented Aug 23, 2014 at 9:48
0
\$\begingroup\$

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)
{
}
\$\endgroup\$
7
  • \$\begingroup\$ I am using MPLAB8.70 and Pic18f45k80. d>>8 is not working, the division operator also not working. \$\endgroup\$ Commented Aug 21, 2014 at 12:12
  • 1
    \$\begingroup\$ d>>8; will not have any effect. It's purely a right-hand value, not assigned to anything. You probably want d=d>>8; \$\endgroup\$
    – Dzarda
    Commented Aug 21, 2014 at 12:13
  • \$\begingroup\$ @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;". \$\endgroup\$ Commented Aug 21, 2014 at 12:46
  • 1
    \$\begingroup\$ @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. \$\endgroup\$
    – Medo42
    Commented Aug 21, 2014 at 13:08
  • \$\begingroup\$ 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) \$\endgroup\$ Commented Aug 21, 2014 at 13:25

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.