用模拟I2C读取MP6050,读取WHO_AM_I寄存器的值为0.。。困扰几天了

2019-08-18 20:55发布

用模拟I2C读取MP6050,读取WHO_AM_I寄存器的值为0,很烦人!!!!
模拟I2C
/*******************************************************************************
* Function Name  : I2C_GPIO_Config
* Description    : Configration Simulation IIC GPIO
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_INIT(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_GPIO_I2C, ENABLE);  //使能GPIOB时钟

        GPIO_InitStructure.GPIO_Pin =  SCL_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  
  GPIO_Init(GPIO_I2C, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  SDA_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  GPIO_Init(GPIO_I2C, &GPIO_InitStructure);
        delay(0XFFF);
}
/*******************************************************************************
* Function Name  : I2C_delay
* Description    : Simulation IIC Timing series delay
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_delay(void)
{
        __NOP();
}
void delay5ms(void)
{
               
   int i=5000;  
   while(i)
   {
     i--;
   }  
}
/*******************************************************************************
* Function Name  : I2C_Start
* Description    : Master Start Simulation IIC Communication
* Input          : None
* Output         : None
* Return         : Wheather         Start
****************************************************************************** */
uint16_t I2C_Start(void)
{
        SDA_H;
        SCL_H;
        I2C_delay();
        if(!SDA_read)return FALSE;        //SDA线为低电平则总线忙,退出
        SDA_L;
        I2C_delay();
        if(SDA_read) return FALSE;        //SDA线为高电平则总线出错,退出
        SDA_L;
        I2C_delay();
        return TRUE;
}
/*******************************************************************************
* Function Name  : I2C_Stop
* Description    : Master Stop Simulation IIC Communication
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_Stop(void)
{
        SCL_L;
        I2C_delay();
        SDA_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SDA_H;
        I2C_delay();
}
/*******************************************************************************
* Function Name  : I2C_Ack
* Description    : Master Send Acknowledge Single
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_Ack(void)
{       
        SCL_L;
        I2C_delay();
        SDA_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SCL_L;
        I2C_delay();
}   
/*******************************************************************************
* Function Name  : I2C_NoAck
* Description    : Master Send No Acknowledge Single
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_NoAck(void)
{       
        SCL_L;
        I2C_delay();
        SDA_H;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SCL_L;
        I2C_delay();
}
/*******************************************************************************
* Function Name  : I2C_WaitAck
* Description    : Master Reserive Slave Acknowledge Single
* Input          : None
* Output         : None
* Return         : Wheather         Reserive Slave Acknowledge Single
****************************************************************************** */
uint16_t I2C_WaitAck(void)          //返回为:=1有ACK,=0无ACK
{
        SCL_L;
        I2C_delay();
        SDA_H;                       
        I2C_delay();
        SCL_H;
        I2C_delay();
        if(SDA_read)
        {
      SCL_L;
          I2C_delay();
      return FALSE;
        }
        SCL_L;
        I2C_delay();
        return TRUE;
}
/*******************************************************************************
* Function Name  : I2C_SendByte
* Description    : Master Send a Byte to Slave
* Input          : Will Send Date
* Output         : None
* Return         : None
****************************************************************************** */
void I2C_SendByte(unsigned char SendByte) //数据从高位到低位//
{
    u8 i=8;
    while(i--)
    {
        SCL_L;
        I2C_delay();
      if(SendByte&0x80)
        SDA_H;  
      else
        SDA_L;   
        SendByte<<=1;
        I2C_delay();
                SCL_H;
        I2C_delay();
    }
    SCL_L;
}  
/*******************************************************************************
* Function Name  : I2C_RadeByte
* Description    : Master Reserive a Byte From Slave
* Input          : None
* Output         : None
* Return         : Date From Slave
****************************************************************************** */
unsigned char I2C_RadeByte(void)  //数据从高位到低位//
{
    u8 i=8;
    u8 ReceiveByte=0;

    SDA_H;                               
    while(i--)
    {
      ReceiveByte<<=1;      
      SCL_L;
      I2C_delay();
          SCL_H;
      I2C_delay();       
      if(SDA_read)
      {
        ReceiveByte|=0x01;
      }
    }
    SCL_L;
    return ReceiveByte;
}
//ZRX         
//单字节写入*******************************************

uint16_t Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data)                     //void
{
          if(!I2C_Start())return FALSE;
    I2C_SendByte(SlaveAddress);   //发送设备地址+写信号//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//设置高起始地址+器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
    I2C_SendByte(REG_Address );   //设置低起始地址      
    I2C_WaitAck();       
    I2C_SendByte(REG_data);
    I2C_WaitAck();   
    I2C_Stop();
    delay5ms();
    return TRUE;
}


//单字节读取*****************************************
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address)
{  
        unsigned char REG_data;
        if(!I2C_Start())return FALSE;
    I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址
    if(!I2C_WaitAck()){I2C_Stop();return FALSE;}
    I2C_SendByte((u8) REG_Address);   //设置低起始地址      
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(SlaveAddress+1);
    I2C_WaitAck();

          REG_data= I2C_RadeByte();
    I2C_NoAck();
    I2C_Stop();
    //return TRUE;
        return REG_data;
}       

