STM32CubeIDE HAL库操作IIC (二)案例篇(MPU9250)

接上一篇:STM32CubeIDE HAL库操作IIC (一)配置篇

目录

一、IIC协议操作MPU9250寄存器函数

二、MPU9250的操作(举例)

1、设置寄存器方法

2、读取寄存器方法

三、MPU9250简单数据读取流程

1、初始化

2、读取各传感器数据函数

3、使用


一、IIC协议操作MPU9250寄存器函数

#define MPU9250Addr 	0xd0

/*****************************************************************************
* 功  能:写一个字节数据到 MPU9250 寄存器
* 参  数:reg: 寄存器地址
*         data: 要写入的数据
* 返回值:0成功 1失败
*****************************************************************************/
uint8_t MPU9250_WriteByte(uint8_t reg,uint8_t data)
{
	if(HALIIC_WriteByteToSlave(MPU9250Addr,reg,data))
		return 1;
	else
		return 0;
}

/*****************************************************************************
* 功  能:从指定MPU6050寄存器读取一个字节数据
* 参  数:reg: 寄存器地址
*         buf:  读取数据存放的地址
* 返回值:1失败 0成功
*****************************************************************************/
uint8_t MPU9250_ReadByte(uint8_t reg,uint8_t *buf)
{
	if(HALIIC_ReadByteFromSlave(MPU9250Addr,reg,buf))
		return 1;
	else
		return 0;
}

/*****************************************************************************
* 功  能:从指定寄存器写入指定长度数据
* 参  数:reg:寄存器地址
*         len:写入数据长度
*         buf: 写入数据存放的地址
* 返回值:0成功 1失败
*****************************************************************************/
uint8_t MPU9250_WriteMultBytes(uint8_t reg,uint8_t len,uint8_t *buf)
{
	if(HALIIC_WriteMultByteToSlave(MPU9250Addr,reg,len,buf))
		return 1;
	else
		return 0;
}

/*****************************************************************************
* 功  能:从指定寄存器读取指定长度数据
* 参  数:reg:寄存器地址
*         len:读取数据长度
*         buf: 读取数据存放的地址
* 返回值:0成功 0失败
*****************************************************************************/
uint8_t MPU9250_ReadMultBytes(uint8_t reg,uint8_t len,uint8_t *buf)
{
	if(HALIIC_ReadMultByteFromSlave(MPU9250Addr,reg,len,buf))
		return 1;
	else
		return 0;
}

 

二、MPU9250的操作(举例)

1、设置寄存器方法

#define MPU9250_RA_PWR_MGMT_1       0x6B

MPU9250_WriteByte(MPU6050_RA_PWR_MGMT_1, 0x80); //复位MPU9250

2、读取寄存器方法

读单个字节

#define MPU9250_RA_WHO_AM_I         0x75

uint8_t buf;
MPU9250_ReadByte(MPU9250_RA_WHO_AM_I, &buf);//读取器件ID

读多个字节 

/******************************************************************************
* 功  能:读取加速度的原始数据
* 参  数:*accData 原始数据的指针
* 返回值:无
*******************************************************************************/
void MPU9250_AccRead(int16_t *accData)
{
    uint8_t buf[6];
   	MPU9250_ReadMultBytes(MPU6050_RA_ACCEL_XOUT_H,6,buf);
    accData[0] = (int16_t)((buf[0] << 8) | buf[1]);
    accData[1] = (int16_t)((buf[2] << 8) | buf[3]);
    accData[2] = (int16_t)((buf[4] << 8) | buf[5]);
}

三、MPU9250简单数据读取流程

1、初始化

#define MPU9250_RA_INT_ENABLE       0x38
#define MPU9250_RA_PWR_MGMT_1       0x6B
#define MPU9250_RA_GYRO_CONFIG      0x1B
#define MPU9250_RA_ACCEL_CONFIG     0x1C
#define MPU9250_RA_CONFIG           0x1A
#define MPU9250_RA_SMPLRT_DIV       0x19
#define MPU9250_RA_INT_PIN_CFG      0x37

//设置低通滤波
#define MPU9250_DLPF_BW_256         0x00
#define MPU9250_DLPF_BW_188         0x01
#define MPU9250_DLPF_BW_98          0x02
#define MPU9250_DLPF_BW_42          0x03
#define MPU9250_DLPF_BW_20          0x04
#define MPU9250_DLPF_BW_10          0x05
#define MPU9250_DLPF_BW_5           0x06


