How to extract byte from word?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks,
Sujith

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
/* Type defines */typedef long DWORD;typedef int WORD;typedef char BYTE;typedef unsigned long UDWORD;typedef unsigned int UWORD;typedef unsigned char UBYTE;typedef DWORD INT32;typedef WORD INT16;typedef BYTE INT8;typedef UDWORD UINT32;typedef UWORD UINT16;typedef UBYTE UINT8;typedef BYTE BOOLEAN;typedef WORD STACK;/************************************************************************ Useful Macros Section ***********************************************************************//* Returns the low byte of the word */#define LOBYTE(w) ((BYTE)(w))/* Returns the high byte of the word */#define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))/* Makes a word from \a low byte and \a high byte. */#define MAKEWORD(low, high) ((WORD)(((BYTE)(low)) | (((WORD)((BYTE)(high))) << 8)))/* Returns the low word of the double word */#define LOWORD(l) ((UINT16)(UINT32)(l))/* Returns the high word of the double word */#define HIWORD(l) ((UINT16)((((UINT32)(l)) >> 16) & 0xFFFF))/* Returns the low signed word of the double word */#define LOSWORD(l) ((WORD)(DWORD)(l))/* Returns the high signed word of the double word */#define HISWORD(l) ((WORD)((((DWORD)(l)) >> 16) & 0xFFFF))/* Makes a double word from low word and a high word. */#define MAKELONG(low, high) ((UINT32)(((UINT16)(low)) | (((UINT32)((UINT16)(high))) << 16)))
Example use with c code

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is not recommended - especially if portability is required - as the order in which will the bytes will be arranged depends on the compiler. It is safer to use masks and shifts as suggested above.
Anders wrote:I'm just wondering, wouldn't it be more efficient to use a union between a word and a struct of two bytes?

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You do have a good point with the struct though. A person could generate code usign differant methods and inspect the code to see which method is optimized the best.
Just a thought...

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sujith
There are two ways. The portable and non-portable way.
******************* Non-portable ********************
unsigned char *ptr = &usWord;
send-routine(*ptr++);
send-routine(*ptr);
*****************************************************
This works but the order of the bytes is 'endian' dependent. Big-endian (like HC12) or little-endia (like 80186).
If usWord is 0x1234, the data sent will be 0x12, 0x34 when big-endian or 0x34, 0x12 when little endian.
Generally network ordering (as used by Internet etc.) corresponds to the big-endian ordering.
******************* portable ************************
send-routine((unsigned char)(usWord>>8));
send-routine((unsigned char)(usWord));
*****************************************************
The portable version will give the same results as the non-portable when using the HC12. The portable case also specifically sends in network order.
Regards
Mark Butcher
www.mjbc.ch / www.uTasker.com

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
/* If the word has hex value 1234 then */
/*-------------------------------------------/*
unsigned short usWord=0x1234;
/*-------------------------------------------*/
/* To get the upper char ,just And with 0xF0 */
/* and shift right 8 places.result is 0x12 */
/*-------------------------------------------*/
unsigned char upper = (unsigned char)((usWord & 0xF0) >> 8);
/*-------------------------------------------*/
/* To get the lower char ,just And with 0xF */
/* thats it...result is 0x34 */
/*-------------------------------------------*/
unsigned char lower = (unsigned char)(usWord & 0x0F);

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Careful with the logical arithmetic.
You need to AND with 0xff00 and 0x00ff and not 0xf0 resp. 0x0f.
However the AND operations are also superfluous since the casting to unsigned char chops the 16 bit word to 8 bits and so it really doesn't matter whether the other bits have been set to zero or not.
Regards
Mark

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
