Reputation: 5422
I've a sensor that delivers its 16bits in this way : 1. MSB 2. LSB :
The values are in this range :
0xffff ===> -32767 MIN
0x8000 ====> -1 LSB say -1
0x0000 ====> +1 LSB say 1
0x7FFF ====> 32767 MAX
I'm trying to display these values in a readable way. For that I've written this small 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 that I get is strange:
ffffffff temp -1
I expected the output to be:
7fff temp 32767
What am I doing wrong?
Upvotes: 3
Views: 659
Reputation: 30489
Use the following:
uint8_t msbyte =0x7f;
uint8_t lsbyte = 0xff;
If char
behaves as signed char
on your implementation, lsbyte while oring would extend the sign bit and result may be unexpected. To solve the problem you should use unsigned char
or uint8_t
Although this way, the output range would be:
0xffff ===> -1
0x8000 ====> -32768
0x0000 ====> +1 LSB say 1
0x7FFF ====> 32767 MAX
If you really want the range as you specified, do the following: (Keeping the 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;
}
Upvotes: 3
Reputation: 3108
As mentioned your problem is that the high bit is being used as a sign bit.
You can avoid this using:
uint8_t msbyte =0x7f;
uint8_t lsbyte = 0xff;
uint16_t temp=0;
Additionally, I find using the AVR type defs, Short tutorial useful while handling embedded/device data.
For instance define:
typedef unsigned char BYTE
typedef unsigned int WORD
and use BYTE and WORD in your code.
Upvotes: 0
Reputation: 145829
Change:
char msbyte =0x7f;
char lsbyte = 0xff;
to
unsigned char msbyte =0x7f;
unsigned char lsbyte = 0xff;
char
is a signed type on your implementation and undergoes sign extension when promoted to int
.
Also change:
printf(" %4x temp %d ", temp,temp);
to
printf(" %4x temp %d ", (uint16_t) temp,temp);
to avoid signed extension if temp
is negative.
Upvotes: 0