void I2C_Read(u8 addr_, u8 reg_, u8 len, u8 *buf)
{
        u8 i;
         // 起始信号
        I2C_Start();
       
        // 发送设备地址
        I2C_SendByte(addr_);   
       
        I2C_WaitAck();
       
        //发送存储单元地址
        I2C_SendByte(reg_);                  
        I2C_WaitAck();
       
        // 起始信号
        I2C_Start();

        //发送设备地址+读信号
        I2C_SendByte(addr_+1);     
        I2C_WaitAck();
        for (i=0; i<len; i++)                   //连续读取6个地址数据,存储中BUF
        {
                *(buf+i) = I2C_RadeByte();          //BUF[0]存储数据
                if (i == len-1)                I2C_NoAck();                   //最后一个数据需要回NOACK
                else                I2C_Ack();                     //回应ACK
        }
        I2C_Stop();                           //停止信号
        I2C_delay();
}

---------------------------------------------------
u8 Init_MPU6050(void)
{
               
          
       
        u8 ack;
        ack = Single_Read(MPU6050_Address, WHO_AM_I);
        if (!ack)
        {
                printf("初始化MPU6050失败!");
                printf("WHO_AM_I = %d",ack);
                /*Single_Write(MPU6050_Address,PWR_MGMT_1,0x40);
    delay_ms(30);
    Single_Write(MPU6050_Address,PWR_MGMT_1,0x00);
    return FALSE;*/
        }
       
        Single_Write(MPU6050_Address, PWR_MGMT_1, 0x00);          //解除休眠状态
        Single_Write(MPU6050_Address, SMPLRT_DIV, 0x07);     
        Single_Write(MPU6050_Address, CONFIGL, MPU6050_DLPF_BW_5);              //低通滤波
        Single_Write(MPU6050_Address, GYRO_CONFIG, GYRO_FS_1000);  //陀螺仪量程 +-1000
        Single_Write(MPU6050_Address, ACCEL_CONFIG, ACCEL_FS_4);   //加速度量程 +-4G
        //printf("h初始化MPU6050成功! ");
        return TRUE;
}

void Read_MPU6050()
{
                mpu6050_buffer[0] = Single_Read(MPU6050_Address,ACCEL_XOUT_H);
                mpu6050_buffer[1] = Single_Read(MPU6050_Address,ACCEL_XOUT_L);
                printf("ACCEL_XOUT_H:%d    ACCEL_XOUT_L:%d ",mpu6050_buffer[0],mpu6050_buffer[1]);
       
                mpu6050_buffer[2] = Single_Read(MPU6050_Address,ACCEL_YOUT_H);
                mpu6050_buffer[3] = Single_Read(MPU6050_Address,ACCEL_YOUT_L);
                printf("ACCEL_YOUT_H:%d    ACCEL_YOUT_L:%d ",mpu6050_buffer[2],mpu6050_buffer[3]);
       
                mpu6050_buffer[4] = Single_Read(MPU6050_Address,ACCEL_ZOUT_H);
                mpu6050_buffer[5] = Single_Read(MPU6050_Address,ACCEL_ZOUT_L);
                printf("ACCEL_ZOUT_H:%d    ACCEL_ZOUT_L:%d ",mpu6050_buffer[4],mpu6050_buffer[5]);
       
                mpu6050_buffer[6] = Single_Read(MPU6050_Address,TEMP_OUT_H);
                mpu6050_buffer[7] = Single_Read(MPU6050_Address,TEMP_OUT_L);
                printf("TEMP_OUT_H:%d    TEMP_OUT_L:%d ",mpu6050_buffer[6],mpu6050_buffer[7]);
       
                mpu6050_buffer[8] = Single_Read(MPU6050_Address,GYRO_XOUT_H);
                mpu6050_buffer[9] = Single_Read(MPU6050_Address,GYRO_XOUT_L);
                printf("GYRO_XOUT_H:%d    GYRO_XOUT_L:%d ",mpu6050_buffer[8],mpu6050_buffer[9]);
       
                mpu6050_buffer[10] = Single_Read(MPU6050_Address,GYRO_YOUT_H);
                mpu6050_buffer[11] = Single_Read(MPU6050_Address,GYRO_YOUT_L);
                printf("GYRO_YOUT_H:%d    GYRO_YOUT_L:%d ",mpu6050_buffer[10],mpu6050_buffer[11]);
               
                mpu6050_buffer[12] = Single_Read(MPU6050_Address,GYRO_ZOUT_H);
                mpu6050_buffer[13] = Single_Read(MPU6050_Address,GYRO_ZOUT_L);
                printf("GYRO_ZOUT_H:%d    GYRO_ZOUT_L:%d ",mpu6050_buffer[12],mpu6050_buffer[13]);
}

好气呀!printf("WHO_AM_I = %d",ack); ack也就是WHO_AM_I寄存器的值一直是0!
我用的是GY——86模块,I2C上还挂了个MS5611,还有个电子罗盘挂在MPU6050的辅助I2C上的!
各位帮我看一下吧!折磨我好几天了,谢谢了
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
正点原子
1楼-- · 2019-08-19 01:41
参考我们例程吧。
1950618179
2楼-- · 2019-08-19 07:06
正点原子 发表于 2017-5-17 21:05
参考我们例程吧。

嗯嗯,谢谢原子哥

一周热门 更多>