CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Splitting a 16 bit word into two 8 bit bytes

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








Splitting a 16 bit word into two 8 bit bytes
PostPosted: Thu Dec 21, 2006 9:19 am     Reply with quote

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

View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger

PostPosted: Thu Dec 21, 2006 10:14 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Dec 22, 2006 1:50 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Dec 22, 2006 9:07 am     Reply with quote

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








PostPosted: Fri Dec 22, 2006 10:33 am     Reply with quote

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 Crying or Very sad

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







PostPosted: Fri Dec 22, 2006 10:42 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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