天天看點

stm32 iic接口 進入busy_STM32通過IIC接口讀取JY61子產品MPU6050陀螺儀晶片資料核心程式...

1 簡述

最近,想學角度融合算法在網上買一個JY61的子產品。他們家的子產品用起來還不錯。子產品分為序列槽通訊和IIC通訊的。序列槽讀取資料他們家有例程,我就不說了。想分享給大家這個子產品的IIC是怎麼去讀取MPU6050晶片資料的。

stm32 iic接口 進入busy_STM32通過IIC接口讀取JY61子產品MPU6050陀螺儀晶片資料核心程式...

想要讀取MPU6050晶片,其實就是通過IIC去操作讀取寄存器。注意子產品預設是序列槽直接輸出資料的,需要先将子產品設定為IIC模式後,才可以直接通路MPU6050晶片,不過因為角度資料是子產品内部算法解出來的,用IIC接口無法擷取到傳感器角度資料了,如果要用IIC接口通路到角度資料需要選這他家的JY61P或者JY901。

連接配接的大緻過程就是STM32和MPU6050先建立好IIC通訊。再去初始化MPU6050晶片。然後單片機再去讀取寄存器,就能把資料讀取出來了。

2 配置32單片機的IIC引腳

根據你32單片機的原理圖,找到你的IIC引腳。

  • 時鐘RCC的配置

以我自己寫的為例子。

stm32 iic接口 進入busy_STM32通過IIC接口讀取JY61子產品MPU6050陀螺儀晶片資料核心程式...
  • GPIO口的配置
stm32 iic接口 進入busy_STM32通過IIC接口讀取JY61子產品MPU6050陀螺儀晶片資料核心程式...

注意:SCL和SDA都得接上兩個4.7K的電阻。不然你是讀取不到MPU6050的資料。

  • STM32的IIC的配置
stm32 iic接口 進入busy_STM32通過IIC接口讀取JY61子產品MPU6050陀螺儀晶片資料核心程式...

3 初始化 MPU6050

void MPU6050_Initialize()        
         {        
              MPU6050_I2C_ByteWrite(0xd0,0x00,MPU6050_RA_PWR_MGMT_1);     
              MPU6050_I2C_ByteWrite(0xd0,0x07,MPU6050_RA_SMPLRT_DIV);   
              MPU6050_I2C_ByteWrite(0xd0,0x06,MPU6050_RA_CONFIG);                 
              MPU6050_I2C_ByteWrite(0xd0,0x01,MPU6050_RA_ACCEL_CONFIG);     
              MPU6050_I2C_ByteWrite(0xd0,0x18,MPU6050_RA_GYRO_CONFIG);      
         }
           

注意:0xD0 表示 MPU6050 的位址。MPU6050有 8 位的位址,前 7 位由 WHO AM I 确定,第 8 位由 AD0 的電平決定。WHO AM I 預設值是 0x68H(1101000B),AD0 接低電平,是以 MPU6050 的 I2C 位址是 0xD0H(11010000B)。

4 核心讀取程式

總結: 發送開始信号 -> 起始成功? -> 發送 MPU6050 位址、狀态(寫)-> 寫位址成功? -> 發送 MPU6050内部某個待寫寄存器位址 -> 發送成功? -> 發送要寫入的内容 -> 發送成功? -> 發送結束信号

void MPU6050_I2C_BufferRead(u8 slaveAddr, u8* pBuffer, u8 readAddr, u16 NumByteToRead)
{
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
  I2C_GenerateSTART(I2C1, ENABLE);//發送開始條件
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//在EV5上測試并清除
  I2C_Send7bitAddress(I2C1, slaveAddr, I2C_Direction_Transmitter); //發送MOU6050位址進行寫操作
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//在EV6上測試并清除
  I2C_Cmd(I2C1, ENABLE);//通過再次設定PE位來清除EV6
  I2C_SendData(I2C1, readAddr);//發送MPU6050的内部位址來寫入
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//在EV8上測試并清除
  I2C_GenerateSTART(I2C1, ENABLE);//第二次發送STRAT條件
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//在EV5上測試并清除
  I2C_Send7bitAddress(I2C1, slaveAddr, I2C_Direction_Receiver);//發送MOU6050位址進行寫操作
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//在EV6上測試并清除
  while(NumByteToRead)//當有資料被讀取到的時候
  {
    if(NumByteToRead == 1)
    {
      I2C_AcknowledgeConfig(I2C1, DISABLE);//Acknowledge不使能
      I2C_GenerateSTOP(I2C1, ENABLE);//發送停止條件
    }
    if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))//在EV7上測試并清除
    {
      *pBuffer = I2C_ReceiveData(I2C1);//從MPU6050讀取一個位元組
      pBuffer++;//指向将儲存讀取的位元組的下一個位置
      NumByteToRead--;//讀取位元組計數器減一
    }
  }
  I2C_AcknowledgeConfig(I2C1, ENABLE);//啟用确認以準備再次接收
}