2

I'm considered a beginner in programming, so sorry if this is a very simple question.

I'm using STM32f411 uC to read from a pressure sensor MS5525DSO using I2C protocol. The programming is in c language through Eclipse.

when I read a data from sensor "PROM" memory, I expect 2 bytes "clocked with the MSB first" as data sheet said in page10.

My code:

uint8_t Cmd= 0xA6;
  // Transmit a request to read from 0xA6 memory address:
  HAL_I2C_Master_Transmit(&I2C_HandleTypeDef, sensor_address, Cmd, 1 byte, timeout);

uint8_t PROM [2];
  // Read from PROM 0xA6
  HAL_I2C_Master_Receive(&I2C_HandleTypeDef, sensor_address, &PROM[0], 2 bytes, timeout);

Now, I stored the two bytes in an array variable unint8_t PROM [2],

the result is then:

PROM [0]= 61 decimal or (0011 1101 b)

PROM [1]= 66 decimal or (0100 0010 b)

With memcpy function the value then should be = 15,682 or (0011 1101 0100 0010‬ b)

Then, I change my mind and said let me store the data directly in one 16-bit variable so,

unint8_t PROM --->> unint16_t PROM

When I execute that I got this value:

PROM = 16,957 decimal or (0100 0010 0011 1101 b)

It is clear that the second byte (66d) is written first then the (61d) byte after,

So, I'm confused. Is my first method correct or am I missing something? does the second method swaps the bytes? which one is correct?

glts
  • 21,808
  • 12
  • 73
  • 94
  • 7
    This seems to be a good time to learn about [*endianness*](https://en.wikipedia.org/wiki/Endianness). – Some programmer dude Dec 29 '19 at 10:21
  • @4386427, I added the the code. For the uint16, I just change the the variable type. – Mohammad Aldawsari Dec 29 '19 at 11:11
  • You read some bytes, in a particular order. An int consists of 2 bytes on your platform and the bytes are stored in some particular order. If the order in which you receive the bytes is not the order in which an int is stored, you must swap the bytes. – Paul Ogilvie Dec 29 '19 at 11:17

2 Answers2

2

you can store two 8-bits into a 16-bit with (x1 << 8) | x2, where x1 is PROM[0] and x2 is PROM[1]

This is in combine multiple chars to an int, << and | are logical operators, << is left-shift, | is or

There are many other bit hacking solutions, cf https://graphics.stanford.edu/~seander/bithacks.html

ralf htp
  • 9,149
  • 4
  • 22
  • 34
1

Thanks guys for comments and answers.

It is an endianness issue as you said. So, I added this line to the code giving that "PROM" is a 16-bit uint.

           PROM= ((PROM<<8)&0xff00)|((PROM>>8)&0x00ff);

This will do the byte swapping.

Fortunately, my sensor has a temperature measurement. So, I could validate my code and got a correct result "23 C" (my room temp.) using the above byte swapping line code.

However, I'm still interested why the function used in my code did the little-endian ordering, and is there a way to change that setting.

Thank you again for contributions.

  • 2
    Endianness is rarely a matter of a setting, but mostly a matter of the processor core. Some processor families are capable to use both little and big endianness, others are fixed by their hardware. For example, 80x86 processors are little endian machines while 680x0 processors are big endian machines. ARM cores can be used with both in principle, but commonly the run-time environment and/or compiler system are fixed to one of both. -- **TL;DR: Commonly you can't change anything about it.** – the busybee Dec 29 '19 at 15:02