STM32F411VET通过I2C读取TC74A5温度传感器数据失败
问题分析与解决方案
1. I2C传感器地址错误
TC74A5的7位I2C地址由A0/A1/A2引脚电平决定:
- 若A0/A1/A2均接地,7位地址为
0x48,对应写地址0x90(左移1位),读地址0x91 - 你代码中使用
0x4D << 1(即写地址0x9A),需确认硬件上A0/A1/A2的连接是否匹配该地址。如果是默认接线(全接地),应修改地址定义:
const uint8_t Sensor_Address = (0x48 << 1);
2. 错误的I2C读寄存器流程
当前用HAL_I2C_Master_Transmit和HAL_I2C_Master_Receive分开执行,两个函数会在每次操作后发送Stop信号,而TC74A5读寄存器需要**重复Start(Repeated Start)**的流程(无中间Stop)。更可靠的方式是使用HAL库提供的HAL_I2C_Mem_Read函数,它会自动处理完整的读寄存器流程:
// 替换原有的Transmit+Receive代码 if (HAL_I2C_Mem_Read(&hi2c1, Sensor_Address, TEMP_Reg, I2C_MEMADD_SIZE_8BIT, &temp_data, 1, HAL_MAX_DELAY) != HAL_OK) { // 接收错误处理 HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_8); HAL_Delay(250); // 重置I2C总线状态 HAL_I2C_DeInit(&hi2c1); MX_I2C1_Init(); }
3. I2C引脚未正确配置
你的MX_GPIO_Init中没有配置I2C1的SDA/SCL引脚(默认是PB6=SCL,PB7=SDA),这些引脚需要配置为复用开漏输出+上拉。添加以下Msp初始化代码:
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(i2cHandle->Instance==I2C1) { __HAL_RCC_GPIOB_CLK_ENABLE(); /**I2C1 GPIO Configuration PB6 ------> I2C1_SCL PB7 ------> I2C1_SDA */ GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); __HAL_RCC_I2C1_CLK_ENABLE(); } } void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle) { if(i2cHandle->Instance==I2C1) { __HAL_RCC_I2C1_CLK_DISABLE(); /**I2C1 GPIO Configuration PB6 ------> I2C1_SCL PB7 ------> I2C1_SDA */ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6); HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7); } }
4. 通信错误后未重置I2C总线
当I2C通信出错时,总线可能处于锁定状态,后续通信会持续失败。在错误处理分支中添加总线重置代码:
// 在Transmit错误分支中添加 HAL_I2C_DeInit(&hi2c1); MX_I2C1_Init(); // 在Receive错误分支中同样添加上述两行代码
额外调试建议
- 使用示波器或逻辑分析仪抓取I2C总线波形,确认地址、数据帧是否正确
- 检查TC74A5的供电是否正常(需3.3V或5V,根据型号)
- 确认I2C总线的上拉电阻是否存在(一般4.7kΩ,连接SDA/SCL到VCC)
内容的提问来源于stack exchange,提问作者Lorenzo
相关产品推荐
相关产品推荐

