1 簡述
最近,想學角度融合算法在網上買一個JY61的子產品。他們家的子產品用起來還不錯。子產品分為序列槽通訊和IIC通訊的。序列槽讀取資料他們家有例程,我就不說了。想分享給大家這個子產品的IIC是怎麼去讀取MPU6050晶片資料的。
想要讀取MPU6050晶片,其實就是通過IIC去操作讀取寄存器。注意子產品預設是序列槽直接輸出資料的,需要先将子產品設定為IIC模式後,才可以直接通路MPU6050晶片,不過因為角度資料是子產品内部算法解出來的,用IIC接口無法擷取到傳感器角度資料了,如果要用IIC接口通路到角度資料需要選這他家的JY61P或者JY901。
連接配接的大緻過程就是STM32和MPU6050先建立好IIC通訊。再去初始化MPU6050晶片。然後單片機再去讀取寄存器,就能把資料讀取出來了。
2 配置32單片機的IIC引腳
根據你32單片機的原理圖,找到你的IIC引腳。
- 時鐘RCC的配置
以我自己寫的為例子。
- GPIO口的配置
注意:SCL和SDA都得接上兩個4.7K的電阻。不然你是讀取不到MPU6050的資料。
- STM32的IIC的配置
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);//啟用确認以準備再次接收
}