1. 介绍
3轴陀螺仪+3轴加速度
3轴陀螺仪,可编程FSR为±250dps、±500dps、±1000dps和±2000 dps;
3轴加速度计,可编程FSR为±2g、±4g、±8g和±16g;
用户可编程中断:
动作响应中断,用于应用处理器低功耗运行
1KB FIFO缓冲区使应用程序处理器能够分批读取数据
片上16位ADC和可编程滤波器
通讯主机接口:
SPI - 10MHz
I2C - 400kHz
数字输出温度传感器
VDD工作范围为1.71V至3.45V
2. 使用
器件引脚及轴向:
原理图:
代码:
while(ICM20602_ReadID() == 0) //读取ID
{
HAL_Delay(500);
}
ICM20602_INIT(); //初始化
#define MPU6050_RA_WHO_AM_I 0x75
uint8_t ICM20602_ReadID(void)
{
unsigned char Re = 0;
MPU6050_ReadData(MPU6050_RA_WHO_AM_I,&Re,1); //根据6050改的.....
if(Re != 0x12) //注意读取数据
{
printf("ICM20602 dectected error! --0x%X \r\n", Re);
return 0;
}
else
{
printf("ICM20602 ID = 0x%X\r\n",Re);
return 1;
}
}
#define MPU6050_SLAVE_ADDRESS (0x68<<1) //地址 AD0接地 为0x68 高电平0x69
void MPU6050_ReadData(uint8_t reg_add,unsigned char*Read,uint8_t num)
{
unsigned char i;
i2c_Start();
i2c_SendByte(MPU6050_SLAVE_ADDRESS);
i2c_WaitAck();
i2c_SendByte(reg_add);
i2c_WaitAck();
i2c_Start();
i2c_SendByte(MPU6050_SLAVE_ADDRESS+1);
i2c_WaitAck();
for(i=0;i<(num-1);i++){
*Read=i2c_ReadByte(1);
Read++;
}
*Read=i2c_ReadByte(0);
i2c_Stop();
}
void MPU6050_WriteReg(uint8_t reg_add,uint8_t reg_dat)
{
i2c_Start();
i2c_SendByte(MPU6050_SLAVE_ADDRESS);
i2c_WaitAck();
i2c_SendByte(reg_add);
i2c_WaitAck();
i2c_SendByte(reg_dat);
i2c_WaitAck();
i2c_Stop();
}
#define MPU6050_RA_PWR_MGMT_1 0x6B
#define MPU6050_RA_PWR_MGMT_2 0x6C
#define MPU6050_RA_CONFIG 0x1A
#define MPU6050_RA_SMPLRT_DIV 0x19
#define MPU6050_RA_GYRO_CONFIG 0x1B
#define MPU6050_RA_ACCEL_CONFIG 0x1C
void ICM20602_INIT(void)
{
HAL_Delay(30);
//MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x80); //复位
//HAL_Delay(80);
MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x01); //时钟设置
MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_2, 0x00); //使能陀螺仪和加速度计
MPU6050_WriteReg(MPU6050_RA_CONFIG , 0x01); //176Hz
MPU6050_WriteReg(MPU6050_RA_SMPLRT_DIV , 0x07); // 采样速率
MPU6050_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x18); //+-2000
MPU6050_WriteReg(MPU6050_RA_ACCEL_CONFIG , 0x00); //+-8g
}
#define MPU6050_ACC_OUT 0x3B
void get_icm20602_AccData_IIC(short *accData) //获取加速度
{
uint8_t buf[6];
MPU6050_ReadData(MPU6050_ACC_OUT, buf, 6); //
accData[0] = ((buf[0] << 8) | buf[1]);
accData[1] = ((buf[2] << 8) | buf[3]);
accData[2] = ((buf[4] << 8) | buf[5]);
}
#define MPU6050_GYRO_OUT 0x43
void get_icm20602_GyroData_IIC(short *gyroData) //获取角速度
{
uint8_t buf[6];
MPU6050_ReadData(MPU6050_GYRO_OUT,buf,6);
gyroData[0] = ((buf[0] << 8) | buf[1]);
gyroData[1] = ((buf[2] << 8) | buf[3]);
gyroData[2] = ((buf[4] << 8) | buf[5]);
}
void ICM_20602_Data(void)
{
float accx, accy, accz;
get_icm20602_AccData_IIC(ACC_DATA); //Acc Get
// get_icm20602_GyroData_IIC(GYRO_DATA); //Gyro Get
//Get_Accx_ShortData_Average(ACC_DATA[0]); //accx-average out -> accx_DATA_GET
//Get_Accy_ShortData_Average(ACC_DATA[1]); //accy-average out -> accy_DATA_GET
//Get_Accz_ShortData_Average(ACC_DATA[2]); //accz-average out -> accz_DATA_GET
accel_x = ACC_DATA[0];
accel_y = ACC_DATA[1];
accel_z = ACC_DATA[2];
if(accel_x<32764)
{
accx=accel_x/(16384.0); //0-1g
}
else
{
accx=1-(accel_x-49152)/16384.0;
}
if(accel_y<32764)
{
accy=accel_y/16384.0;
}
else
{
accy=1-(accel_y-49152)/16384.0;
}
if(accel_z<32764)
{
accz=accel_z/16384.0;
}
else
{
accz=(accel_z-49152)/16384.0;
}
// pitch_raw=(atan(accy/accz))*180/3.14;
pitch_raw= atan2(accy,accz)*180/3.14;
roll_raw = atan2(accx,accz)*180/3.14;
for(int i=9; i>0; i--)
{
base_pedal_pitch_buf[i] = base_pedal_pitch_buf[i-1];
}
base_pedal_pitch_buf[0] = pitch_raw*(-1);
pitch_raw = (base_pedal_pitch_buf[0]+base_pedal_pitch_buf[1]+base_pedal_pitch_buf[2]+base_pedal_pitch_buf[3]+base_pedal_pitch_buf[4]
+base_pedal_pitch_buf[5]+base_pedal_pitch_buf[6]+base_pedal_pitch_buf[7]+base_pedal_pitch_buf[8]+base_pedal_pitch_buf[9])/10.0f;
for(int i=9; i>0; i--)
{
base_pedal_roll_buf[i] = base_pedal_roll_buf[i-1];
}
base_pedal_roll_buf[0] = roll_raw;
roll_raw = (base_pedal_roll_buf[0]+base_pedal_roll_buf[1]+base_pedal_roll_buf[2]+base_pedal_roll_buf[3]+base_pedal_roll_buf[4]
+base_pedal_roll_buf[5]+base_pedal_roll_buf[6]+base_pedal_roll_buf[7]+base_pedal_roll_buf[8]+base_pedal_roll_buf[9])/10.0f;
/*angleChange*/
}
.h文件
void ICM_20602_Data(void);
uint8_t ICM20602_ReadID(void);
void ICM20602_INIT(void);
void get_icm20602_AccData_IIC(short *accData);
void get_icm20602_GyroData_IIC(short *gyroData);