MPU6050 IIC通信查询地址时无ACK回复问题

问题描述

单片机与MPU6050 IIC通信时,查询6050地址,发送0xD0后第九个时钟上升沿SDA为高电平,即没有回复ACK.
在这里插入图片描述

排查

1.芯片是否有虚焊,短路(检查硬件走线正常)
2.MPU6050供电是否正常(我的电源是3.3V,SCL,SDA 4.7K电阻上拉电压3.3V)
3.通信时序是否正确(软件排查正常:IO设置,SCL时钟频率200Khz)
4.排除以上问题后,怀疑是否芯片是坏的?应该不可能

问题解决

各种排查失败后,无意中在单片机上电初始化时加个了20ms延时,竟然正常了。所以MPU6050上电后需要一定的时间来初始化,然后才能通信,否则会通信失败。

  ClockConfig();
  Delay_ms(20);
  VariableInit();	
  HardWareInit();
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的使用 STM32 的 I2C 库函数读取 MPU6050 加速度计和陀螺仪数据的示例代码: ```c #include "stm32f10x.h" #include "stm32f10x_i2c.h" #define MPU6050_ADDRESS 0xD0 void I2C_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; /* I2C1 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); /* GPIOB clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* Configure I2C1 pins: SCL and SDA */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); /* I2C1 configuration */ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 400000; I2C_Init(I2C1, &I2C_InitStructure); /* Enable I2C1 */ I2C_Cmd(I2C1, ENABLE); } void MPU6050_Init(void) { uint8_t data[2]; /* Configure MPU6050 */ data[0] = 0x6B; /* PWR_MGMT_1 register */ data[1] = 0x00; /* Reset */ I2C_Write(MPU6050_ADDRESS, data, 2); data[0] = 0x1A; /* CONFIG register */ data[1] = 0x03; /* DLPF_CFG = 3 (Fs = 1 kHz) */ I2C_Write(MPU6050_ADDRESS, data, 2); data[0] = 0x1B; /* GYRO_CONFIG register */ data[1] = 0x08; /* FS_SEL = 1 (±500 °/s) */ I2C_Write(MPU6050_ADDRESS, data, 2); data[0] = 0x1C; /* ACCEL_CONFIG register */ data[1] = 0x08; /* AFS_SEL = 1 (±4 g) */ I2C_Write(MPU6050_ADDRESS, data, 2); } void I2C_Write(uint8_t address, uint8_t *data, uint8_t length) { /* While the bus is busy */ while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); /* Generate the start condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Wait until the start condition is sent */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send the slave address and enable writing */ I2C_Send7bitAddress(I2C1, address, I2C_Direction_Transmitter); /* Wait until the address is sent */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Send the data */ while(length--) { I2C_SendData(I2C1, *data++); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); } /* Generate the stop condition */ I2C_GenerateSTOP(I2C1, ENABLE); } void I2C_Read(uint8_t address, uint8_t *data, uint8_t length) { /* While the bus is busy */ while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); /* Generate the start condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Wait until the start condition is sent */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send the slave address and enable reading */ I2C_Send7bitAddress(I2C1, address, I2C_Direction_Receiver); /* Wait until the address is sent */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* Receive the data */ while(length--) { if(length == 0) { I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_GenerateSTOP(I2C1, ENABLE); } while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); *data++ = I2C_ReceiveData(I2C1); } I2C_AcknowledgeConfig(I2C1, ENABLE); } int main(void) { uint8_t data[14]; /* Configure I2C */ I2C_Configuration(); /* Initialize MPU6050 */ MPU6050_Init(); while(1) { /* Read accelerometer and gyroscope data */ data[0] = 0x3B; /* ACCEL_XOUT_H register */ I2C_Write(MPU6050_ADDRESS, data, 1); I2C_Read(MPU6050_ADDRESS, data, 14); /* Process accelerometer data */ int16_t ax = (data[0] << 8) | data[1]; int16_t ay = (data[2] << 8) | data[3]; int16_t az = (data[4] << 8) | data[5]; /* Process gyroscope data */ int16_t gx = (data[8] << 8) | data[9]; int16_t gy = (data[10] << 8) | data[11]; int16_t gz = (data[12] << 8) | data[13]; } } ``` 在上面的示例代码中,`I2C_Configuration()` 函数用于配置 I2C1 的 GPIO 和参数,`MPU6050_Init()` 函数用于配置 MPU6050 的寄存器,`I2C_Write()` 和 `I2C_Read()` 函数分别用于向 MPU6050 写入数据和读取数据。在主函数中,我们循环读取 MPU6050 的加速度计和陀螺仪数据,并对数据进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值