bigdogguru
Administrator
- Joined
- Mar 12, 2010
- Messages
- 9,821
- Helped
- 2,350
- Reputation
- 4,694
- Reaction score
- 2,272
- Trophy points
- 1,413
- Location
- Southwest, USA
- Activity points
- 62,383
Three Axis compass has six register's ( two for X , two for Y , two for z )
That mean 16bit or two 8byte register's
when we need to read x Axis we have to read two register's
Like This
Code:msb =I2CRead(); I2CAck(); lsb =I2CRead(); I2CAck(); raw_z=( (msb<<8) | lsb);
First we need read msb and then read lsb and msb shift 8 times and OR with lsb
I need to verify
why shift 8 times and what are the data this two registers contain (Data Output X Registers A and B)
why we can not use single register instead of two registers
Please advice
You have answered your own question concerning:
why we can not use single register instead of two registers
Three Axis compass has six register's ( two for X , two for Y , two for z )
That mean 16bit or two 8byte register's
when we need to read x Axis we have to read two register's
The registers of the PIC16F877A are 8-bit, the complete value for each of the coordinate axes, X, Y and Z, require 16-bit of storage.
Can you squeeze 16-bit into 8-bit without loss of data or resolution? No.
Therefore, two 8-bit registers or an integral type, "int" for example in the case of the Hi-Tech C Compiler, with a size of at least two bytes is required to contain the entire value for each of the coordinate axes.
why shift 8 times ....
The code snippet you posted is one method of "reassembling" the two bytes into a single 16-bit entity and storing it into an integral type of at least 2 bytes.
Code:
msb = I2CRead();
I2CAck();
lsb =I2CRead();
I2CAck();
raw_z=( (msb<<8) | lsb);
Assuming the variable raw_z is of sufficient size, 2 bytes or more, the Most Significant Byte (MSB) of the axis value is read and stored into the msb variable, the Least Significant Byte (LSB) of the axis value is read and stored into the lsb variable and are combined with the actions of the last statement:
Code:
raw_z=( (msb<<8) | lsb);
Although I would suggest explicitly casting msb before shifting, otherwise depending on your compiler as you will soon see, you may end up loosing data:
Code:
raw_z=( ((signed int)msb<<8) | lsb);
Lets example each part of the above statement.
Assuming:
msb = 0b00101011
lsb = 0b01010101
Code:
raw_z=( ([COLOR="#FF0000"](signed int)msb[/COLOR]<<8) | lsb);
First the cast of msb to signed int essential extents the 8-bits of msb to 16-bits:
msb 0b00101011
(signed int)msb 0b0000000000101011
Code:
raw_z=( [COLOR="#FF0000"]((signed int)msb<<8)[/COLOR] | lsb);
The left shift eight places of the value contained in msb moves the entire value into the MSB from the LSB of the now two bytes of storage:
(signed int)msb 0b0000000000101011
((signed int)msb<<8) 0b0010101100000000
Code:
raw_z=( ((signed int)msb<<8) [COLOR="#FF0000"]| lsb[/COLOR]);
The ORing of the value now contained in two bytes of storage with the value contained in lsb, essentially copies the value contained in the single byte of lsb into the LSB of the two bytes of storage:
((signed int)msb<<8) 0b0010101100000000
lsb 0b01010101
((signed int)msb<<8) | lsb 0b0010101101010101
And then the final two byte value is stored into the variable raw_z.
what are the data this two registers contain (Data Output X Registers A and B)
Essentially the two bytes of data for each axis represent the magnitude of the magnetic force which lies along each particular axis.
Remember physics where the magnitude and direction of the total force is comprised of the magnitudes of force along each of the axes/vectors, X, Y and Z. A similar scenario exists here.
Time to dust off those vector mathematics books.
BigDog