|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
Splitting a 16 bit word into two 8 bit bytes |
Posted: Thu Dec 21, 2006 9:19 am |
|
|
Hi,
I need to write a 16 bit variable to the internal EEPROM. I know that I can use the Make16 function to recombine two 8 bit bytes into one 16 bit word, but I can't find a reverse function. How do I split the 16 bit word into two 8 bit bytes?
Thanks
Augie |
|
|
jamesjl
Joined: 22 Sep 2003 Posts: 52 Location: UK
|
|
Posted: Thu Dec 21, 2006 10:14 am |
|
|
The answer is to use make8(); This is from the manual:
Code: |
int32 x;
int y;
y = make8(x,3); // Gets MSB of x
|
|
|
|
davekelly
Joined: 04 Oct 2006 Posts: 53 Location: Berkshire, England
|
|
Posted: Fri Dec 22, 2006 1:50 am |
|
|
I use the following style, which can be expanded to accomodate 32 bit numbers as well
Code: |
/////////////////////////////////////////////////////////////////////////
/// Write the specified byte to the EEPROM. Check if the data needs changing
/// first to avoid unnecessary saves.
/////////////////////////////////////////////////////////////////////////
void WriteEEPROM (int8 addr, int8 data)
{
if (read_eeprom (addr) != data)
{
write_eeprom (addr, data);
}
}
void WriteEEPROM16 (int8 addr, int16 data)
{
int8 * currentByte;
currentByte = &data;
WriteEEPROM (addr++, *currentByte++);
WriteEEPROM (addr++, *currentByte++);
} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Dec 22, 2006 9:07 am |
|
|
Davekelly,
Your code can be optimized. Working with pointers (16 bit) is not very efficient in a 8 bit PIC processor, also the increments in the last line of WriteEEPROM16 have no purpose.
Here an optimized version (now 34 bytes, was 84 bytes in the original)
Code: | void WriteEEPROM16_optimized(int8 addr, int16 data)
{
WriteEEPROM(addr++, make8(data,1));
WriteEEPROM(addr, make8(data,0));
} |
|
|
|
Guest
|
|
Posted: Fri Dec 22, 2006 10:33 am |
|
|
Hi All,
OK, getting back to my original question, I seem to be having a problem with make8 and make 16. The problem is that these functions don't seem to work correctly in both directions. In other words if I use make8 to "de-contruct" a 16 bit word, and then use make 16 to "reconstruct" the I don't end up with the same value
Code: |
int16 VoltsScaleFactor;
int8 Byte0, Byte1;
VoltsScaleFactor = 26475;
printf("Original VoltsScaleFactor: %lu\n\r", VoltsScaleFactor);
Byte0 = make8(VoltsScaleFactor, 0);
Byte1 = make8(VoltsScaleFactor, 1);
VoltsScaleFactor = make16(Byte0, Byte1);
printf("Contructed VoltsScaleFactor: %lu\n\r", VoltsScaleFactor);
|
When I run this code I see:
Original VoltsScaleFactor: 26475
Contructed VoltsScaleFactor: 27495
As you can see, the original and the re-constructed values are different.
What is going on??
Compiler is 3.249
Augie |
|
|
Ttelmah Guest
|
|
Posted: Fri Dec 22, 2006 10:42 am |
|
|
You have byte 0, and byte 1, the wrong way round when you reconstruct the word...
The high byte comes first in make16.
A an 'aside', I prefer the use of a union, to the make8/mae16 functions, since this is portable C to other compilers, and also makes it much easier to keep the bytes in the right order. There is no need to actually have seperate variables at all with this:
Code: |
union joiner {
int8 b[2]
int16 w;
} VoltScaleFactor;
//Then
VoltScaleFactor.w=26475;
printf("Original VoltsScaleFactor: %lu\n\r", VoltScaleFactor.w);
printf("Byte 0 is :%u Byte 1 is: %u\n\r",VoltScaleFactor.b[0],VoltScaleFactor.b[1]);
|
You can read/write the bytes/word, at will.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|