View previous topic :: View next topic |
Author |
Message |
Jerry712731
Joined: 14 Apr 2004 Posts: 12 Location: UK
|
Getting 2 bytes from a Long (Int16) |
Posted: Fri Oct 22, 2004 6:33 pm |
|
|
What is the most efficent way to extract the data from the 2 bytes that make up a Long (int16)
#byte etc works OK any other ideas |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Fri Oct 22, 2004 6:38 pm |
|
|
Code: |
Union Convert
{
int16 LongVar;
byte ByteVar[2];
} LongToByte;
LongToByte.LongVar=0xAA55;
|
Now LongToByte.ByteVar[0] and LongToByte.ByteVar[1] hold the two byte of your long variable. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1636 Location: Perth, Australia
|
|
Posted: Fri Oct 22, 2004 7:38 pm |
|
|
Code: | int8 x;
int16 l;
...
x = l; // get low byte
..
x = l >> 8; //get high order byte
.... |
|
|
|
Ttelmah Guest
|
Re: Getting 2 bytes from a Long (Int16) |
Posted: Sat Oct 23, 2004 7:52 am |
|
|
Jerry712731 wrote: | What is the most efficent way to extract the data from the 2 bytes that make up a Long (int16)
#byte etc works OK any other ideas |
Lots of good suggestions, but why not just use the provided 'make8' function...
short_val=make8(long_val,0);
and
short_val=make8(long_val,1);
return the first and second byte respectively. They are written efficiently, and will only fetch the actual byte required, not involving the overhead of rotating or masking the value.
The union, is very efficient, if you want to go both ways, and declare the actual variable using the union (so there is no need to copy the value into another variable).
Best Wishes |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Sat Oct 23, 2004 9:36 am |
|
|
I use:
#define gethi(x) (*(&x+1))
#define getlo(x) x
#define puthi(x,y) *(&x+1) = y
#define putlo(x,y) *(&x) = y
Will |
|
|
Guest
|
Re: Getting 2 bytes from a Long (Int16) |
Posted: Sat Oct 23, 2004 10:36 am |
|
|
Ttelmah wrote: | Jerry712731 wrote: | What is the most efficent way to extract the data from the 2 bytes that make up a Long (int16)
#byte etc works OK any other ideas |
Lots of good suggestions, but why not just use the provided 'make8' function...
short_val=make8(long_val,0);
and
short_val=make8(long_val,1);
return the first and second byte respectively. They are written efficiently, and will only fetch the actual byte required, not involving the overhead of rotating or masking the value.
The union, is very efficient, if you want to go both ways, and declare the actual variable using the union (so there is no need to copy the value into another variable).
Best Wishes |
Yes but Make8() can't be used left and right side !
union can. |
|
|
Guest
|
|
Posted: Sat Oct 23, 2004 10:41 am |
|
|
Will Reeve wrote: | I use:
#define gethi(x) (*(&x+1))
#define getlo(x) x
#define puthi(x,y) *(&x+1) = y
#define putlo(x,y) *(&x) = y
Will |
puthi(0 and gethi() are not a good idea. It is such a space hog.
Union is as small as make8() and can be used left and right side of argument with equal space saving.
In addition, using the union allows easy expansion to int32 and if an array is added tothe union then 8 bit values and be stuffed directly into the int32 value using array syntax.
Make8() is very limited can only be used on the right side...
geth() and outhi() eat ROM space
.................... val = gethi(Var);
0028: CLRF 03
002A: MOVLW 08
002C: MOVWF FE9
002E: MOVFF 03,FEA
0032: MOVFF FEF,06
.................... puthi(Var,val);
0036: CLRF 03
0038: MOVLW 08
003A: MOVWF FE9
003C: MOVFF 03,FEA
0040: MOVFF 06,FEF
Union
....................
.................... val = u16.hl.h;
0044: MOVFF 0A,06
.................... u16.a[1] = val;
0048: MOVFF 06,0A
Make8()
....................
.................... val = make8(Var,1);
004C: MOVFF 08,06 |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sat Oct 23, 2004 11:02 am |
|
|
Quote: | Yes but Make8() can't be used left and right side !
union can. |
That's why there is a make16() function |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Sat Oct 23, 2004 11:46 am |
|
|
How long have make8 and make16 been available? I don't know how I missed them!
Keep well all,
Will |
|
|
Guest
|
|
Posted: Sat Oct 23, 2004 11:54 am |
|
|
Mark wrote: | Quote: | Yes but Make8() can't be used left and right side !
union can. |
That's why there is a make16() function |
I do not understand how make16() solves that problem ! |
|
|
Ttelmah Guest
|
|
Posted: Sat Oct 23, 2004 12:09 pm |
|
|
Anonymous wrote: | Mark wrote: | Quote: | Yes but Make8() can't be used left and right side !
union can. |
That's why there is a make16() function |
I do not understand how make16() solves that problem ! |
Make16, allows you to build a 16bit value from 2 8bit values. It can be used as the 'inverse' of make8 (to insert a byte into one half of the 16bit value), by using make8 to pull in the low/high byte for the other half of the re-assembly. Personally the union is easier to go this way (which is why in my previous post, I suggested this - which another poster seemed to miss).
Since the original poster was asking how to _extract_ the bytes, Make8, is the easiest answer. To assemble two bytes, Make16, is the simplest answer. For a 'partial' reassembly, the union is the way to go. It is worth realising that this can be done with a cast.
Best Wishes |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Sat Oct 23, 2004 4:46 pm |
|
|
What I like about unions is the fact that there is no code overhead in converting between 32 bit to 16 bit to 8 bit variables. And if you want to construct bigger variables from the smaller ones (8->16->32) it will do it only using load instructions, no shifting is required which again leads to smaller/faster code. |
|
|
Guest
|
|
Posted: Sat Oct 23, 2004 6:16 pm |
|
|
Will Reeve wrote: | How long have make8 and make16 been available? I don't know how I missed them!
Keep well all,
Will |
many years... |
|
|
Guest
|
|
Posted: Sat Oct 23, 2004 6:19 pm |
|
|
Ttelmah wrote: | Anonymous wrote: | Mark wrote: | Quote: | Yes but Make8() can't be used left and right side !
union can. |
That's why there is a make16() function |
I do not understand how make16() solves that problem ! |
Make16, allows you to build a 16bit value from 2 8bit values. It can be used as the 'inverse' of make8 (to insert a byte into one half of the 16bit value), by using make8 to pull in the low/high byte for the other half of the re-assembly. Personally the union is easier to go this way (which is why in my previous post, I suggested this - which another poster seemed to miss).
Since the original poster was asking how to _extract_ the bytes, Make8, is the easiest answer. To assemble two bytes, Make16, is the simplest answer. For a 'partial' reassembly, the union is the way to go. It is worth realising that this can be done with a cast.
Best Wishes |
Yes may be be used to do the job, but it is strictly not left side compatible.
make16() = a; does not work |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sat Oct 23, 2004 10:11 pm |
|
|
Quote: | make16() = a; does not work |
And what would the point of doing that be? |
|
|
|