What's goingon here?

15 Jan 2011 . Edited: 15 Jan 2011

Hello,  

if I have an unsigned int with the value 255  and I  <<8  I  was expecting to get 65280.  If I then |  ('bitwise or') it  with say 127,  I  am expecting to get  serialdata=65407.

unsigned int serialdata=0;/* the 16 bits of serial data to go out to the  analog board - flush  it so its clean */
    unsigned int shift_out_bit=0;
    int m=1;
    int SCOUNT=0;
    printf("serialdata 1   %u\n\r",serialdata);
   
    serialdata = (control | inputrelay);
   
    printf("serialdata 2 =  %u\n\r",serialdata);

However, what I get at the second printf is  4294967134.

It looks like this is somehow converting to an unsigned long,  but the value is still garbage. I tried quite a few  things,  but no luck.  Any  pointers  here?

 

Thanks

 

15 Jan 2011

Hi Andrew,

Is this a division?

serialdata = (control | inputrelay);

15 Jan 2011

Hi Michel,

 

no,  |  is  for bitwise or  (logic function)

 

cheers

15 Jan 2011

Sorry, with the bad resolution of my laptop, I saw a "\" insteat of the pipe.

Bitwise OR is overloadable. what do you have in the variables control and inputrelay ?

 

15 Jan 2011 . Edited: 15 Jan 2011

Both are  defined as unsigned int.

 

Control starts out as an 8 bit word and gets right shited 8 places by <<8  so it sites in the top 8 bits of a 16bit word.  Then I  bitwise or it with inputrelay which is sitting in the bottom 8 lsb's. Now I am supposed to have a 16 bit word  which I  then send  out. 

 

The  bottom 8  bits (inputrelay) are working fine and do as they are suposed to.  The top 8  bits (control) do not work.

 

so,  I definelity  have an  issue  around the statement

 

serialdata = (control | inputrelay);

 

 

 

15 Jan 2011

The result 4294967134 is bin 11111111111111111111111101011110.(32bit)

Is it possible, that you fill control with "1" when shifting to left, because it is not defined as a 16 -bit word?

 

15 Jan 2011

what happens if you use uint16_t rather than unsigned int ?

15 Jan 2011 . Edited: 15 Jan 2011

Michel

control  is  defined as an unsigned int - this  gives it a range of  2^16-1 = 65535

I think  the shift right (<<8)  is  defined in the C/C++ standard as right filling with  zeros.

 

If I understand it correctly,  if  I  have 255  for example,  and I right shift 8 times  I  get 255*256 = 65280.

 

Then  I  bit wise or  with the lower 8  bits - lets assume 100  in this case,  I  should get 65280+100 = 65380

 

I  cannot use the multiply and add  approach,  because  the serialout()  function is  called by  other  functions - it needs  to functionusing the bitwise  or  approach.

 

really  got me stumped!

15 Jan 2011

hi Andy,

sorry,  I never heard of uint16_t.  What is that?

15 Jan 2011 . Edited: 15 Jan 2011

I think  the shift right (<<8)  is  defined in the C/C++ standard as right filling with  zeros.

Isn't that left shift, or am I thinking backwords?

 

15 Jan 2011

yes,  sorry  you are right.  shift left  shifts data  towards  the  MSB. 

 

 

15 Jan 2011

Show us the full code, with the definitions of control, inputrelay and the shift statement. Otherwise we can keep guessing all day.

15 Jan 2011

Quote:

sorry, I never heard of uint16_t. What is that?

See http://en.wikipedia.org/wiki/Stdint.h

16 Jan 2011

Thanks Andy - looks  very  useful.  I'll need to read  through  it carefully.

I  think I  may  hav e worked out the problem - the  software  appears to be working now.

I declared 2 variables as unsigned ints so range  of values is   2^16-1) for each variable.

I complemented the one variable - so  it  had a value  of  239  and  after I complemented it,  it  became ~239 = 65296

Then  I  <<8   that variable . . .

Clearly 65296 <<8  is  going to be a very  big  number.

 

 

 

 

16 Jan 2011

Quote:

I declared 2 variables as unsigned ints so range of values is 2^16-1) for each variable.

I thought the Mbed default of unsigned int was 2^32 and an int was +/12^31 ? (hence why I tend to use stdint.h)

Anyway, you seem to have things under control, nice one :)

Btw, stdint.h is pulled in when you #include "mbed.h"

16 Jan 2011

Ah,  perhaps  another reason why I lost my  way!  I  am  using  an ANSI C  handbbook.  Looks  like this  was also a step in the wrong direction on my part.

 

16 Jan 2011

Hi Andrew, All,

I can see there is a little confusion about C data types and sizes etc here, so i've just written a page I hope will help make it all explicit:

In general, use int for variables/counting things etc, and the stdint.h types when you are working/storing/manipulating things explicitly at the bit level.

Simon

22 Jan 2011

Thanks Simon, that clarifies a few things. My software is working ok now.