MPU6050

news/2024/11/25 2:56:47/

MUP6050简介

首先mpu6050是由三个陀螺仪和三个加速度传感器组成的6轴运动处理组件(如下图所示)。mpu6050还含有两个IIC接口,一个可作为主接口给单片机传输数据,另一个可以接入外部磁力传感器。
在这里插入图片描述
mpu6050的输出形式为数字形式输出6轴或9轴1的旋转矩阵,四元数,欧拉角公式的融合演算数据(需要DMP2支持)

MPU6050与单片机接线

端口连接
VCC接3.3V或5V电源
GND接地
SCL作为从机,接单片机的I2C2_SCL
SDA作为从机,接单片机的I2C2_SDA
XDA辅助IIC用来连接其他器件,不需要连接单片机
XCL辅助IIC用来连接其他器件,不需要连接单片机
AD0地址管脚(可以不接单片机)
INT中断引脚(可以不接单片机)

MPU6050作为一个IIC从机设备的时候,有8位地址,高7位的地址是固定的,就是WHOAMI寄存器的默认——0x68,最低的一位是由AD0的连线决定的.
AD0接GND时候,高8位的最后一位是0 所以整个iic从几地址就是0x68;
AD0接VCC时候,高8位的最后一位是1 所以整个iic从几地址就是0x69.
四、程序里需要知道的

MPU6050的代码实现(以keil5软件为例)

MPU6050 IIC配置

  1. 初始化IIC接口(初始化与mpu6050连接的SDA与SCL数据线)
