首页 > 其他分享 >16_MPU6050

16_MPU6050

时间:2024-02-29 15:37:20浏览次数:18  
标签:MyI2C void 16 uint8 MPU6050 GPIO define

MPU6050

MPU6050简介

image-20240226004250055

MPU6050参数

image-20240226005704035

硬件电路

image-20240226140558744

MPU6050框图

image-20240226141640986

软件I2C读写MPU6050

接线图

image-20240226163355312

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);
	}
}

标签:MyI2C,void,16,uint8,MPU6050,GPIO,define
From: https://www.cnblogs.com/mzx233/p/18044350

相关文章

  • m基于深度学习的16QAM调制解调系统相位检测和补偿算法matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下: 2.算法涉及理论知识概要        随着通信技术的飞速发展,高阶调制格式如16QAM(16-QuadratureAmplitudeModulation,16进制正交幅度调制)在高速数据传输中得到了广泛应用。然而,由于信道失真、噪声干扰等因素,接收端往往面临相......
  • 数组构建_cfECR162_C. Find B
    目录问题概述思路分析参考代码问题反思问题概述原题参考:C.FindB对于一个数组a,给出m次咨询,问对于每一次询问的区间是否可以构建出另外一个好的数组b,对于a的好数组的定义是a数组和b数组的元素和相同a数组和b数组的每一位不同b数组的每一位是正数思路分析对于第一个条件......
  • 1.16
    创建一个新的JavaWeb项目,新建测试类 HelloServlet ,该类需要继承 HttpServlet ,所以首先需要导入 Servlet 依赖<!--Servlet依赖--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0<......
  • P10160 [DTCPC 2024] Ultra 题解
    【题目描述】给你一个\(01\)序列,你可以进行如下操作若干次(或零次):将序列中形如\(101\cdots01\)的一个子串(即\(1(01)^k\),\(k\ge1\))替换成等长的\(010\cdots10\)(即\(0(10)^k\))。你要操作使得\(1\)的个数尽可能少,输出最少的\(1\)的个数。【思路】一开始看到这道题......
  • 假期vue学习笔记16 vuex多组数据共享
     <template>  <div>    <h1>当前求和为:{{sum}}</h1>    <h1>十倍的和为:{{bigSum}}</h1>    <h1>{{xuexiao}}</h1>    <h1>{{xueke}}</h1>    <h3>下方总人数为:{{$store.state.personList......
  • P1668 题解
    两种做法。一、最短路题目要求区间数量最小。如果能建出图来,就可以转换为最短路问题。具体地,我们从\(l-1\tor\)连一条长度为\(1\)的边,意味着要多经过\((l-1,r]\)这一个区间。这是左开右闭的形式。现在还有一个问题:通过这种边我们只能到达区间的右端点,如果想向左到达区......
  • 2.16 Android 手机端学习
    publicclassAccountAdapterextendsBaseAdapter{Contextcontext;List<AccountBean>mDatas;LayoutInflaterinflater;intyear,month,day;publicAccountAdapter(Contextcontext,List<AccountBean>mDatas){this.context=......
  • cf1621g-solution
    CF1621GSolutionlink考虑对每个位置\(i\)作为\(i_j\)时计算贡献。\(i\)对一次答案有贡献当且仅当:设其子序列内最右端的位置为\(r\),则要满足\(r\)右侧存在一个数大于\(a_{i}\)。即,设\(lst_i\)表示整个序列最右侧的大于\(a_i\)的数,要满足\(lst_i>r\)。现......
  • cf1606e-solution
    CF1606ESolutionlink考虑dp。注意到这个题造成的伤害与剩余人数有关,每次消灭的人数又与剩余人的血量最大值有关:设\(dp_{i,j}\)表示剩下\(i\)个人中血量最大值为\(j\)的方案数。显然当\(i-1>=j\)时一次伤害就可以杀光所有人,于是这时\(dp_{i,j}=j^i-(j-1)^i\)(只需让......
  • 【APP逆向16】frida反调试
    1.当我们对莫个app进行fridahook的时候,如果已启动hook脚本,app就自动退出了。这个时候可能就是app对frida进行了反调试。2.如何解决这种问题呢?反调试一般在so中实现,如果有frida使用,就给关闭app启动过程中,都有加载so文件下面的问题是如何找到反调试的so文件3.hookapp......