16_MPU6050
MPU6050
MPU6050简介
MPU6050参数
硬件电路
MPU6050框图
软件I2C读写MPU6050
接线图
MPU6050原地址为:0xD0
AD0接口接高电平后,地址为:0xD2
代码
MyI2C.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
void MyI2C_w_SCL(uint8_t BitValue)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_10,(BitAction)BitValue);
Delay_us(10);
}
void MyI2C_w_SDA(uint8_t BitValue)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_11,(BitAction)BitValue);
Delay_us(10);
}
uint8_t MyI2C_R_SDA(void)
{
uint8_t BitValue = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11);
Delay_us(10);
return BitValue;
}
void MyI2C_Init(void) //软件I2C
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_OD; //开漏输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10 | GPIO_Pin_11; //PB10:SCL PB11:SDA
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
}
void MyI2C_Start(void)
{
MyI2C_w_SDA(1);
MyI2C_w_SCL(1);
MyI2C_w_SDA(0);
MyI2C_w_SCL(0);
}
void MyI2C_Stop(void)
{
MyI2C_w_SDA(0);
MyI2C_w_SCL(1);
MyI2C_w_SDA(1);
}
void MyI2C_SendByte(uint8_t Byte)
{
for(int8_t i=0;i<8;i++)
{
MyI2C_w_SDA(Byte&(0x80>>i));
MyI2C_w_SCL(1);
MyI2C_w_SCL(0);
}
}
uint8_t MyI2C_ReceiveByte(void)
{
uint8_t Byte=0x00;
MyI2C_w_SDA(1); //释放SDA
for(int8_t i=7;i>=0;i--) //不能用uint8_t到0之后会变成255
{
MyI2C_w_SCL(1);
Byte|=(MyI2C_R_SDA()<<i);
MyI2C_w_SCL(0);
}
return Byte;
}
void MyI2C_SendAck(uint8_t AckByte)
{
MyI2C_w_SDA(AckByte);
MyI2C_w_SCL(1);
MyI2C_w_SCL(0);
}
uint8_t MyI2C_ReceiveAck(void)
{
uint8_t AckByte;
MyI2C_w_SDA(1); //释放SDA
MyI2C_w_SCL(1);
AckByte=MyI2C_R_SDA();
MyI2C_w_SCL(0);
return AckByte;
}
MyI2C.h
#ifndef __MYI2C_H__
#define __MYI2C_H__
void MyI2C_Init(void); //软件I2C
void MyI2C_Start(void);
void MyI2C_Stop(void);
void MyI2C_SendByte(uint8_t Byte);
uint8_t MyI2C_ReceiveByte(void);
void MyI2C_SendAck(uint8_t AckByte);
uint8_t MyI2C_ReceiveAck(void);
#endif
MPU6050.c
#include "stm32f10x.h" // Device header
#include "MyI2C.h"
#include "MPU6050_Reg.h"
#include "MPU6050.h"
#define MPU6050_ADDRESS 0xD0 //AD0接高电平地址为:0xD2
void MPU6050_Init(void)
{
MyI2C_Init();
MPU6050_WriteReg(MPU6050_PWR_MGMT_1,0x01); //解除睡眠模式,使用x轴陀螺仪时钟
MPU6050_WriteReg(MPU6050_PWR_MGMT_2,0x00); //六个轴均不待机
MPU6050_WriteReg(MPU6050_SMPLRT_DIV,0x09); //采样率分频:10分频
MPU6050_WriteReg(MPU6050_CONFIG,0x06); //配置寄存器
MPU6050_WriteReg(MPU6050_GYRO_CONFIG,0x18); //陀螺仪配置寄存器
MPU6050_WriteReg(MPU6050_ACCEL_CONFIG,0x18); //加速度计配置寄存器
}
void MPU6050_WriteReg(uint8_t RegAddress,uint8_t Data)
{
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_SendByte(Data);
MyI2C_ReceiveAck();
MyI2C_Stop();
}
void MPU6050_WriteMulReg(uint8_t RegAddress,uint8_t *Data) //多字节写入
{
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
for(uint8_t i=0;i<sizeof(Data);i++)
{
MyI2C_SendByte(Data[i]);
MyI2C_ReceiveAck();
}
MyI2C_Stop();
}
uint8_t MPU6050_ReadReg(uint8_t RegAddress) //读一个字节
{
uint8_t Byte;
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS|0x01); //读
MyI2C_ReceiveAck();
Byte = MyI2C_ReceiveByte();
MyI2C_SendAck(1); //0:继续读 1:停止读
MyI2C_Stop();
return Byte;
}
void MPU6050_ReadMulReg(uint8_t RegAddress, uint8_t* result) //读多个字节
{
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS|0x01); //读
MyI2C_ReceiveAck();
for(uint8_t i=0;i<sizeof(result);i++)
{
result[i] = MyI2C_ReceiveByte();
if(i==sizeof(result)-1)
{
MyI2C_SendAck(1); //0:继续读 1:停止读
}
else
{
MyI2C_SendAck(0); //0:继续读 1:停止读
}
}
MyI2C_Stop();
}
void MPU6050_GetData(int16_t *AccX,int16_t *AccY,int16_t *AccZ,
int16_t *GyroX,int16_t *GyroY,int16_t *GyroZ)
{
uint8_t DataH, DataL;
DataH=MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H); //加速度X轴寄存器高八位
DataL=MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L); //加速度X轴寄存器低八位
*AccX=(DataH<<8)|DataL;
DataH=MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H); //加速度Y轴寄存器高八位
DataL=MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L); //加速度Y轴寄存器低八位
*AccY=(DataH<<8)|DataL;
DataH=MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H); //加速度Z轴寄存器高八位
DataL=MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L); //加速度Z轴寄存器低八位
*AccZ=(DataH<<8)|DataL;
DataH=MPU6050_ReadReg(MPU6050_GYRO_XOUT_H); //陀螺仪X轴寄存器高八位
DataL=MPU6050_ReadReg(MPU6050_GYRO_XOUT_H); //陀螺仪X轴寄存器低八位
*GyroX=(DataH<<8)|DataL;
DataH=MPU6050_ReadReg(MPU6050_GYRO_YOUT_H); //陀螺仪Y轴寄存器高八位
DataL=MPU6050_ReadReg(MPU6050_GYRO_YOUT_H); //陀螺仪Y轴寄存器低八位
*GyroY=(DataH<<8)|DataL;
DataH=MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H); //陀螺仪Z轴寄存器高八位
DataL=MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H); //陀螺仪Z轴寄存器低八位
*GyroZ=(DataH<<8)|DataL;
}
MPU6050.h
#ifndef __MPU6050_H__
#define __MPU6050_H__
void MPU6050_Init(void);
void MPU6050_WriteReg(uint8_t RegAddress,uint8_t Data);
void MPU6050_WriteMulReg(uint8_t RegAddress,uint8_t *Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);
void MPU6050_ReadMulReg(uint8_t RegAddress, uint8_t* result);
void MPU6050_GetData(int16_t *AccX,int16_t *AccY,int16_t *AccZ,
int16_t *GyroX,int16_t *GyroY,int16_t *GyroZ);
#endif
MPU6050_Reg.h
#ifndef __MPU6050_REG_H__
#define __MPU6050_REG_H__
#define MPU6050_SMPLRT_DIV 0x19
#define MPU6050_CONFIG 0x1A
#define MPU6050_GYRO_CONFIG 0x1B
#define MPU6050_ACCEL_CONFIG 0x1C
#define MPU6050_ACCEL_XOUT_H 0x3B
#define MPU6050_ACCEL_XOUT_L 0x3C
#define MPU6050_ACCEL_YOUT_H 0x3D
#define MPU6050_ACCEL_YOUT_L 0x3E
#define MPU6050_ACCEL_ZOUT_H 0x3F
#define MPU6050_ACCEL_ZOUT_L 0x40
#define MPU6050_TEMP_OUT_H 0x41
#define MPU6050_TEMP_OUT_L 0x42
#define MPU6050_GYRO_XOUT_H 0x43
#define MPU6050_GYRO_XOUT_L 0x44
#define MPU6050_GYRO_YOUT_H 0x45
#define MPU6050_GYRO_YOUT_L 0x46
#define MPU6050_GYRO_ZOUT_H 0x47
#define MPU6050_GYRO_ZOUT_L 0x48
#define MPU6050_PWR_MGMT_1 0x6B
#define MPU6050_PWR_MGMT_2 0x6C
#define MPU6050_WHO_AM_I 0x75
#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "MPU6050.h"
int16_t AX,AY,AZ,GX,GY,GZ;
int main(void)
{
OLED_Init();
MPU6050_Init();
while(1)
{
MPU6050_GetData(&AX,&AY,&AZ,&GX,&GY,&GZ);
OLED_ShowSignedNum(2,1,AX,5);
OLED_ShowSignedNum(3,1,AY,5);
OLED_ShowSignedNum(4,1,AZ,5);
OLED_ShowSignedNum(2,8,GX,5);
OLED_ShowSignedNum(3,8,GY,5);
OLED_ShowSignedNum(4,8,GZ,5);
}
}