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?