The I2C communications bus uses 7-bit or 10-bit addressing to address slave devices. Taking the more common 7-bit addresses, each packet sent on the bus by the master starts with an 7-bit address followed by a 1-bit read or write indicator (\$\text{R}/\overline{\text{W}}\$).
Most datasheets only give the I2C address for their device either in binary notation or as bits on timing diagrams (with notes for configurable address bits), which are both unambiguous as they either display seven or eight bits so you can tell if the \$\text{R}/\overline{\text{W}}\$ bit is included. This seems to follow the official NXP I2C specification.
The problem comes when trying to write down the address in hex. Different sources convert the address in different ways:
- Convert the 7-bit address to a hexadecimal value in the range
0x00
to0x7F
0b101 0011
becomes0x53
- Examples Robot Electronics I2C tutorial, Linux i2cdetect tool, STM32 CPAL library, Arduino Wire library
- Include the \$\text{R}/\overline{\text{W}}\$ bit as the LSB and give two addresses, one for reading and one for writing in the range
0x00
to0xFF
0b101 0011
becomes0xA6
for writing and0xA7
for reading- Sometimes only the write address (e.g.
0xA6
) is given - Examples: 8051 Project tutorial, STM32 HAL library (example of confusion), Microchip PIC code examples (CE119), Saleae Logic protocol analyser
These two options are not always distinguishable.
Clearly using binary notation is better as it gives you an unambiguous address, however this is not always possible. One notable case is on C/C++ where there is not a particularly standard way of writing binary numbers. This leads to the problem I'm having where specifying constants for devices in the circuit is ambiguous.
So in choosing a standard for our schematics, documentation and code (C++) we have to pick one way or the other. That leads to my question:
Is there a dominant way of displaying an I2C address in hexadecimal notation, or are both used commonly?
Best Answer
I know what you mean. I have seen these ambiguities in documentation too. That doesn't make it right, though.
I personally only communicate the address as a 7 bit value, whether in binary (0-1111111), hex (0-7F), decimal (0-127) or some other scheme. The R/W bit is NOT part of the address. It and the address are two separate fields that happen to be crammed into the same byte.
Unfortunately, even though the 7-bit address interpretation is correct and does seem to be the more common, there is a lot of bad documentation out there. This means you can't count on the next datasheet you read to do it one way or the other. When reading documentation, this is a issue you just have to be aware of and be extra careful to see how exactly the address is being presented. So far I haven't come across a datasheet where this couldn't eventually be figured out.
When writing your own documentation, please do the rest of the world a favor and express the "address" as a 7 bit value. If you want to show it with the R/W bit, call it the "address byte" or something to make this clear.