MPU6050.c
#include "stm32f10x.h"
#include "MPU6050_SEG.h"
#define MPU_ADDRESS 0xD0
/*
* 等待事件 带超时退出机制
* 将while与I2C_CheckEvent封装在一起
*/
void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
uint32_t Timeout=50000;
while(Timeout && (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS))
{
Timeout --;
}
}
/*
* 往指定地址写入指定数据
*/
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{
// 起始条件
I2C_GenerateSTART(I2C2, ENABLE);
// 等待 EV5
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);
// 呼叫设备(MPU6050)
I2C_Send7bitAddress(I2C2, MPU_ADDRESS, I2C_Direction_Transmitter);
// 等待 EV6
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);
// 寻找写入地址
I2C_SendData(I2C2, RegAddress);
// 等待EV8
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);
// 写入数据
I2C_SendData(I2C2, Data);
// 等待EV8_2
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);
// 终止条件
I2C_GenerateSTOP(I2C2, ENABLE);
}
/*
* 从指定地址读取数据
*/
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
uint8_t Data;
// 起始条件
I2C_GenerateSTART(I2C2, ENABLE); // 起始条件
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); // 等待 EV5
I2C_Send7bitAddress(I2C2, MPU_ADDRESS, I2C_Direction_Transmitter); //呼叫设备 写
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); // 等待 EV6
I2C_SendData(I2C2, RegAddress); // 寻找读取地址
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED); // 等待EV8_2
I2C_GenerateSTART(I2C2, ENABLE); // 再次产生起始条件
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); // 等待 EV5
I2C_Send7bitAddress(I2C2, MPU_ADDRESS, I2C_Direction_Receiver); // 呼叫设备 读
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED); // 等待 EV6
I2C_AcknowledgeConfig(I2C2, DISABLE); // 关闭应答
I2C_GenerateSTOP(I2C2, ENABLE); // 终止条件
MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED); // 等待EV7
Data = I2C_ReceiveData(I2C2); // 接收数据
I2C_AcknowledgeConfig(I2C2, ENABLE); // 开启应答
return Data;
}
/*
* 配置MPU6050
*/
void MPU6050_Init(void)
{
// I2C初始化
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD; // 复用开漏
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// I2C
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Ack=I2C_Ack_Enable; // 有应答
I2C_InitStructure.I2C_ClockSpeed=50000; // 400 kHz以下 100 kHz以上为快速通讯
I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2; // 低电平比高电平2:1 仅在快速通讯生效
I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
// 从模式下 stm32作为从机的地址所占位数
I2C_InitStructure.I2C_OwnAddress1=0x00; // 从模式下stm32作为从机的地址
I2C_Init(I2C2, &I2C_InitStructure);
// 开启I2C2
I2C_Cmd(I2C2, ENABLE);
MPU6050_WriteReg(PWR_MGMT_1, 0x01);
MPU6050_WriteReg(PWR_MGMT_2, 0x00);
MPU6050_WriteReg(SMPLRT_DIV, 0x09);
MPU6050_WriteReg(CONFIG, 0x06);
MPU6050_WriteReg(GYRO_CONFIG, 0x18);
MPU6050_WriteReg(ACCEL_CONFIG, 0x18);
}
/*
* 获取ID号
*/
uint8_t MPU6050_GetID(void)
{
return MPU6050_ReadReg(WHO_AM_I);
}
/*
* 获取MPU6050数据
*/
void MPU6050_GetData(MPU6050_DataTypeDef * MPU_DataStructure)
{
uint16_t Data_H, Data_L; // 高位数据和低位数据
Data_H = MPU6050_ReadReg(ACCEL_XOUT_H);
Data_L = MPU6050_ReadReg(ACCEL_XOUT_L);
MPU_DataStructure->AccX=(Data_H<<8) | Data_L;
Data_H = MPU6050_ReadReg(ACCEL_YOUT_H);
Data_L = MPU6050_ReadReg(ACCEL_YOUT_L);
MPU_DataStructure->AccY=(Data_H<<8) | Data_L;
Data_H = MPU6050_ReadReg(ACCEL_ZOUT_H);
Data_L = MPU6050_ReadReg(ACCEL_ZOUT_L);
MPU_DataStructure->AccZ=(Data_H<<8) | Data_L;
Data_H = MPU6050_ReadReg(GYRO_XOUT_H);
Data_L = MPU6050_ReadReg(GYRO_XOUT_L);
MPU_DataStructure->GyroX=(Data_H<<8) | Data_L;
Data_H = MPU6050_ReadReg(GYRO_YOUT_H);
Data_L = MPU6050_ReadReg(GYRO_YOUT_L);
MPU_DataStructure->GyroY=(Data_H<<8) | Data_L;
Data_H = MPU6050_ReadReg(GYRO_ZOUT_H);
Data_L = MPU6050_ReadReg(GYRO_ZOUT_L);
MPU_DataStructure->GyroZ=(Data_H<<8) | Data_L;
}
|