I2C (Inter Integrated Circuit) is a serial communication bus standard mainly used in short distance, low-speed communication scenarios, widely used for communication between microcontrollers and various peripheral devices. The I2C protocol allows multiple "slave" chips to communicate with one or more "master" chips using a multi master multi slave architecture, requiring only two signal lines: SCL (clock signal line) and SDA (data input/output line)
The I2C protocol is a protocol that allows multiple "slave" chips to communicate with one or more "master" chips. It is like the Serial Peripheral Interface (SPI) and can only be used for short-range communication. Similar to asynchronous serial interfaces (such as RS232 or UART), only two signal lines are needed to exchange information.
Implementing I2C requires two signal lines for information exchange, SCL clock signal line and SDA data input/output line. It belongs to synchronous communication, and due to the use of a single wire for input and output data, the communication direction is half duplex.
Summary: Short distance, one master multiple slaves, half duplex, two wires, synchronous communication.
Because it is an open drain output, why is it an open-drain output?
The I2C protocol supports multiple master devices and multiple slave devices on one bus. If the open-drain output is not used, but the push-pull output is used, there will be a short circuit between the master devices. Therefore, the bus generally uses an open-drain output.
The pull-up resistor is connected because I2C communication requires the ability to output a high level. Generally, an open-drain output cannot output a high level. If a pull-up resistor is connected to the drain, level conversion can be performed.
I2C consists of two buses SDA and SCL. The output stages of the devices connected to the bus must be open-drain, all connected to the power supply through pull-up resistors, so that the "wired-AND" function can be achieved. Both lines are high when the bus is idle.
Generally, the driving capability of the IO port is in the order of 2mA to 4mA.
• Considering the power consumption, the resistance value should not be too small
If the pull-up resistance value is too small, the current that VDD sinks into the port will be large, and the power consumption will be large, resulting in an increase in the low level value of the port output (I2C protocol stipulates that the maximum allowable value of the port output low level is 0.4 V). Therefore, usually the pull-up resistor should not be lower than 1K (when VDD=3V, the sink current should not exceed 3mA).
• Considering the speed problem, the resistance value should not be too large
It depends on the RC delay formed by the pull-up resistor and the line capacitance. The larger the RC delay, the more the waveform deviates from the square wave and tends to a sine wave, and the probability of correct data reading and writing is lower, so the pull-up resistor cannot be too large.
The load capacitance on the I2C bus cannot exceed 400pF. As the number of devices on the I2C bus increases, the bus load capacitance increases accordingly. When the total load capacitance is greater than 400pF, it cannot work reliably. This is also a limitation of I2C.
It is recommended to choose 1.5K, 2.2K and 4.7K for the pull-up resistor.
According to the I2C bus specification, both lines must be high when the bus is idle. Assuming that the master device A needs to start I2C, he needs to convert SDA from high level to low level as the start signal when SCL is high.
After the master device A pulls SDA high, it needs to check the level of SDA again. Why? Because of the line AND, if the master device A pulls SDA high, other master devices have already pulled SDA low. Since 1 & 0 = 0, then when the master device A checks the SDA level, it will find that it is not a high level, but is low level. It means that other master devices preempt the bus earlier than it, and master A can only give up occupying the bus. If SDA is high, it means that master A can occupy the bus, and then master A pulls SDA low to start communication.
Therefore, to simulate I2C, be sure to set the GPIO port as an open-drain output and add a pull-up resistor.