Searching \ for '[PIC]: How to split a 16bit into two (2) 8bits' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'How to split a 16bit into two (2) 8bits'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: How to split a 16bit into two (2) 8bits'
2003\04\26@122419 by Mccauley, Daniel H

flavicon
face
I have a few 16 bit variables i would like to split into two 8-bit numbers
which I will then write to an I2C EEPROM device (24xx00 EEPROM).
Any suggestions on what the best way to do this is???

Thanks
Dan

--
http://www.piclist.com hint: To leave the PICList
spam_OUTpiclist-unsubscribe-requestTakeThisOuTspammitvma.mit.edu>

2003\04\26@123947 by Mccauley, Daniel H

flavicon
face
Actually, just found the answer I was looking for:

CCS C has two commands:

MAKE8()
MAKE16()

That will definilty do it!

Dan



{Quote hidden}

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestspamKILLspammitvma.mit.edu>

2003\04\26@125023 by Ned Konz

flavicon
face
On Saturday 26 April 2003 08:33 am, Mccauley, Daniel H wrote:
> I have a few 16 bit variables i would like to split into two 8-bit
> numbers which I will then write to an I2C EEPROM device (24xx00
> EEPROM). Any suggestions on what the best way to do this is???

Assuming that:
* you're using C
* you've already typedef'd uint8 and uint16 to be 8 bit and 16 bit
ints

then this is the cleanest way to do it (and generates the best code in
most 8 bit C compilers):

union { uint16 w; uint8 b[2] } u;
u.w = my16BitNumber;
writeByte(u.b[0]);
writeByte(u.b[1]);

--
Ned Konz
http://bike-nomad.com
GPG key ID: BEEA7EFE

--
http://www.piclist.com hint: To leave the PICList
.....piclist-unsubscribe-requestKILLspamspam.....mitvma.mit.edu>

2003\04\26@132337 by Tal

flavicon
face
This solution is efficient but note that it is based on some hidden
assumptions about the compiler implementation details such as the data
representation used by the compiler (little endian vs. big endian vs.
something else, no padding between byte array elements, etc).

If you want something more general and portable, you can use C operators
such as

  write((uint8)(N >> 8));      // write high byte
  write((uint8)(N & (0xff)));  // write low byte

If the compiler is smart enough (and some of them are), it should be
able to figure out that this is simply byte addressing that requires no
extra overhead.

Tal

> {Original Message removed}

2003\04\26@134123 by Ned Konz

flavicon
face
On Saturday 26 April 2003 10:22 am, Tal wrote:
> This solution is efficient but note that it is based on some hidden
> assumptions about the compiler implementation details such as the
> data representation used by the compiler (little endian vs. big
> endian vs. something else, no padding between byte array elements,
> etc).

I wasn't aware that the C standard allowed padding between consecutive
byte array elements. Which section allows that?

The endianness of the given compiler is likely to remain constant. But
I agree; you'd normally put this into a macro and use a #define for
the endianness:

#define LS_BYTE 0
#define MS_BYTE 1

union { uint16 w; uint8 b[2] } u;
u.w = my16BitNumber;
writeByte(u.b[ LS_BYTE ]);
writeByte(u.b[ MS_BYTE ]);

--
Ned Konz
http://bike-nomad.com
GPG key ID: BEEA7EFE

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspam_OUTspamTakeThisOuTmitvma.mit.edu>

2003\04\26@135203 by Tal

flavicon
face
And your compiler does not have it, try to define something like

#def BYTE1(n)  ((uint8)((n)      ))   // low  byte
#def BYTE2(n)  ((uint8)((n) >>  8))   // high byte

Tal


> {Original Message removed}

2003\04\26@155535 by Tal

flavicon
face
Hi Dan

>
> I wasn't aware that the C standard allowed padding between
> consecutive byte array elements. Which section allows that?

Good question. The standard do allow padding in some integer values:

"For unsigned integer types other than unsigned char, the bits of the
object
representation shall be divided into two groups: value bits and padding
bits (there need
not be any of the latter)." from
http://std.dkuug.dk/jtc1/sc22/open/n2794/n2794.pdf

Which means for example that a 16 bit value may occupy by more than 16
bits. This is probably to address architectures that have addressing and
alignment restrictions.

I posted a question in comp.lang.c. Let's see what the C 'lawyers' say.

Tal


> {Original Message removed}

2003\04\26@160135 by Tal

flavicon
face
Oops, it should be Ned, not Dan.

Tal