void MPU_IIC_Init(void)
{					     GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//先使能外设IO PORTB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;	 // 端口配置,这里以我连接的SDA与SCL为例GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIO GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);						 //PB10,PB11 输出高,都置高可以使模块处于待机模式}
  1. IIC开始信号(SCL为高电平,SDA由高向低跳变开始传输数据)
void MPU_IIC_Start(void)
{MPU_SDA_OUT();     //sda线输出MPU_IIC_SDA=1;	  	  MPU_IIC_SCL=1;MPU_IIC_Delay();MPU_IIC_SDA=0;//START:when CLK is high,DATA change form high to low MPU_IIC_Delay();MPU_IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	  
  1. IIC开始信号(SCL为高电平,SDA由低向高跳变开始传输数据)
void MPU_IIC_Stop(void)
{MPU_SDA_OUT();//sda线输出MPU_IIC_SCL=0;MPU_IIC_SDA=0;//STOP:when CLK is high DATA change form low to highMPU_IIC_Delay();MPU_IIC_SCL=1; MPU_IIC_SDA=1;//发送I2C总线结束信号MPU_IIC_Delay();							   	
}
  1. 等待信号接收
u8 MPU_IIC_Wait_Ack(void)//返回值为1接收失败;返回值为0接收成功
{u8 ucErrTime=0;MPU_SDA_IN();      //SDA设置为输入  MPU_IIC_SDA=1;MPU_IIC_Delay();	   MPU_IIC_SCL=1;MPU_IIC_Delay();	 while(MPU_READ_SDA){ucErrTime++;if(ucErrTime>250){MPU_IIC_Stop();return 1;}}MPU_IIC_SCL=0;//时钟输出0 	   return 0;  
} 
  1. 产生ACK应答
void MPU_IIC_Ack(void)
{MPU_IIC_SCL=0;MPU_SDA_OUT();MPU_IIC_SDA=0;MPU_IIC_Delay();MPU_IIC_SCL=1;MPU_IIC_Delay();MPU_IIC_SCL=0;
}
  1. 产生ACK应答
void MPU_IIC_NAck(void)
{MPU_IIC_SCL=0;MPU_SDA_OUT();MPU_IIC_SDA=1;MPU_IIC_Delay();MPU_IIC_SCL=1;MPU_IIC_Delay();MPU_IIC_SCL=0;
}			

MPU6050初始化

代码来自b站大佬“晴时箫声”

u8 MPU_Init(void)
{ u8 res;GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能AFIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//先使能外设IO PORTA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;	 // 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);					 //根据设定参数初始化GPIOAGPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//禁止JTAG,从而PA15可以做普通IO使用,否则PA15不能做普通IO!!!MPU_AD0_CTRL=0;			//控制MPU6050的AD0脚为低电平,从机地址为:0X68MPU_IIC_Init();//初始化IIC总线MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80);	//复位MPU6050delay_ms(100);MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00);	//唤醒MPU6050 MPU_Set_Gyro_Fsr(3);					//陀螺仪传感器,±2000dpsMPU_Set_Accel_Fsr(0);					//加速度传感器,±2gMPU_Set_Rate(50);						//设置采样率50HzMPU_Write_Byte(MPU_INT_EN_REG,0X00);	//关闭所有中断MPU_Write_Byte(MPU_USER_CTRL_REG,0X00);	//I2C主模式关闭MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);	//关闭FIFOMPU_Write_Byte(MPU_INTBP_CFG_REG,0X80);	//INT引脚低电平有效res=MPU_Read_Byte(MPU_DEVICE_ID_REG);if(res==MPU_ADDR)//器件ID正确{MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);	//设置CLKSEL,PLL X轴为参考MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);	//加速度与陀螺仪都工作MPU_Set_Rate(50);						//设置采样率为50Hz}else return 1;return 0;
}

所调用的函数

u8 MPU_Set_Gyro_Fsr(u8 fsr)
{return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围  
}
u8 MPU_Set_Accel_Fsr(u8 fsr)
{return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围  
}
8 MPU_Set_LPF(u16 lpf)
{u8 data=0;if(lpf>=188)data=1;else if(lpf>=98)data=2;else if(lpf>=42)data=3;else if(lpf>=20)data=4;else if(lpf>=10)data=5;else data=6; return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器  
}
u8 MPU_Set_Rate(u16 rate)
{u8 data;if(rate>1000)rate=1000;if(rate<4)rate=4;data=1000/rate-1;data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);	//设置数字低通滤波器return MPU_Set_LPF(rate/2);	//自动设置LPF为采样率的一半
}
short MPU_Get_Temperature(void)
{u8 buf[2]; short raw;float temp;MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); raw=((u16)buf[0]<<8)|buf[1];  temp=36.53+((double)raw)/340;  return temp*100;;
}
u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{u8 buf[6],res;  res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);if(res==0){*gx=((u16)buf[0]<<8)|buf[1];  *gy=((u16)buf[2]<<8)|buf[3];  *gz=((u16)buf[4]<<8)|buf[5];} 	return res;;
}
u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{u8 buf[6],res;  res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);if(res==0){*ax=((u16)buf[0]<<8)|buf[1];  *ay=((u16)buf[2]<<8)|buf[3];  *az=((u16)buf[4]<<8)|buf[5];} 	return res;;
}
u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{u8 i; MPU_IIC_Start(); MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令	if(MPU_IIC_Wait_Ack())	//等待应答{MPU_IIC_Stop();		 return 1;		}MPU_IIC_Send_Byte(reg);	//写寄存器地址MPU_IIC_Wait_Ack();		//等待应答for(i=0;i<len;i++){MPU_IIC_Send_Byte(buf[i]);	//发送数据if(MPU_IIC_Wait_Ack())		//等待ACK{MPU_IIC_Stop();	 return 1;		 }		}    MPU_IIC_Stop();	 return 0;	
} 
u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{ MPU_IIC_Start(); MPU_IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令	if(MPU_IIC_Wait_Ack())	//等待应答{MPU_IIC_Stop();		 return 1;		}MPU_IIC_Send_Byte(reg);	//写寄存器地址MPU_IIC_Wait_Ack();		//等待应答MPU_IIC_Start();MPU_IIC_Send_Byte((addr<<1)|1);//发送器件地址+读命令	MPU_IIC_Wait_Ack();		//等待应答 while(len){if(len==1)*buf=MPU_IIC_Read_Byte(0);//读数据,发送nACK else *buf=MPU_IIC_Read_Byte(1);		//读数据,发送ACK  len--;buf++; }    MPU_IIC_Stop();	//产生一个停止条件 return 0;	
}
u8 MPU_Write_Byte(u8 reg,u8 data) 				 
{ MPU_IIC_Start(); MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令	if(MPU_IIC_Wait_Ack())	//等待应答{MPU_IIC_Stop();		 return 1;		}MPU_IIC_Send_Byte(reg);	//写寄存器地址MPU_IIC_Wait_Ack();		//等待应答 MPU_IIC_Send_Byte(data);//发送数据if(MPU_IIC_Wait_Ack())	//等待ACK{MPU_IIC_Stop();	 return 1;		 }		 MPU_IIC_Stop();	 return 0;
}
u8 MPU_Read_Byte(u8 reg)
{u8 res;MPU_IIC_Start(); MPU_IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令	MPU_IIC_Wait_Ack();		//等待应答 MPU_IIC_Send_Byte(reg);	//写寄存器地址MPU_IIC_Wait_Ack();		//等待应答MPU_IIC_Start();MPU_IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令	MPU_IIC_Wait_Ack();		//等待应答 res=MPU_IIC_Read_Byte(0);//读取数据,发送nACK MPU_IIC_Stop();			//产生一个停止条件 return res;		
}

