传感器类总结(一)MPU9250 3程序

MPU9250 初始化

static uint8_t MPU_Basic_Init(void)
{
	uint8_t res = 0;
	MPU_ADDR_CTRL();
	MPU_IIC_Init();
	MPU_Delay_ms(10);

	MPU_Write_Byte(MPU9250_ADDR, MPU_PWR_MGMT1_REG, 0X80); // Reset MPU9250 //复位MPU9250
	MPU_Delay_ms(100);										   // Delay 100 ms //延时100ms
	MPU_Write_Byte(MPU9250_ADDR, MPU_PWR_MGMT1_REG, 0X00); // Wake mpu9250 //唤醒MPU9250

	MPU_Set_Gyro_Fsr(1);  // Gyroscope sensor              //陀螺仪传感器,±500dps=±500°/s ±32768 (gyro/32768*500)*PI/180(rad/s)=gyro/3754.9(rad/s)
	MPU_Set_Accel_Fsr(0); // Acceleration sensor           //加速度传感器,±2g=±2*9.8m/s^2 ±32768 accel/32768*19.6=accel/1671.84
	MPU_Set_Rate(50);	  // Set the sampling rate to 50Hz //设置采样率50Hz

	MPU_Write_Byte(MPU9250_ADDR, MPU_INT_EN_REG, 0X00);	   // Turn off all interrupts //关闭所有中断
	MPU_Write_Byte(MPU9250_ADDR, MPU_USER_CTRL_REG, 0X00); // The I2C main mode is off //I2C主模式关闭
	MPU_Write_Byte(MPU9250_ADDR, MPU_FIFO_EN_REG, 0X00);   // Close the FIFO //关闭FIFO
	// The INT pin is low, enabling bypass mode to read the magnetometer directly
	// INT引脚低电平有效,开启bypass模式,可以直接读取磁力计
	MPU_Write_Byte(MPU9250_ADDR, MPU_INTBP_CFG_REG, 0X82);
	// Read the ID of MPU9250 读取MPU9250的ID
	res = MPU_Read_Byte(MPU9250_ADDR, MPU_DEVICE_ID_REG);
	printf("MPU9250 RD ID=0x%02X\n", res);
	if (res == MPU9250_ID) // The device ID is correct //器件ID正确
	{
		MPU_Write_Byte(MPU9250_ADDR, MPU_PWR_MGMT1_REG, 0X01); // Set CLKSEL,PLL X axis as reference //设置CLKSEL,PLL X轴为参考
		MPU_Write_Byte(MPU9250_ADDR, MPU_PWR_MGMT2_REG, 0X00); // Acceleration and gyroscope both work //加速度与陀螺仪都工作
		MPU_Set_Rate(50);									   // Set the sampling rate to 50Hz //设置采样率为50Hz
	}
	else
		return 1;

	res = MPU_Read_Byte(AK8963_ADDR, MAG_WIA); // Read AK8963ID //读取AK8963ID
	printf("AK8963 RD ID=0x%02X\n", res);
	if (res == AK8963_ID)
	{
		MPU_Write_Byte(AK8963_ADDR, MAG_CNTL1, 0X11); // Set AK8963 to single measurement mode //设置AK8963为单次测量模式
	}
	else
		return 1;
	MPU_Delay_ms(30);
	return 0;
}

上述代码我们实现了MPU9250的初始化
1、设置地址

MPU_ADDR_CTRL(); // 控制MPU9250的IIC地址为0x68 控制9脚高电平地址为011010001(B) 低电平为011010000(B)

2、初始化IIC控制引脚设置为推完输出

MPU_IIC_Init();

3、复位9250

	MPU_Write_Byte(MPU9250_ADDR, MPU_PWR_MGMT1_REG, 0X80); // Reset MPU9250 //复位MPU9250
	MPU_Delay_ms(100);										   // Delay 100 ms //延时100ms
	MPU_Write_Byte(MPU9250_ADDR, MPU_PWR_MGMT1_REG, 0X00); // Wake mpu9250 //唤醒MPU9250 这个应该是清除复位

在这里插入图片描述
4、设置参数

	MPU_Set_Gyro_Fsr(1);  // Gyroscope sensor              //陀螺仪传感器,±500dps=±500°/s ±32768 (gyro/32768*500)*PI/180(rad/s)=gyro/3754.9(rad/s)
	MPU_Set_Accel_Fsr(0); // Acceleration sensor           //加速度传感器,±2g=±2*9.8m/s^2 ±32768 accel/32768*19.6=accel/1671.84
	MPU_Set_Rate(50);	  // Set the sampling rate to 50Hz //设置采样率50Hz

在这里插入图片描述
在这里插入图片描述