{Quote hidden}

--
http://www.piclist.com hint: To leave the PICList
spamBeGonepiclist-unsubscribe-requestspamBeGonespammitvma.mit.edu>

2003\04\26@160625 by Ned Konz

flavicon
face
On Saturday 26 April 2003 12:54 pm, Tal wrote:
> Hi Dan
>
> > I wasn't aware that the C standard allowed padding between
> > consecutive byte array elements. Which section allows that?
>
> Good question. The standard do allow padding in some integer
> values:
>
> "For unsigned integer types other than unsigned char, the bits of
> the object
> representation shall be divided into two groups: value bits and
> padding bits (there need
> not be any of the latter)." from
> http://std.dkuug.dk/jtc1/sc22/open/n2794/n2794.pdf
>
> Which means for example that a 16 bit value may occupy by more than
> 16 bits. This is probably to address architectures that have
> addressing and alignment restrictions.

Yes, of course. But this *is* an array of unsigned char,
so the standard doesn't allow padding between u.b[0] and u.b[1].

Which is why I asked.
A lot of C code would break if there were padding
between consecutive bytes in byte arrays!

> > {Original Message removed}

2003\04\26@162417 by Sid Weaver
picon face
Ned, how do you do this in PBasic?


Sid Weaver
W4EKQ
Port Richey, FL

--
http://www.piclist.com hint: To leave the PICList
TakeThisOuTpiclist-unsubscribe-requestEraseMEspamspam_OUTmitvma.mit.edu>

2003\04\26@163039 by Ned Konz

flavicon
face
On Saturday 26 April 2003 01:23 pm, Sid Weaver wrote:
> Ned, how do you do this in PBasic?

I don't know. I've never used pbasic. Though if there's any kind of
way to get addresses you should be able to do it.

--
Ned Konz
http://bike-nomad.com
GPG key ID: BEEA7EFE

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestspamTakeThisOuTmitvma.mit.edu>

2003\04\26@165421 by Sid Weaver

picon face
Ned, if you responded to my question, when I opened your-mail it said:

<<<<No message collected>>>>


Sid Weaver
W4EKQ
Port Richey, FL

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestEraseMEspam.....mitvma.mit.edu>

2003\04\26@193944 by Tal

flavicon
face
First check if Pbasic alreay has built in functions for such conversion.
If not, you can use a numeric based approach.

Something similar to:


 high_byte = (word16 / 256)
 low_byte  = word16 - (low_byte * 256)

I don't know Pbasic so you may need to modify the above code.

Tal

> {Original Message removed}

2003\04\26@193952 by Tal

flavicon
face
Ned,

Looks like the code is not 100 ANSI C safe but not because of byte array
padding as I stated earlier.

Including below is a reply from Jack Klein (http://JK-Technology.Com).
According to him, the standard does not guaranty that you will get
either high or low 8 bits and you can get an arbitrary set of 8 bits.
That is, the standard does not restrict compilers to use either little
of big endian and allows arbitrary order of value bits in memory.

Also (now we switch to my interpretation), as he hints, the standard
allows 16 bit values to be represented in memory using extra padding
bits. In this case, it may also not guaranteed that u.b[0] will have 8
value bits of u.n as it can include few puddings bits of u.n.

Bottom line, the union base conversion is not 100% ANSI C safe though it
is very likely to work with most commercial compilers assuming you take
care of the endian issue.

Tal




========================================================================
=================

> Hello,
>
> Assuming that uin8 and uin16 are defined properly by the user to
> represent 8 and 16 bit unsigned integers respectively,  and
> considering the following definition:

...and assuming that the implementation provides 8 and 16 bit integers
at all...

BTW, the header <stdint.h> which is part of the current (1999) C
standard, provides standard type definitions uint8_t and uint16_t for
compilers that provide these types.

{Quote hidden}

Given that there is no room for padding in a 16 bit int, when you
overlay an array of two 8-bit unsigned chars on one, one of the
unsigned chars must contain 8 of the 16 bits, and the other must
contain the other 8 bits.

Not only is there no guarantee about endianness, there is not even a
guarantee that one char will have the 8 least significant bits and the
other will have the 8 most significant ones.

An implementation where one of the unsigned chars winds up with the 4
most significant and the four least significant bits, and the other
unsigned char wound up with the 8 bits in the middle, could be
conforming.


--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq


========================================================================
===============

> {Original Message removed}

More... (looser matching)
- Last day of these posts
- In 2003 , 2004 only
- Today
- New search...