Principles and Programming Implementation of I2C Communication in Embedded Technology (Temperature and Humidity Sensor)

1. Detailed Explanation of I2C Communication Principles

1. Hardware Structure and Physical Layer

Bus Topology:

The I2C bus is a multi-master/slave structure that supports multiple master and slave devices sharing the bus.

SCL (Clock Line) and SDA (Data Line) are both open-drain outputs and require external pull-up resistors (typical value: 4.7kΩ, specific values should be adjusted based on bus capacitance).

When the bus is idle, SCL and SDA are both at a high level.

Levels and Speeds:

Standard Mode (Standard Mode):100kHz, maximum bus capacitance 400pF.

Fast Mode (Fast Mode):400kHz, maximum bus capacitance 200pF.

High-Speed Mode (High-Speed Mode):3.4MHz (both master and slave devices must support this).

Signal Integrity:

For long-distance communication, signal reflection and interference must be considered. The pull-up resistor value can be reduced, or an I2C buffer (such as PCA9615) can be used.

2. Protocol Timing Details

Start Condition (START):

When SCL is high, SDA transitions from high to low.

(https://img-blog.csdnimg.cn/20210519150818168.png)

Stop Condition (STOP):

When SCL is high, SDA transitions from low to high.

(https://img-blog.csdnimg.cn/20210519150834724.png)

Data Transmission Rules:

Data Validity: SDA must remain stable during the high level of SCL and can only change when SCL is low.

ACK/NACK Mechanism: After transmitting 8 bits of data, the receiver pulls down SDA on the 9th clock cycle (ACK) or keeps it high (NACK).

If the master device does not receive an ACK, it must trigger a retransmission or terminate communication.

7-bit Address Format:

Slave Address (7 bits) + Read/Write Bit (0: Master writes, 1: Master reads).

Example:SHT30 default address is 0x44, write operation address is `0x44 << 1 | 0 = 0x88`, read operation is `0x44 << 1 | 1 = 0x89`.

2. Deep Configuration of SHT30 Sensor

1. Pin Definitions for Sensor and Hardware Connections:

Pin Function Connection Description
VDD Power 3.3V (range 2.4V-5.5V)
GND Ground Connect to Ground
SDA Data Line Connect to MCU SDA, pull up to VDD
SCL Clock Line Connect to MCU SCL, pull up to VDD
ADDR Address Selection Connect to Ground (0x44) or connect to VDD (0x45).

Hardware Design Considerations:

Power supply should include a 0.1μF ceramic capacitor for filtering to reduce noise.

Avoid long traces for SDA/SCL to reduce electromagnetic interference (EMI).

2. Common Commands in Sensor Command Set:

Command Command Code (MSB, LSB) Function
Trigger Measurement (High Precision) 0x2C, 0x06 Start a single measurement, enable clock stretching
Soft Reset 0x30, 0xA2 Reset the sensor
Read Status Register 0xF3, 0x2D Get sensor status information

Clock Stretching:

The SHT30 may pull down SCL during measurement, and the master device must detect and wait for its release.

3. Data Format and CRC Check for Raw Data Parsing:

Measurement data consists of 6 bytes: `[Temp_H, Temp_L, Temp_CRC, Humi_H, Humi_L, Humi_CRC]`.

Temperature and humidity are both 16-bit unsigned integers (big-endian format).

CRC8 Check Algorithm:

Polynomial: `x^8 + x^5 + x^4 + 1` (0x31).

Initial Value: 0xFF.

Example Code:

uint8_t crc8(uint8_t *data, uint8_t len) {

uint8_t crc = 0xFF;

for (uint8_t i = 0; i < len; i++) {

crc ^= data[i];

for (uint8_t bit = 0; bit < 8; bit++) {

if (crc & 0x80) {

crc = (crc << 1) ^ 0x31;

} else {

crc <<= 1;

}

}

return crc;

}

3. STM32 Programming Implementation (Deep Optimization of HAL Library)

1. I2C Initialization (Key Parameters in CubeMX Configuration):

hi2c1.Instance = I2C1;

hi2c1.Init.ClockSpeed = 100000; // 100kHz

hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; // Tlow/Thigh = 2 (Standard Mode)

hi2c1.Init.OwnAddress1 = 0; // Master device does not need an address

hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; // Allow clock stretching

HAL_I2C_Init(&hi2c1);

2. Complete Communication Process (Including Timeout and Error Handling) Trigger Measurement:

uint8_t cmd[2] = {0x2C, 0x06}; // High Precision Measurement Command

HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, 0x88, cmd, 2, 100);

if (status != HAL_OK) {

// Error Handling: Retry or Report Error

Error_Handler();

}

Wait for Measurement Completion:

Method 1 (Blocking Wait): Delay 6ms (SHT30 typical measurement time).

Method 2 (Clock Stretching Detection): MCU must support clock stretching, HAL library handles it automatically.

Read Data:

uint8_t data[6];

status = HAL_I2C_Master_Receive(&hi2c1, 0x89, data, 6, 100);

if (status != HAL_OK) {

// Error Handling

}

Data Verification and Conversion:

// Verify Temperature Data CRC

if (crc8(data, 2) != data[2]) {

// CRC Error Handling

}

// Temperature Conversion

uint16_t raw_temp = (data[0] << 8) | data[1];

float temperature =45.0f + 175.0f * (raw_temp / 65535.0f);

// Humidity Conversion (similarly)

3. Interrupt and DMA Optimization in Interrupt Mode:

// Start Non-blocking Transmission

HAL_I2C_Master_Transmit_IT(&hi2c1, 0x88, cmd, 2);

// Handle Completion Event in Callback Function

void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) {

// Trigger Data Read

}

DMA Mode:

// Configure DMA Channel (enable I2C TX/RX DMA in CubeMX)

HAL_I2C_Master_Transmit_DMA(&hi2c1, 0x88, cmd, 2);

// Handle Subsequent Logic in DMA Completion Interrupt

4. Debugging and Troubleshooting

1. Hardware Debugging Tools Logic Analyzer (Saleae/PulseView):

Capture I2C waveforms, verify start/stop conditions, addresses, data, and ACK.

Check if the SCL frequency meets expectations (e.g., 100kHz).

Oscilloscope:

Observe SDA/SCL signal quality, ensuring no overshoot or ringing.

2. Common Issues and Solutions

Problem Phenomenon Possible Cause Solution
Sensor Not Responding Incorrect Address/Power Not Connected Check I2C address, measure VDD voltage
DataCRC Check Failed Bus Interference/Timing Instability Reduce Communication Speed, Shorten Traces
Communication Timeout Slave Device Did Not ReleaseSCL (Clock Stretching) Enable `NoStretchMode` or Increase Timeout
Temperature/Humidity Values Abnormal Data Processing Formula Error Check Raw Data Conversion Formula

3. Code Debugging Tips Add Debug Prints:

printf(“Raw Temp: 0x%04X, Calc: %.2f°C\n”, raw_temp, temperature);

HAL Library Error Code Analysis:

if (status == HAL_ERROR) {

uint32_t error = HAL_I2C_GetError(&hi2c1);

if (error & HAL_I2C_ERROR_AF) {

// ACK Failure

}

}

5. Extended Applications Multi-Sensor Shared Bus:

Assign a unique address for each sensor (e.g., SHT30 can set the ADDR pin to switch between 0x44/0x45).

Use an I2C multiplexer (such as TCA9548A) to extend the bus.

Low Power Design:

Turn off the sensor power during non-measurement periods (controlled by a MOS transistor for VDD).

Use I2C wake-up commands (such as SHT30‘s 0x2C06 supports low power mode).

Summary: By refining the I2C protocol details, sensor configuration, code optimization, and debugging techniques, the stability and accuracy of temperature and humidity data collection can be significantly improved. In practical development, it is necessary to combine hardware design with software fault tolerance mechanisms to ensure reliability in complex environments.

Leave a Comment