以上代码就可以使mpu6050正常工作了。


  1. 输出9轴需要外接磁传感器 ↩︎

  2. 官方自带的数字运动处理器 ↩︎


http://www.ppmy.cn/news/111594.html

相关文章

联想笔记本G510升级固态硬盘(SSD)血泪教程!!!

#联想笔记本G510升级固态硬盘(SSD)血泪教程!!! 用了5年的联想笔记本G510,经过了四年的游戏历程,然后四年后还老当益壮的挣扎在我工作的战斗一线,是我并肩作战多年,比兄弟还要亲的兄弟,虽然此时已经身躯残破,反应迟缓我依旧不舍得抛弃它(主要是没钱!)然后为了我个人的用户体验决…

联想G510进入BIOS的两种方法

按照网上的说法&#xff0c;FNF2可以进入BIOS&#xff0c;但是自己反复试了半天还是不行&#xff0c;于是咨询客服。给了两种方法进入BIOS。 1、开机或重启是按住FN&#xff0c;然后不停地敲击F2&#xff0c;注意是不停地&#xff0c;敲一次或一直按着没什么卵用。 2、按恢复…

联想G510 U盘启动

两种方法 开机F2进入BIOS&#xff0c;切换到boot&#xff0c;设置U盘为第一启动。(Boot Mode选择Legacy Support,否则无法u盘启动&#xff09; https://jingyan.baidu.com/article/49ad8bce4aaa495834d8fa9f.html 开机F12直接选择启动方式&#xff0c;更方便。

Arcgis for javascript 应用开发相关网站推荐(SDK,github社区等)

一、什么是arcgis for javascript ArcGIS for JavaScript是一种用于构建基于Web的GIS应用程序的开发框架。它允许开发人员使用Esri的地图和地理空间数据来构建具有交互性和可视化效果的应用程序。ArcGIS for JavaScript提供了丰富的API和组件&#xff0c;使开发人员可以将地理…

推动创意成果:创意过程如何改变 2023 年的业务

时下全球经济放缓&#xff0c;很多企业业务都陷入了增长瓶颈&#xff0c;如何突破&#xff1f;今天我们来聊聊一般业务突破的3种方式&#xff1a; 发现一片新的蓝海&#xff0c;迅速杀入占领生态位&#xff08;快&#xff09;&#xff1b; 发现结构性红利机会&#xff0c;大量投…

利用ArcGIS与CAD制作设计底图

准备工作&#xff1a; 1、需要用到的软件&#xff1a;ArcGIS软件、AutoCAD&#xff1b; 2、卫星图数据、矢量数据&#xff08;因数据涉密&#xff0c;需要的同事请联系科技小组拷贝&#xff0c;并签署保密协议&#xff0c;严格履行保密责任&#xff09;。 现在&#xff0c;保…

Dell服务器安装系统操作(以戴尔R720为例)

1、准备好系统盘 1、插上服务器后重启服务器&#xff08;CtrlAitDelete重启&#xff09; 2、重启时按F11&#xff0c;进入Boot Manager ----点击BIOS Boot Menu&#xff08;一键BIOS启动菜单&#xff09;找到U盘&#xff08;“USB”&#xff09;回车 这里需要注意只适用2TB内…

[转]尼康D7000或D7100优化校准与白平衡设置摄影指南

原贴&#xff1a;http://forum.xitek.com/thread-1370740-1-1-1.html 尼康D7000/D7100相机设置技巧 1、优化校准&#xff1a;采用鲜艳模式&#xff0c;进入快速调整菜单&#xff0c;调整为&#xff1a;锐度为4&#xff0c;或5&#xff0c;拍人像&#xff1b;锐化为7&#xff0…