# Reading 2 bytes the right way

I have a sensor that supplies its 16 bits like this: 1. MSB 2. LSB:

Values ββare in this range:

``````0xffff ===> -32767   MIN
0x8000 ====> -1 LSB say -1
0x0000 ====> +1 LSB say 1
0x7FFF ====> 32767 MAX
```

```

I am trying to display these values ββin a readable way. To do this, I wrote this little program:

``````#include <stdio.h>
#include <math.h>
#include <stdint.h>
int main(){
char msbyte =0x7f;
char lsbyte = 0xff;
int16_t temp=0;
temp = (msbyte<<8) | lsbyte;
printf(" %4x temp %d ", temp,temp);

return 0 ;

}
```

```

the result I am getting is weird:

ffffffff temp -1

I expected the result to be:

7fff temp 32767

What am I doing wrong?

+3

source to share

Use the following:

``````uint8_t msbyte =0x7f;
uint8_t lsbyte = 0xff;
```

```

If `char`

behaves as `signed char`

in your implementation, lsbyte while oring expands the sign bit and the result may be unexpected. To solve the problem, you must use `unsigned char`

or`uint8_t`

Regardless of this path, the output range will be:

``````0xffff ===> -1
0x8000 ====> -32768
0x0000 ====> +1 LSB say 1
0x7FFF ====> 32767 MAX
```

```

If you really want the range as you pointed out, follow these steps: (Save msbyte and lsbyte `unsigned`

)

``````int16_t num16=0;
temp = (msbyte<<8) | lsbyte;
num16 = (int16_t)(temp & 0x7FFF);  /* Get the number */
if(temp & 0x8000) { /* Get sign bit */
num16 = num16 * -1 - 1;
}
```

```
+3

source

Edit:

``````char msbyte =0x7f;
char lsbyte = 0xff;
```

```

to

``````unsigned char msbyte =0x7f;
unsigned char lsbyte = 0xff;
```

```

`char`

is a signed type in your implementation and undergoes sign expansion when promoted to `int`

.

Also change:

``````printf(" %4x temp %d ", temp,temp);
```

```

to

``````printf(" %4x temp %d ", (uint16_t) temp,temp);
```

```

to avoid signed expansion if `temp`

negative.

0

source

As mentioned, your problem is that the most significant bit is being used as the sign bit.

You can avoid this by using:

``````uint8_t msbyte =0x7f;
uint8_t lsbyte = 0xff;
uint16_t temp=0;
```

```

Also, I find using the AVR type defs , Short tutorial useful when handling inline / device data.

For example, define:

``````typedef unsigned char BYTE
typedef unsigned int WORD
```

```

and use BYTE and WORD in your code.

0

source

All Articles