View previous topic :: View next topic |
Author |
Message |
skybox63
Joined: 30 Jun 2018 Posts: 17
|
Correct placeholder for two 8 bit binaries |
Posted: Sat Jul 07, 2018 11:20 am |
|
|
Hello,
I respectfully ask for some assistance on connecting two 8 bit binaries into a 16 bit representation so that I get the correct placeholders for adding.
For example:
first = 00101101 = 45
second = 00000010 = 2
If the two are combined (how I want it) it results in:
0000001000000010 = 557
I tried this without success:
unsigned int8 first, second;
unsigned int16 number
number = (int)first << 8 | second;
Again sure would appreciate some direction.
Roger |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sat Jul 07, 2018 12:01 pm |
|
|
x = make16(hi,lo);
so..
number= make16(first,second);
if you press F11 while your project is open, the CCS Manual magically appears,
make16() is a function.
I generally keep the manual open (lousy typist, lotsa seniors moments too !)
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jul 07, 2018 12:19 pm |
|
|
CCS doesn't do automatic type promotion, so you have to do this:
Code: | number = ((int16)first << 8) | second; |
Assuming you're using 16F or 18F PICs, an 'int' is the same as
'unsigned int8'. It's best to always use int8, int16, and int32 in CCS. |
|
|
skybox63
Joined: 30 Jun 2018 Posts: 17
|
|
Posted: Sat Jul 07, 2018 1:06 pm |
|
|
Jay,
Noted and thank you.
PCM Programmer,
I now see what I did wrong. I appreciate the clarification.
Best,
Roger |
|
|
skybox63
Joined: 30 Jun 2018 Posts: 17
|
|
Posted: Sat Jul 07, 2018 1:39 pm |
|
|
PCM Programmer,
I was hoping you could expand on your explanation. I'm trying to understand how this works?
What exactly is happening when "first" gets shifted left by 8 bits and ultimately ends up as a concatenate of the two bytes and is stored in the variable "number". Perhaps my thought process is backward on this... do you have some time to explain?
Thank you
Roger |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sat Jul 07, 2018 1:55 pm |
|
|
I'll take a stab...
8 bit data of 'first' gets put into the 16bit wide variable called 'number'.
If 'first' is 00101101 ( your 45)
number becomes..
xxxxxxxx00101101
then gets shifted left 8 places
xxxxxxx001011010
xxxxxx0010110100
xxxxx00101101000
xxxx001011010000
xxx0010110100000
xx00101101000000
x001011010000000
0010110100000000
then 8bit data of 'second gets or'd into the 16 bit wide variable called 'number'
0010110100000010
At least that's my take on it. If you want, you can dump the listing and see the machine code, though it might be confusing....
I'm sure if I'm not right, others will correct my post.
Jay |
|
|
skybox63
Joined: 30 Jun 2018 Posts: 17
|
|
Posted: Sat Jul 07, 2018 3:36 pm |
|
|
But the result doesn't equal 557 ? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sat Jul 07, 2018 4:44 pm |
|
|
hmm...
I put 45 into the Windows calculator, got 00101101 in binary.
I then leftshifted it ,when I put in '2', 0000 0010 on the 'tail',
so it displays 0010110100000010.
which when converted to decimal shows 11522
which works out when you manually add 8192+2018+1024+256+2 ( the '1' bits )
Now I'm trying to figure out how you get 557 , as 'first' is 45, 'second' is 2 , which means the 16 bit 'number' HAS to be even !
EDIT....
ARRRGH..... OK. light bulb came on....
'first' aka 45 is really the LOW byte
'second' aka 2 is the HIGH byte
that makes 'number' to be 00000010 00101101
so.... put 2 into the 16 bit variable 'number'..
0000 0000 0000 0010
leftshift 8 times.
0000 0000 0000 0100
0000 0000 0000 1000
0000 0000 0001 0000
0000 0000 0010 0000
0000 0000 0100 0000
0000 0000 1000 0000
0000 0001 0000 0000
0000 0010 0000 0000
then 'or' 45
0000 0010 0010 1101
and THAT should give you 557.
Jay |
|
|
skybox63
Joined: 30 Jun 2018 Posts: 17
|
|
Posted: Sat Jul 07, 2018 5:26 pm |
|
|
Very good explanation Jay, thank you for your time & effort.
Roger |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Sun Jul 08, 2018 2:01 am |
|
|
It's just worth adding, that the compiler is 'smart'; in it's optimisation, so if you perform:
Code: |
number = ((int16)first << 8) | second;
|
It doesn't actually perform 8 single rotations to move 'first', instead just moving the value with a single byte move.
So:
0000 0000 0000 0100
0000 0000 0000 1000 //never actually generated
0000 0000 0001 0000 //never actually generated
0000 0000 0010 0000 //never actually generated
0000 0000 0100 0000 //never actually generated
0000 0000 1000 0000 //never actually generated
0000 0001 0000 0000 //never actually generated
0000 0010 0000 0000
//Single byte move performed to get here..... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sun Jul 08, 2018 8:10 am |
|
|
OK I got curious..
number1, number 2 are int16, preset to 0
first,second, int8 (2 and 45)
code generated.....
157: number1 = ((int16)first << 8) | second;
213 01D1 CLRF 0x51
214 084E MOVF 0x4e, W
215 00D0 MOVWF 0x50
216 00D1 MOVWF 0x51
217 01D0 CLRF 0x50
218 0850 MOVF 0x50, W
219 044F IORWF 0x4f, W
21A 00CA MOVWF 0x4a
21B 0851 MOVF 0x51, W
21C 00CB MOVWF 0x4b
158: number2 = make16(first,second);
21D 084E MOVF 0x4e, W
21E 00CD MOVWF 0x4d
21F 084F MOVF 0x4f, W
220 00CC MOVWF 0x4c
159:
interesting how small make16() is !
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Sun Jul 08, 2018 12:41 pm |
|
|
Yes.
In the first example, the compiler moves the 8bit variable into the low byte of a 16bit 'scratch' variable, then clears the upper byte of this. Then moves the byte from the low byte to the high byte, and then clears the low byte. It then loads the second variable, and does the OR.
The make8, simply moves the 'high' byte directly into the high byte of the result, and the low byte into the low byte of the result. All done... |
|
|
|