void MPU9250_Init(void)
{
	MPU9250_Check(); //通过读取ID,检查MPU9250是否连接

	MPU9250_WriteByte(MPU9250_RA_PWR_MGMT_1, 0x80); //复位MPU9250
	HAL_Delay(100);
	MPU9250_WriteByte(MPU9250_RA_PWR_MGMT_1, 0x00); //唤醒MPU9250,并选择陀螺仪x轴PLL为时钟源 (MPU9250_RA_PWR_MGMT_1, 0x01)
	MPU9250_WriteByte(MPU9250_RA_INT_ENABLE, 0x00); //禁止中断
	MPU9250_WriteByte(MPU9250_RA_GYRO_CONFIG, 0x18); //陀螺仪满量程+-2000度/秒 (最低分辨率 = 2^15/2000 = 16.4LSB/度/秒
	MPU9250_WriteByte(MPU9250_RA_ACCEL_CONFIG, 0x08); //加速度满量程+-4g   (最低分辨率 = 2^15/4g = 8196LSB/g )
	MPU9250_WriteByte(MPU9250_RA_CONFIG, MPU6050_DLPF_BW_20);//设置陀螺的输出为1kHZ,DLPF=20Hz
	MPU9250_WriteByte(MPU9250_RA_SMPLRT_DIV, 0x00);  //采样分频 (采样频率 = 陀螺仪输出频率 / (1+DIV),采样频率1000hz)
	MPU9250_WriteByte(MPU9250_RA_INT_PIN_CFG, 0x02); //MPU 可直接访问MPU9250辅助I2C

}

2、读取各传感器数据函数

#define MPU9250_RA_ACCEL_XOUT_H     0x3B

#define MPU9250_RA_TEMP_OUT_H       0x41

#define MPU9250_RA_GYRO_XOUT_H      0x43

//MPU9250内部封装了一个AK8963磁力计,地址和ID如下:
#define AK8963_ADDR			0X0C	//AK8963的I2C地址
#define AK8963_ID			0X48	//AK8963的器件ID
//AK8963的内部寄存器
#define MAG_WIA				0x00	//AK8963的器件ID寄存器地址
#define MAG_XOUT_L			0X03

/******************************************************************************
* 功  能:读取加速度的原始数据
* 参  数:*accData 原始数据的指针
* 返回值:无
*******************************************************************************/
void MPU9250_AccRead(int16_t *accData)
{
    uint8_t buf[6];
   	MPU9250_ReadMultBytes(MPU9250_RA_ACCEL_XOUT_H,6,buf);
    accData[0] = (int16_t)((buf[0] << 8) | buf[1]);
    accData[1] = (int16_t)((buf[2] << 8) | buf[3]);
    accData[2] = (int16_t)((buf[4] << 8) | buf[5]);
}

/******************************************************************************
* 功  能:读取陀螺仪的原始数据
* 参  数:*gyroData 原始数据的指针
* 返回值:无
*******************************************************************************/
void MPU9250_GyroRead(int16_t *gyroData)
{
    uint8_t buf[6];
	MPU9250_ReadMultBytes(MPU9250_RA_GYRO_XOUT_H, 6, buf);
    gyroData[0] = (int16_t)((buf[0] << 8) | buf[1]) ;
    gyroData[1] = (int16_t)((buf[2] << 8) | buf[3]) ;
    gyroData[2] = (int16_t)((buf[4] << 8) | buf[5]) ;
}

/******************************************************************************
* 功  能:读取磁力计的原始数据
* 参  数:*magData原始数据的指针
* 返回值:无
*******************************************************************************/
void MPU9250_MagRead(int16_t *magData)
{
    uint8_t buf[6];
    HALIIC_WriteByteToSlave(MPU9250Addr,0x37,0x02);//turn on Bypass Mode
    HAL_Delay(10);
    HALIIC_WriteByteToSlave(AK8963_MAG_ADDRESS,0x0A,0x11);
    HAL_Delay(10);

    HALIIC_ReadMultByteFromSlave(AK8963_MAG_ADDRESS,MAG_XOUT_L, 6, buf);
    magData[0] = (int16_t)((buf[1] << 8) | buf[0]) ;
    magData[1] = (int16_t)((buf[3] << 8) | buf[2]) ;
    magData[2] = (int16_t)((buf[5] << 8) | buf[4]) ;
}

/******************************************************************************
* 功  能:温度值读取
* 参  数:*tempdata 温度数据的指针
* 返回值:无
*******************************************************************************/
void MPU9250_TempRead(float *tempdata)
{
	uint8_t buf[2];
	short data;
	MPU9250_ReadMultBytes(MPU9250_RA_TEMP_OUT_H, 2, buf);
	data = (int16_t)((buf[0] << 8) | buf[1]) ;
	*tempdata = 21f + ((float)data/333.87f);
}

3、使用

int16_t acc[3],gyy[3],mag[3];

MPU9250_AccRead(acc);
MPU9250_GyroRead(gyy);
MPU9250_MagRead(mag);
ANO_DT_Send_Senser(acc[0],acc[1],acc[2],gyy[0],gyy[1],gyy[2],mag[0],mag[1],mag[2],0);

