Bootstrap

软件I2C读写MPU6050

硬件图片

在这里插入图片描述

需要新建的文件夹

在这里插入图片描述

1、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     //加速度计X轴高位
#define	MPU6050_ACCEL_XOUT_L	0x3C     //加速度计X轴底位
#define	MPU6050_ACCEL_YOUT_H	0x3D     //加速度计Y轴高位
#define	MPU6050_ACCEL_YOUT_L	0x3E     //加速度计Y轴底位
#define	MPU6050_ACCEL_ZOUT_H	0x3F     //加速度计Z轴高位
#define	MPU6050_ACCEL_ZOUT_L	0x40     //加速度计Z轴底位
#define	MPU6050_TEMP_OUT_H		0x41     //温度测量值高位     
#define	MPU6050_TEMP_OUT_L		0x42     //温度测量值低位
#define	MPU6050_GYRO_XOUT_H		0x43     //陀螺仪X轴高位
#define	MPU6050_GYRO_XOUT_L		0x44     //陀螺仪X轴低位
#define	MPU6050_GYRO_YOUT_H		0x45     //陀螺仪Y轴高位
#define	MPU6050_GYRO_YOUT_L		0x46     //陀螺仪Y轴低位
#define	MPU6050_GYRO_ZOUT_H		0x47     //陀螺仪Z轴高位
#define	MPU6050_GYRO_ZOUT_L		0x48     //陀螺仪Z轴低位
 
#define	MPU6050_PWR_MGMT_1		0x6B     //电源管理1
#define	MPU6050_PWR_MGMT_2		0x6C     //电源管理2
#define	MPU6050_WHO_AM_I		0x75     //设备ID

#endif
MPU6050.h文件内容
#ifndef __MPU6050_H
#define __MPU6050_H

#include "stm32f10x.h" 

void MPU6050_writeReg(uint8_t RegAddress,uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);
void MPU6050_Init(void);
void MPU6050_GetData(int16_t *AccX,int16_t *AccY,int16_t *AccZ,
					int16_t *GyroX,int16_t *GyroY,int16_t *GyroZ);
uint8_t MPU6050_GetID(void);

#endif

2、写MPU6050寄存器函数
2.1写单个字节

在这里插入图片描述

#include "MPU6050.h"
#include "I2C.h"
#include "MPU6050_Reg.h"

#define MPU6050_ADDRESS 0xD0

/**
  * 函数功能:MPU6050写1个寄存器
  * 入口参数:RegAddress: 需要操作的MPU6050地址
  * 入口参数:Data:需要写入的数据
  * 返 回 值:无
  */
void MPU6050_writeReg(uint8_t RegAddress,uint8_t Data) //写数据
{
	/*发送从机地址*/
	MyI2C_Start();                     //I2C起始
	MyI2C_SendByte(MPU6050_ADDRESS);  //发送MPU6050地址 0xD0  第0位为0是写操作,1是读操作
	MyI2C_ReceiveAck();              //接收应答,我这里只接收,不作处理
	
	/*发送需要写操作的寄存器*/
	MyI2C_SendByte(RegAddress);
	MyI2C_ReceiveAck();
	
	/*发送需要写入的数据*/
	MyI2C_SendByte(Data);
	MyI2C_ReceiveAck();
	
	MyI2C_Stop(); //I2C终止
}
3、读MPU6050寄存器函数
3.1读单个字节:

在这里插入图片描述

/**
  * 函数功能:读取MPU6050寄存器里的数据
  * 入口参数:Reg:需要读取的寄存器地址
  * 返 回 值:读取到的数据
  */
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
	uint8_t Data;  //定义保存读取到的数据变量
	
	/*发送从机地址*/
	MyI2C_Start();                     //I2C起始
	MyI2C_SendByte(MPU6050_ADDRESS);  //MPU6050默认地址:0xD0 
	MyI2C_ReceiveAck();              //接收MPU6050应答位
	
	/*发送需要读取的寄存器地址*/
	MyI2C_SendByte(RegAddress);
	MyI2C_ReceiveAck();
	
	/*发送读取模式*/
	MyI2C_Start();
	MyI2C_SendByte(MPU6050_ADDRESS | 0X01);
	MyI2C_ReceiveAck();
	
	/*开始读取从机数据*/
	Data = MyI2C_ReceiveByte();
	MyI2C_SendAck(1);
	MyI2C_Stop();
	
	return Data;
}
4、初始化MPU6050函数
/**
  * 函数功能:初始化MPU6050
  * 入口参数:无
  * 返 回 值:无
  */
