Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Microchip C18 - Get LSB and MSB from Int Variable

Status
Not open for further replies.

Techtone

Newbie level 4
Joined
May 25, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
South East England
Activity points
1,359
Hi,

I am using Microchips C18 on a P18F2455.

I am having trouble getting the Least Significant Byte and Most Significant Byte values from and Int variable.

I am trying to logical AND the Int value with 0xFF to get the LSB. For the MSB I am trying to shift right 8 bits.

I guess I would rather directly access the bytes used by C18 to store the Int variable!

I am new to C18 and have always worked in assembly language in the past.

Any suggestion would be greatly appreciated.

Here is the code that is giving me grief:

void writeIntEE(unsigned char address, int data)
{
//LSB
EEADR =(address);
EEDATA = (data && 0xFF); //LSB

//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;

while (EECON1bits.WR)
{
}

//MSB
EEADR =(address+1);
EEDATA =(data >> 8); //MSB

//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;

while (EECON1bits.WR)
{
}

}

Thanks

Tony
 

This is wrong:
EEDATA = (data && 0xFF); //LSB
You should use:
EEDATA = (data & 0xFF); //LSB

& is bit and. && is logic and.
 

    Techtone

    Points: 2
    Helpful Answer Positive Rating
Hi Unaided,

Thanks for your input, I have changed the && for &, things are improved, but still not correct.

Here is what happens, for a given Int, I am getting the following LSB and MSB results:

0x0000 LSB=0xA0 MSB=0x00 Incorrect!
0x00FF LSB=0xA0 MSB=0xFF Incorrect!
0x0020 LSB=0xA0 MSB=0x20 Incorrect!
0xFFFF LSB=0xFF MSB=0xFF Perfect!
0xFEFD LSB=0xFD MSB=oxFE Perfect!
0x0213 LSB=0x13 MSB=0x02 Perfect!
0x0100 LSB=0x00 MSB=0x01 Perfect!

It seems whenever the value in the Int is less than 0x0100, I get a problem, LSB reads 0xA0 and MSB receives the LSB value!

For clarity, here is the current code:

void writeIntEE(unsigned char address, int data)
{
//LSB
EEADR =(address);
EEDATA = (data & 0xFF); //LSB ( I tried (data & 0x00FF) too)

//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;

while (EECON1bits.WR)
{
}

//MSB
EEADR =(address+1);
EEDATA =(data >> 8); //MSB

//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;

while (EECON1bits.WR)
{
}

}

Further suggestions would be gratfully appreciated.

Thanks

Tony
 

Possibly a type conversion is taking place as EEDATA is 8 bit and you are manipulating an int.

Try EEDATA = (data & 0xFF00) >> 8;

for the high byte. You could also try a casting data as an int but try the above first. I use a different compiler so I'm afraid I can't check for you.

Brian.
 

    Techtone

    Points: 2
    Helpful Answer Positive Rating
Hi betwixt (and I really am now :^o ),

I tried your suggestion, however the results were the same.

I found this thread:

Then I created these two routines:

unsigned char getLSB(int data)
{
return data & 0xFF;
}
unsigned char getMSB(int data)
{
return data / 256u;
}


After confirming the results from getLSB and getMSB were correct, I called the routines from within my writeIntEE code:

void writeIntEE(unsigned char address, int data)
{
//LSB

EEADR =(address);
EEDATA = getLSB(data); //LSB

//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;

while (EECON1bits.WR)
{
}

//MSB
EEADR =(address+1);
EEDATA = getMSB(data); //MSB

//Configuration as per manual
EECON1bits.EEPGD =0;
EECON1bits.CFGS =0;
EECON1bits.WREN =1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;

while (EECON1bits.WR)
{
}

}


The same problem persisted@*x!

So... My solution is to pass both the LSB and MSB values as unsigned char to writeIntEE:

void writeIntEE(unsigned char address, unsigned char dataLSB, unsigned char dataMSB)
{
//LSB

EEADR =(address);
EEDATA = dataLSB; //LSB

.....

//MSB
EEADR =(address+1);
EEDATA = dataMSB; //MSB

......
}


Then I call the writeIntEE like this:

writeIntEE(2, getLSB(0x0036), getMSB(0x0036));

No more problem! WT*?

I don't understand what the problem was, but this workaround works for me :eek:)

As a C18 newbie and assembler veteran, I have been amazed by C18, it only took 3 or 4 days to get PC1602 2x16 line LCD working, Timer driven interrupts up and running, 3 channels of ADC reading in under interrupt control, interrupt driven button debounce,

Then along comes a problem like this, chews up nearly a day!

Thank you betwixt and unaided for your assistance, I have clicked both your 'Helped Me' buttons.

Kind regards

Tony

'We can sell our time, but we can't buy it back..'
 

Sometimes life's like that, no matter what you try it never seems to follow the rules.
I'm glad it's working now. Thanks for the 'helped me' points - with all the ones I've accumulated since joining here I can probably download the whole internet!

Brian.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top