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

Correct placeholder for two 8 bit binaries

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



Joined: 30 Jun 2018
Posts: 17

View user's profile Send private message

Correct placeholder for two 8 bit binaries
PostPosted: Sat Jul 07, 2018 11:20 am     Reply with quote

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: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jul 07, 2018 12:01 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 07, 2018 12:19 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 07, 2018 1:06 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 07, 2018 1:39 pm     Reply with quote

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: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jul 07, 2018 1:55 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 07, 2018 3:36 pm     Reply with quote

But the result doesn't equal 557 ?
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jul 07, 2018 4:44 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 07, 2018 5:26 pm     Reply with quote

Very good explanation Jay, thank you for your time & effort.

Roger
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Sun Jul 08, 2018 2:01 am     Reply with quote

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: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jul 08, 2018 8:10 am     Reply with quote

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: 19496

View user's profile Send private message

PostPosted: Sun Jul 08, 2018 12:41 pm     Reply with quote

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... Smile
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