当前位置:   article > 正文

利用TM4C123G单片机读取并处理MPU6050初始数据_tm4c 交换芯片

tm4c 交换芯片

一、MPU6050简介

网络上关于这款芯片的介绍很多,这里简单概括一下

MPU6050简介

MPU6050 内部有 3 轴陀螺仪和 3 轴加速度传感器,其中陀螺仪可以测得芯片当前的角速度,而加速度传感器可以测得芯片当前感应到的加速度。通过读取并处理这两个传感器的数据,我们可以分别求得两个独立的传感器姿态数据,即传感器坐标系相对于地面坐标系x、y、z轴的相对角度偏移,然后通过特定的算法整合这两组数据,从而求得精确的姿态数据,求得当前的欧拉角。
传感器姿态

MPU6050结构框图

本程序需要使用的模块已被框出
硬件框图

二、关于该芯片的使用

芯片的使用方法可以总结为以下几个步骤
1、主程序必要模块初始化(IIC等)
2、利用IIC写入芯片寄存器,初始化芯片
3、利用IIC读取芯片数据
4、数据处理
注:在本程序中,MPU6050的IIC地址是0x68
芯片的接线:

MPU6050接口单片机接口
VDD3.3V
GND任意GND接口
SCLPA6
SDAPA7
INTN/A
AD0N/A
芯片的初始化:
void MPU6050_Init(void)//MPU6050初始化
{
	IMU_ID=Single_ReadI2C(MPU_ADDR,WHO_AM_I);
	printf("%d\n",IMU_ID);//检验IIC是否能对MPU6050进行操作
  i2cWrite(MPU_ADDR,MPU_PWR_MGMT1_REG,0X80);//对MPU6050寄存器清零
	delay_ms(100);
	i2cWrite(MPU_ADDR,MPU_PWR_MGMT1_REG,0X00);//唤醒MPU6050
	i2cWrite(MPU_ADDR,MPU_GYRO_CFG_REG,0X00);//设置陀螺仪满量程范围为250°
	i2cWrite(MPU_ADDR,MPU_ACCEL_CFG_REG,0X00);//设置加速度传感器满量程范围为±2G
	i2cWrite(MPU_ADDR,MPU_SAMPLE_RATE_REG,0X13);//设置采样率
	i2cWrite(MPU_ADDR,MPU_INT_EN_REG,0X00);//关闭所有中断(本程序不需要)
	i2cWrite(MPU_ADDR,MPU_USER_CTRL_REG,0X00);
	i2cWrite(MPU_ADDR,MPU_FIFO_EN_REG,0X00);//关闭FIFO
	i2cWrite(MPU_ADDR,MPU_INTBP_CFG_REG,0X80);
	i2cWrite(MPU_ADDR,MPU_PWR_MGMT1_REG,0X01);
	i2cWrite(MPU_ADDR,MPU_PWR_MGMT2_REG,0X00);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

注意:在“对MPU6050清零操作”和“唤醒MPU6050操作”间,必须使用延时函数间隔(一般是100ms),否则初始化函数后续操作将无效

三、代码

1.MPU6050数据的读取

void MPU6050_Read_Data(vector3f *gyro,vector3f *accel,float *temperature)
{
	uint8_t buf[14];
	int16_t temp;
	i2cReadData(MPU_ADDR,ACCEL_XOUT_H,buf,14);
	accel->x=(int16_t)((buf[0]<<8)|buf[1]);
	accel->y=-(int16_t)((buf[2]<<8)|buf[3]);
	accel->z=-(int16_t)((buf[4]<<8)|buf[5]);
	temp=(int16_t)((buf[6]<<8)|buf[7]);
	gyro->x	=(int16_t)((buf[8]<<8)|buf[9]);
	gyro->y	=-(int16_t)((buf[10]<<8)|buf[11]);
	gyro->z	=-(int16_t)((buf[12]<<8)|buf[13]);
	*temperature=36.53f+(double)(temp/340.0f);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

注:vector3f是一个含有三个浮点型变量的结构体

2.IIC模块(篇幅受限,不做介绍)
3.主函数

#include "Headfile.h"
#define LSB_ACCEL 16384	//加速度灵敏度常数 
#define LSB_GYRO  131  //角加速度灵敏度常数 
int fputc(int ch, FILE *f){UARTCharPut(UART0_BASE,ch);	return (ch);}//重新映射printf函数 
int fgetc(FILE *f) {int ch=UARTCharGet(UART0_BASE);	return (ch);}
vector3f wgyro,aaccel;
float tempr,xaxisA,yaxisA,zaxisA,xaxisB,yaxisB,zaxisB;
float XAxisREG,YAxisREG,ZAxisREG;
float GxREG,GyREG,GzREG;
float Gx,Gy,Gz;
float g_Gyro_xoffset = 2.665, g_Gyro_yoffset = -0.395, g_Gyro_zoffset = 0.825;//校正传感器角速度静止数据(校正后静止时角速度应为0) 
float yaw,pitch,roll;
int lasttime,nowtime;
void main_loop()
{
	MPU6050_Read_Data( &wgyro , &aaccel , &tempr );
	float Ax=aaccel.x/LSB_ACCEL;
	float Ay=aaccel.y/LSB_ACCEL;
	float Az=aaccel.z/LSB_ACCEL;
	float Angel_accX=atan(Ax/sqrt(Az*Az+Ay*Ay))*180/3.14;		//加速度计数据处理
    float Angel_accY=atan(Ay/sqrt(Ax*Ax+Az*Az))*180/3.14;
    float Angel_accZ=atan(Az/sqrt(Ax*Ax+Ay*Ay))*180/3.14;
	float gx=wgyro.x/LSB_GYRO;
	float gy=wgyro.y/LSB_GYRO;
	float gz=wgyro.z/LSB_GYRO;
	lasttime=nowtime;
	nowtime=millis();
	Gx=Gx+(gx-GxREG+g_Gyro_xoffset)*(nowtime-lasttime)/1000;	//陀螺仪数据处理
    Gy=Gy+(gy-GyREG+g_Gyro_yoffset)*(nowtime-lasttime)/1000;
    Gz=Gz+(gz-GzREG+g_Gyro_zoffset)*(nowtime-lasttime)/1000;
	GxREG=Gx,GyREG=Gy,GzREG=Gz;
	Gx=gx;
	XAxisREG+=Angel_accX;
	YAxisREG+=Angel_accY;
	ZAxisREG+=Angel_accZ;
	pitch=yijiehubu(Angel_accX,Gy,nowtime-lasttime);			//通过一阶互补滤波函数整合数据(博主这里也没搞懂,希望广大网友不吝赐教) 
	roll=yijiehubu(Angel_accY,Gx,nowtime-lasttime);
	yaw=Angel_accZ;
	printf("PITCH:%f ROLL%f YAW:%f\n",pitch,roll,yaw);			//姿态角输出 
}

int main(void)
{
  	HardWave_Init();
	printf("初始化完成");
  	while(1)
	{
		main_loop();
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

p.s.:
加速度处理:利用重力矢量推测出当前传感器姿态,公式为:

Angel_accX=arctan(Ax/sqrt(Az*Az+Ay*Ay))*180/PI;
Angel_accY=arctan(Ax/sqrt(Ax*Ax+Az*Az))*180/PI;
Angel_accZ=arctan(Ax/sqrt(Ax*Ax+Ay*Ay))*180/PI;
  • 1
  • 2
  • 3

角速度处理:对速度求积分得到姿态角

Gx=Gx+(gx-GxREG+g_Gyro_xoffset)*dt;
Gy=Gy+(gy-GyREG+g_Gyro_yoffset)*dt;
Gz=Gz+(gz-GzREG+g_Gyro_zoffset)*dt;
  • 1
  • 2
  • 3

dt的获取:
使用millis函数获取当时的时间戳(以毫秒计),储存起来,与下一次采样时以相同方法获取的时间戳做差,这样就可以获得dt了(注意,dt数据需要除以1000转换为秒,而且需以浮点数储存,否则。。。会出很大的问题)

四、程序效果

采样

注意: 本文的方法只能测出相对xyz坐标系的角度, 如果要算出pitch roll yaw角度需要进行四元数转换, 在下面的资源中附有测PRY角度相关工程

具体工程文件:

链接:https://pan.baidu.com/s/1biANvELF43nf-XEMi-boWg
提取码:5zc2

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/666702
推荐阅读
相关标签
  

闽ICP备14008679号