注:ANO_DT_Send_Senser函数是适用于匿名电子的V6版本上位机的发送协议,可以用来看波形显示

#define BYTE0(dwTemp)       ( *( (char *)(&dwTemp)		) )
#define BYTE1(dwTemp)       ( *( (char *)(&dwTemp) + 1) )
#define BYTE2(dwTemp)       ( *( (char *)(&dwTemp) + 2) )
#define BYTE3(dwTemp)       ( *( (char *)(&dwTemp) + 3) )

uint8_t data_to_send[50];	//发送数据缓存

void ANO_DT_Send_Senser(int16_t a_x,int16_t a_y,int16_t a_z,int16_t g_x,int16_t g_y,int16_t g_z,int16_t m_x,int16_t m_y,int16_t m_z,s32 bar)
{
	uint8_t _cnt=0,sum = 0,i;
	vs16 _temp;

	data_to_send[_cnt++]=0xAA;
	data_to_send[_cnt++]=0x05;
	data_to_send[_cnt++]=0xAF;
	data_to_send[_cnt++]=0x02;
	data_to_send[_cnt++]=0;

	_temp = a_x;
	data_to_send[_cnt++]=BYTE1(_temp);
	data_to_send[_cnt++]=BYTE0(_temp);
	_temp = a_y;
	data_to_send[_cnt++]=BYTE1(_temp);
	data_to_send[_cnt++]=BYTE0(_temp);
	_temp = a_z;
	data_to_send[_cnt++]=BYTE1(_temp);
	data_to_send[_cnt++]=BYTE0(_temp);

	_temp = g_x;
	data_to_send[_cnt++]=BYTE1(_temp);
	data_to_send[_cnt++]=BYTE0(_temp);
	_temp = g_y;
	data_to_send[_cnt++]=BYTE1(_temp);
	data_to_send[_cnt++]=BYTE0(_temp);
	_temp = g_z;
	data_to_send[_cnt++]=BYTE1(_temp);
	data_to_send[_cnt++]=BYTE0(_temp);

	_temp = m_x;
	data_to_send[_cnt++]=BYTE1(_temp);
	data_to_send[_cnt++]=BYTE0(_temp);
	_temp = m_y;
	data_to_send[_cnt++]=BYTE1(_temp);
	data_to_send[_cnt++]=BYTE0(_temp);
	_temp = m_z;
	data_to_send[_cnt++]=BYTE1(_temp);
	data_to_send[_cnt++]=BYTE0(_temp);

	data_to_send[4] = _cnt-5;


	for(i=0;i<_cnt;i++)
		sum += data_to_send[i];
	data_to_send[_cnt++] = sum;

	usart_send(data_to_send, _cnt);
}

 

参考文献:

[原创] STM32 的 硬件IIC 很好用

基于MPU-9250和BMP180的IMU 10DOF模块原理图/PCB/demo程序

  • 9
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
在使用STM32 HAL库进行IIC驱动MPU6050时,可以按照以下步骤进行配置和初始化: 1. 首先,添加所需的头文件,包括"oled.h"、"mpu6050.h"、"control.h"、"inv_mpu.h"和"inv_mpu_dmp_motion_driver.h"。\[1\] 2. 在初始化函数中,调用MX_I2C1_Init()函数来初始化IIC总线。\[2\] 3. 调用mpu_init()函数来初始化MPU6050。如果返回值为0,则表示初始化成功。\[2\] 4. 使用mpu_set_sensors()函数设置所需的传感器,例如陀螺仪和加速度计。\[2\] 5. 使用mpu_configure_fifo()函数设置FIFO,以确定传感器数据的存储方式。\[2\] 6. 使用mpu_set_sample_rate()函数设置采样率。\[2\] 7. 调用dmp_load_motion_driver_firmware()函数加载DMP固件。\[2\] 8. 使用dmp_set_orientation()函数设置陀螺仪方向。\[2\] 9. 使用dmp_enable_feature()函数设置DMP功能,例如姿态、敲击和原始数据的发送。\[2\] 10. 使用dmp_set_fifo_rate()函数设置DMP输出速率。\[2\] 11. 调用run_self_test()函数进行自检。\[2\] 12. 使用mpu_set_dmp_state()函数使能DMP。\[2\] 13. 在相关初始化函数定义之后,添加循环代码,通过mpu_dmp_get_data()函数获取角度数据,并进行相应的处理和输出。\[3\] 14. 最后,根据需要添加延时函数,以控制数据的采样频率。\[3\] 以上是使用STM32 HAL库进行IIC驱动MPU6050的基本步骤。根据具体的应用需求,你可能需要进行一些额外的配置和修改。 #### 引用[.reference_title] - *1* *2* *3* [HAL库 STM32CubeMX----SPI驱动OLED 与 IIC驱动MPU6050](https://blog.csdn.net/weixin_62213694/article/details/125018662)[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 ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值