//设置MPU9250的采样率(假定Fs=1KHz)
// rate:4~1000(Hz)
// 返回值:0,设置成功, 其他,设置失败
uint8_t MPU_Set_Rate(uint16_t rate)
{
	uint8_t data;
	if (rate > 1000)
		rate = 1000;
	if (rate < 4)
		rate = 4;
	data = 1000 / rate - 1;
	data = MPU_Write_Byte(MPU9250_ADDR, MPU_SAMPLE_RATE_REG, data); //设置数字低通滤波器
	return MPU_Set_LPF(rate / 2);									//自动设置LPF为采样率的一半
}

在这里插入图片描述


//设置MPU9250的数字低通滤波器
// lpf:数字低通滤波频率(Hz)
// 返回值:0,设置成功, 其他,设置失败
uint8_t MPU_Set_LPF(uint16_t lpf)
{
	uint8_t 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(MPU9250_ADDR, MPU_CFG_REG, data); //设置数字低通滤波器
}

在这里插入图片描述
在这里插入图片描述
这里注意几个问题:1、带宽是指的传感器对待测量信号的响应,比如带宽过宽对高频信号也进行测量,传感器响应速度快(延时低),但是会测量到高频干扰。如果带宽窄会滤波高频信号那么响应速度也相应降低。
2、这里的FCHOICE[1:0]和下面的Fchoice_b[1:0]是一个位。上面我们配置陀螺仪的量程范围时,已经设置过这个寄存器了。设置为00也就是这里设置为11 然后我们写入的值,比如程序中的50/2 是25相应写入data值为4 也就是配置了DLPF_CFG[2:0]为4 即带宽为20HZ 延迟为9.9ms

5、关闭中断

MPU_Write_Byte(MPU9250_ADDR, MPU_INT_EN_REG, 0X00);	   // Turn off all interrupts //关闭所有中断

这个寄存器没找到
6、设置IIC为从机模式

MPU_Write_Byte(MPU9250_ADDR, MPU_USER_CTRL_REG, 0X00); // The I2C main mode is off //I2C主模式关闭

在这里插入图片描述
7、关闭FIFO

MPU_Write_Byte(MPU9250_ADDR, MPU_FIFO_EN_REG, 0X00);   // Close the FIFO //关闭FIFO

在这里插入图片描述
8、设置bypass模式

	// The INT pin is low, enabling bypass mode to read the magnetometer directly
	// INT引脚低电平有效,开启bypass模式,可以直接读取磁力计
	MPU_Write_Byte(MPU9250_ADDR, MPU_INTBP_CFG_REG, 0X82);

9、读取ID

res = MPU_Read_Byte(MPU9250_ADDR, MPU_DEVICE_ID_REG);

在这里插入图片描述
这里不懂复位值是0x68返回值却是0x71

10、设备ID正确的情况下设置时钟和加速度和陀螺仪

MPU_Write_Byte(MPU9250_ADDR, MPU_PWR_MGMT1_REG, 0X01); // Set CLKSEL,PLL X axis as reference //设置CLKSEL,PLL X轴为参考
MPU_Write_Byte(MPU9250_ADDR, MPU_PWR_MGMT2_REG, 0X00); // Acceleration and gyroscope both work //加速度与陀螺仪都工作
MPU_Set_Rate(50);									   // Set the sampling rate to 50Hz //设置采样率为50Hz

在这里插入图片描述
在这里插入图片描述
11、设置磁力计