void MPU6050_Init(void)
{
	MyI2C_Init();  //调用软件I2C初始化函数
	
	/*MPU6050寄存器初始化, 需要对照手册描述来配置*/
	MPU6050_writeReg(MPU6050_PWR_MGMT_1,0x01);     //电源管理1寄存器,取消睡眠模式,选择时钟源为  X轴陀螺
	MPU6050_writeReg(MPU6050_PWR_MGMT_2,0x02);     //电源管理2寄存器,保持默认值,所有轴不休眠
	MPU6050_writeReg(MPU6050_SMPLRT_DIV,0x09);     //采样率分频寄存器
	MPU6050_writeReg(MPU6050_CONFIG,0x06);         //配置寄存器
	MPU6050_writeReg(MPU6050_GYRO_CONFIG,0x18);    //陀螺仪配置寄存器,选择满量程 ±2000°/s
	MPU6050_writeReg(MPU6050_ACCEL_CONFIG,0x18);   //加速度计配置寄存器,选择满量程 ±16g
	
}
5、读取MPU6050设备ID函数(不要这个函数也是可以的)
/**
  * 函数功能:读取MPU6050设备ID
  * 入口参数:无
  * 返 回 值:设备ID
  */
uint8_t MPU6050_GetID(void)
{
	return MPU6050_ReadReg(MPU6050_WHO_AM_I);  //读取设备ID  寄存器:0x75
}
6、读取加速度计、陀螺仪原始数值
/**
  * 函数功能:读取加速度计、陀螺仪原始数值
  * 入口参数:ACCEL_Array: X轴保存到外部的第0个元素
                           Y轴保存到外部的第1个元素
                           Z轴保存到外部的第2个元素
  * 返 回 值:无
  */
void MPU6050_GetData(int16_t *AccX,int16_t *AccY,int16_t *AccZ,
										 int16_t *GyroX,int16_t *GyroY,int16_t *GyroZ)
{
	uint8_t DataL;  //定义保存数据低位变量
	uint8_t DataH;  //定义保存数据高位变量
	
	/*读取加速度计原始数值,寄存器地址含义需要翻手册的描述*/
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H); //读取X轴高位数据到DataH
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L); //读取X轴低位数据到DataL
	*AccX = (DataH << 8) | DataL; //DataL放到低8位,DataH放到高8位
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H); //读取Y轴高位数据到DataH
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L); //读取Y轴低位数据到DataL
	*AccY = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H); //读取Z轴高位数据到DataH
	DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L); //读取Z轴低位数据到DataL
	*AccZ = (DataH << 8) | DataL;
	
	/*读取陀螺仪原始数值,寄存器地址含义需要翻手册的描述*/
	DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);
	*GyroX = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);
	*GyroY = (DataH << 8) | DataL;
	
	DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);
	DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);
	*GyroZ = (DataH << 8) | DataL;
}
7、main函数
#include "stm32f10x.h"
#include "Delay.h"
#include "OLED.h"
#include "MPU6050.h"

int16_t AX,AY,AZ,GX,GY,GZ;
uint8_t ID;

int main(void)
{
	OLED_Init();     //OLED初始化
	MPU6050_Init();  //MPU6050初始化
	 
	OLED_ShowString(1,1,"ID");  //显示ID
	ID = MPU6050_GetID();       //读取MPU6050 ID
	OLED_ShowHexNum(1,4,ID,2);
	while(1)
	{
        /*读取MPU6050数据*/
		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);
		
	}
}


;