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?
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
oruint8_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;
}
source to share
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.
source to share
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.
source to share