res = MPU_Read_Byte(AK8963_ADDR, MAG_WIA); // Read AK8963ID //读取AK8963ID
printf("AK8963 RD ID=0x%02X\n", res);
if (res == AK8963_ID)
{
	MPU_Write_Byte(AK8963_ADDR, MAG_CNTL1, 0X11); // Set AK8963 to single measurement mode //设置AK8963为单次测量模式 14位输出
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
自此初始化设置完毕

MPU9250 数据读取

		MPU_Get_Gyroscope(mpu_data.gyro); //陀螺仪
		MPU_Get_Accelerometer(mpu_data.accel);//加速度
		MPU_Get_Magnetometer(mpu_data.compass);//磁力计
uint8_t MPU_Get_Gyroscope(short *gyro)
{
	#if ENABLE_MPU9250_FILTER
	uint8_t buf[6],res; 
	res=MPU_Read_Len(MPU9250_ADDR,MPU_GYRO_XOUTH_REG,6,buf);
	if(res==0)
	{
		/*前1000次作为陀螺仪零点*/
		if(Deviation_Count<CONTROL_DELAY)
		{
			Deviation_Count++;
			//Read the gyroscope zero //读取陀螺仪零点
			Deviation_gyro[0] = (((uint16_t)buf[0]<<8)|buf[1]);  
			Deviation_gyro[1] = (((uint16_t)buf[2]<<8)|buf[3]);  
			Deviation_gyro[2] = (((uint16_t)buf[4]<<8)|buf[5]);	
		}
		else
		{
			/*g_mpu_start 作为1000次读取的标志位,把第999次作为原点值值打印出来*/
			if (g_mpu_start == 0)
			{
				g_mpu_start = 1;
				Beep_On_Time(100);
				DEBUG("OFFSET GYRO:%d, %d, %d", Deviation_gyro[0], Deviation_gyro[1], Deviation_gyro[2]);
			}
			//Save the raw data to update zero by clicking the user button
			//保存原始数据用于单击用户按键更新零点
			Original_gyro[0] = (((uint16_t)buf[0]<<8)|buf[1]);
			Original_gyro[1] = (((uint16_t)buf[2]<<8)|buf[3]);
			Original_gyro[2] = (((uint16_t)buf[4]<<8)|buf[5]);
			
			//Removes zero drift data
			//去除零点漂移的数据
			gyro[0] = Original_gyro[0]-Deviation_gyro[0];
			gyro[1] = Original_gyro[1]-Deviation_gyro[1];
			gyro[2] = Original_gyro[2]-Deviation_gyro[2];
		}
	}
	return 0;
	#else
	uint8_t buf[6], res;
	res = MPU_Read_Len(MPU9250_ADDR, MPU_GYRO_XOUTH_REG, 6, buf);
	if (res == 0)
	{
		gyro[0] = ((uint16_t)buf[0] << 8) | buf[1];
		gyro[1] = ((uint16_t)buf[2] << 8) | buf[3];
		gyro[2] = ((uint16_t)buf[4] << 8) | buf[5];
	}
	g_mpu_start = 1;
	return res;
	#endif
}
res=MPU_Read_Len(MPU9250_ADDR,MPU_GYRO_XOUTH_REG,6,buf);

寄存器 67 到 72 陀螺仪测量
其中67 68为X轴陀螺仪的字节 H L (BE)
其中69 70为X轴陀螺仪的字节 H L
其中71 72为X轴陀螺仪的字节 H L
每次的到的gyro是消除零漂的数据,用每次读到的原始数据减去第999次的数据。

uint8_t MPU_Get_Accelerometer(short *accel)
{
	uint8_t buf[6], res;
	res = MPU_Read_Len(MPU9250_ADDR, MPU_ACCEL_XOUTH_REG, 6, buf);
	if (res == 0)
	{
		accel[0] =((uint16_t)buf[0]<<8)|buf[1];
		accel[1] =((uint16_t)buf[2]<<8)|buf[3];
		accel[2] =((uint16_t)buf[4]<<8)|buf[5];
	}
	return res;
}

//得到磁力计值(原始值)
// mx,my,mz:磁力计x,y,z轴的原始读数(带符号)
// 返回值:0,设置成功, 其他,设置失败
uint8_t MPU_Get_Magnetometer(short *mag)
{
	uint8_t buf[6], res;
	res = MPU_Read_Len(AK8963_ADDR, MAG_XOUT_L, 6, buf);
	if (res == 0)
	{
		mag[0] = ((uint16_t)buf[1]<<8)|buf[0];
		mag[1] = ((uint16_t)buf[3]<<8)|buf[2];
		mag[2] = ((uint16_t)buf[5]<<8)|buf[4];
	}
	MPU_Write_Byte(AK8963_ADDR, MAG_CNTL1, 0X11); // AK8963每次读完以后都需要重新设置为单次测量模式
	return res;
}

同理加速度轴和磁力轴也相同。
注意磁力中是先L后H
在这里插入图片描述

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MPU9250是一种集成了加速度计、陀螺仪和磁力计的传感器模块。在使用SPI进行读写寄存器时,可以使用以下函数进行操作。SPI写寄存器的函数为MPU9250_Write_Reg,它通过SPI发送寄存器地址和数据来写入寄存器。SPI读寄存器的函数为MPU9250_Read_Reg,它通过SPI发送寄存器地址和读命令,然后读取寄存器中的数据。\[1\]\[2\] 在开发过程中,使用了STM32CubeIDE作为开发软件,主控使用了STM32F103C8T6。同时使用了两个GY-91模块,但第一个模块出现了问题,读取WHO_AM_I寄存器的值为0x70,而实际上MPU9250的WHO_AM_I寄存器的值应该是0x71或者0x73。经过查询资料发现,MPU6500的WHO_AM_I寄存器的值才是0x70,因此第一个模块无法读取磁力计的数据。更换了新的模块后问题得到解决。\[3\] 总结来说,MPU9250是通过SPI进行寄存器读写的,可以使用相应的函数进行操作。在开发过程中,需要注意模块的型号和寄存器的值,以确保正确读取数据。 #### 引用[.reference_title] - *1* *2* [STM32单片机SPI读取MPU9250加速度计、陀螺仪、磁力计九轴数据(附程序)](https://blog.csdn.net/liuyifanliu/article/details/99309839)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [STM32使用HAL库SPI驱动MPU9250九轴姿态传感器](https://blog.csdn.net/sin1111yi/article/details/121906053)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值