STM32F446通过I2C读取MPU6050数据不更新且初始化卡死问题
问题排查与修复方案
1. 修复I2C引脚配置(核心故障原因)
I2C通信要求总线为开漏输出模式,同时搭配上拉电阻,你当前的GPIO配置为推挽输出且无上拉,会导致总线电平异常,通信直接卡住。修改I2C1_Init中的GPIO配置代码:
GPIO_InitTypeDef i2c_pins = {0}; i2c_pins.Pin = GPIO_PIN_6 | GPIO_PIN_7; i2c_pins.Mode = GPIO_MODE_AF_OD; // 改为开漏输出 i2c_pins.Pull = GPIO_PULLUP; // 开启内部上拉,若已有外部上拉可保留GPIO_NOPULL i2c_pins.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // 补充引脚速度配置 i2c_pins.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &i2c_pins);
2. 补全I2C初始化参数
你注释了DutyCycle的赋值,结构体成员未初始化会导致I2C参数校验失败,取消注释并补全所有必要配置:
hi2c1.Instance = I2C1; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; // 取消注释 hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) Error_Handler();
3. 调整MPU6050初始化时序
MPU6050软复位后需要等待至少50ms才能响应后续指令,调整复位后的延时参数,同时替换永久等待的超时配置:
buffer[0] = 0x6B; buffer[1] = 0x80; // 超时改为1s,不要用HAL_MAX_DELAY避免永久卡死 if(HAL_I2C_Master_Transmit(&hi2c1, MPU_ADDRESS, buffer, 2, 1000) != HAL_OK){ Error_Handler(); } HAL_Delay(50); // 复位后延时从10ms改为50ms
所有I2C读写操作都建议按上述格式增加返回值判断,通信异常时直接进入错误处理,方便快速定位问题。
4. 可选验证步骤
- 确认MPU6050的AD0引脚电平,若接高电平,7位地址为0x69,对应地址宏定义需改为
0xD2 - 检查MPU6050的供电是否为3.3V,部分5V供电的模块可能存在电平兼容问题
- 可先运行I2C扫描程序确认设备地址是否能被正常识别,排除硬件接线错误
内容的提问来源于stack exchange,提问作者Froggy Chair
相关产品推荐
相关产品推荐

