QMI8658 - 姿态传感器学习笔记 - Ⅰ

本文介绍了QMI8658传感器模块的Pin配置、I2C和SPI接口操作,以及初始化和读取加速度与陀螺仪数据的详细步骤。通过示例代码展示了如何进行通信设置和读写操作,适用于嵌入式硬件和运动传感器应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0. 说在最前面

这里推荐一个 人工智能(AI)的学习网站 点击这里进入
机器学习能以简单、快速、经济划算的方式来改进许多应用。博主今年立的 Flag 🚩 就是进入 AI 知识的学习。 也在此网站上学习过一些,后面也会输出一些学习心得。

1. 前言

QMI8658 传感的相关参数介绍在这里不摘抄,详细请查阅数据手册。在这里重点提一下 AttitudeEngine 。
QMI8658集成了称为 AttitudeEngine 的高级矢量数字信号处理器 (DSP) 运动协处理器。 AttitudeEngine 以高内部采样率有效地编码高频运动,在较低频率的输出数据速率下保持完全的准确性。这使应用程序能够利用低输出数据速率 (ODR) 或按需(主机轮询),同时仍能获取准确的 3D 运动数据。 AttitudeEngine 可减少主机处理器上的数据处理和中断负载,而不会影响 3D 运动跟踪精度。

2. QMI8658 Pin

2.1 引脚说明

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

2.2 Pin-To-Pin

QMI8658 可以与 (LSM6DSM/ICM20690) Pin-To-Pin 兼容设计

3. 参考设计图

3.1 QMI8658-I2C

在这里插入图片描述

3.2 QMI8658-4线SPI

在这里插入图片描述

3.3 QMI8658-3线SPI在这里插入图片描述

3.3 QMI8658 操作流程

在这里插入图片描述

3.1 I2C 接口

unsigned char Qmi8658_write_reg(unsigned char reg, unsigned char value)
{
	unsigned char ret=0;
	unsigned int retry = 0;

	while((!ret) && (retry++ < 5))
	{
		ret = i2c1_write_reg(NULL,qmi8658_slave_addr << 1, reg, &value,1);
	}
	return ret;
}

unsigned char Qmi8658_read_reg(unsigned char reg, unsigned char* buf, unsigned short len)
{
	unsigned char ret=0;
	unsigned int retry = 0;

	while((!ret) && (retry++ < 5))
	{
		ret = i2c1_read_reg(NULL,qmi8658_slave_addr << 1, reg, buf, len);
	}
	return ret;
}

3.2 Qmi8658 初始化

  1. I2c_addr:
    write 0x6B(SA0 = 0) / 0x6A (SA0 = 1)
  2. Init_Configure:
    0x0A= 0xA2; /selftest/
    dealy_ms(1750); /延时1.75s以上:根据MCU,需要调整延时时间/
    0x02 = 0x60; /配置I2C通信模式/
    0x03 = 0xxx; /配置加速度计数据Range和ODR/
    0x04 = 0xxx; /配置陀螺仪数据Range和ODR/
    0x06 = 0xxx; /开启加速度计和陀螺仪低通滤波LPF滤波截止频率/
    0x08 = 0x03; /开启加速度计和陀螺仪/
  3. Sensor Data Lock register:
    0x2D[bit1 bit0] Sensor Data Available and lock:
    “0x00”: no new data; “0x03": Sensor Data Locked for reading;
  4. Read output data register:
    0x35~0x40
  5. Output register:
    First byte is LSB, second byte is MSB.
unsigned char Qmi8658_init(void)
{
	unsigned char qmi8658_chip_id = 0x00;
	unsigned char qmi8658_revision_id = 0x00;
	unsigned char qmi8658_slave[2] = {QMI8658_SLAVE_ADDR_L, QMI8658_SLAVE_ADDR_H};
	unsigned char iCount = 0;

	while((qmi8658_chip_id == 0x00)&&(iCount<2))
	{
		qmi8658_slave_addr = qmi8658_slave[iCount];
		Qmi8658_read_reg(Qmi8658Register_WhoAmI, &qmi8658_chip_id, 1);
		if(qmi8658_chip_id == 0x05)
			break;
		iCount++;
	}
	
	Qmi8658_read_reg(Qmi8658Register_Revision, &qmi8658_revision_id, 1);
	
	if(qmi8658_chip_id == 0x05)
	{
		qmi8658_printf("Qmi8658_init slave=0x%x  Qmi8658Register_WhoAmI=0x%x 0x%x\n", qmi8658_slave_addr,qmi8658_chip_id,qmi8658_revision_id);
		Qmi8658_write_reg(Qmi8658Register_Ctrl1, 0x60);
		qmi8658_config.inputSelection = QMI8658_CONFIG_ACCGYR_ENABLE;//QMI8658_CONFIG_ACCGYR_ENABLE;
		qmi8658_config.accRange = Qmi8658AccRange_2g;
		qmi8658_config.accOdr = Qmi8658AccOdr_500Hz;
		qmi8658_config.gyrRange = Qmi8658GyrRange_64dps;		//Qmi8658GyrRange_2048dps   Qmi8658GyrRange_1024dps
		qmi8658_config.gyrOdr = Qmi8658GyrOdr_500Hz;
		qmi8658_config.magOdr = Qmi8658MagOdr_125Hz;
		qmi8658_config.magDev = MagDev_AKM09918;
		qmi8658_config.aeOdr = Qmi8658AeOdr_128Hz;

		Qmi8658_Config_apply(&qmi8658_config);
		
		Qmi8658_write_reg(Qmi8658Register_Ctrl5, 0x55);
		
		if(1)
		{
			unsigned char read_data = 0x00;
			unsigned char firmware[3] = {0x00};
			Qmi8658_read_reg(Qmi8658Register_Ctrl1, &read_data, 1);
			qmi8658_printf("Qmi8658Register_Ctrl1=0x%x \n", read_data);
			Qmi8658_read_reg(Qmi8658Register_Ctrl2, &read_data, 1);
			qmi8658_printf("Qmi8658Register_Ctrl2=0x%x \n", read_data);
			Qmi8658_read_reg(Qmi8658Register_Ctrl3, &read_data, 1);
			qmi8658_printf("Qmi8658Register_Ctrl3=0x%x \n", read_data);
			Qmi8658_read_reg(Qmi8658Register_Ctrl4, &read_data, 1);
			qmi8658_printf("Qmi8658Register_Ctrl4=0x%x \n", read_data);
			Qmi8658_read_reg(Qmi8658Register_Ctrl5, &read_data, 1);
			qmi8658_printf("Qmi8658Register_Ctrl5=0x%x \n", read_data);
			Qmi8658_read_reg(Qmi8658Register_Ctrl6, &read_data, 1);
			qmi8658_printf("Qmi8658Register_Ctrl6=0x%x \n", read_data);
			Qmi8658_read_reg(Qmi8658Register_Ctrl7, &read_data, 1);
			qmi8658_printf("Qmi8658Register_Ctrl7=0x%x \n", read_data);
			
			Qmi8658_read_reg(0x49, firmware, 3);
			qmi8658_printf("Qmi8658_firmware =0x%x 0x%x 0x%x\n", firmware[0], firmware[1], firmware[2]);
		}
//		Qmi8658_set_layout(2);
		return 1;
	}
	else
	{
		qmi8658_printf("Qmi8658_init fail\n");
		qmi8658_chip_id = 0;
		return 0;
	}
	//return qmi8658_chip_id;
}

3.3 读取加速度与陀螺数据原始数据

void Qmi8658_read_xyz(float acc[3], float gyro[3], unsigned int *tim_count)
{
	unsigned char	buf_reg[12];
	short 			raw_acc_xyz[3];
	short 			raw_gyro_xyz[3];
//	float acc_t[3];
//	float gyro_t[3];

	if(tim_count)
	{
		unsigned char	buf[3];
		unsigned int timestamp;
		Qmi8658_read_reg(Qmi8658Register_Timestamp_L, buf, 3);	// 0x18	24
		timestamp = (unsigned int)(((unsigned int)buf[2]<<16)|((unsigned int)buf[1]<<8)|buf[0]);
		if(timestamp > imu_timestamp)
			imu_timestamp = timestamp;
		else
			imu_timestamp = (timestamp+0x1000000-imu_timestamp);

		*tim_count = imu_timestamp;		
	}
	
	Qmi8658_read_reg(Qmi8658Register_Ax_L, buf_reg, 12); 	// 0x19, 25
	raw_acc_xyz[0] = (short)((unsigned short)(buf_reg[1]<<8) |( buf_reg[0]));
	raw_acc_xyz[1] = (short)((unsigned short)(buf_reg[3]<<8) |( buf_reg[2]));
	raw_acc_xyz[2] = (short)((unsigned short)(buf_reg[5]<<8) |( buf_reg[4]));

	raw_gyro_xyz[0] = (short)((unsigned short)(buf_reg[7]<<8) |( buf_reg[6]));
	raw_gyro_xyz[1] = (short)((unsigned short)(buf_reg[9]<<8) |( buf_reg[8]));
	raw_gyro_xyz[2] = (short)((unsigned short)(buf_reg[11]<<8) |( buf_reg[10]));
	
	qmi8658_printf("%d %d %d %d %d %d\n", raw_acc_xyz[0], raw_acc_xyz[1], raw_acc_xyz[2], raw_gyro_xyz[0], raw_gyro_xyz[1], raw_gyro_xyz[2]);

#if defined(QMI8658_UINT_MG_DPS)
	// mg
	acc[AXIS_X] = (float)(raw_acc_xyz[AXIS_X]*1000.0f)/acc_lsb_div;
	acc[AXIS_Y] = (float)(raw_acc_xyz[AXIS_Y]*1000.0f)/acc_lsb_div;
	acc[AXIS_Z] = (float)(raw_acc_xyz[AXIS_Z]*1000.0f)/acc_lsb_div;
#else
	// m/s2
	acc[AXIS_X] = (float)(raw_acc_xyz[AXIS_X]*ONE_G)/acc_lsb_div;
	acc[AXIS_Y] = (float)(raw_acc_xyz[AXIS_Y]*ONE_G)/acc_lsb_div;
	acc[AXIS_Z] = (float)(raw_acc_xyz[AXIS_Z]*ONE_G)/acc_lsb_div;
#endif
//	acc[AXIS_X] = imu_map.sign[AXIS_X]*acc_t[imu_map.map[AXIS_X]];
//	acc[AXIS_Y] = imu_map.sign[AXIS_Y]*acc_t[imu_map.map[AXIS_Y]];
//	acc[AXIS_Z] = imu_map.sign[AXIS_Z]*acc_t[imu_map.map[AXIS_Z]];

#if defined(QMI8658_UINT_MG_DPS)
	// dps
	gyro[0] = (float)(raw_gyro_xyz[0]*1.0f)/gyro_lsb_div;
	gyro[1] = (float)(raw_gyro_xyz[1]*1.0f)/gyro_lsb_div;
	gyro[2] = (float)(raw_gyro_xyz[2]*1.0f)/gyro_lsb_div;
#else
	// rad/s
	gyro[AXIS_X] = (float)(raw_gyro_xyz[AXIS_X]*0.01745f)/gyro_lsb_div;		// *pi/180
	gyro[AXIS_Y] = (float)(raw_gyro_xyz[AXIS_Y]*0.01745f)/gyro_lsb_div;
	gyro[AXIS_Z] = (float)(raw_gyro_xyz[AXIS_Z]*0.01745f)/gyro_lsb_div;
#endif	
//	gyro[AXIS_X] = imu_map.sign[AXIS_X]*gyro_t[imu_map.map[AXIS_X]];
//	gyro[AXIS_Y] = imu_map.sign[AXIS_Y]*gyro_t[imu_map.map[AXIS_Y]];
//	gyro[AXIS_Z] = imu_map.sign[AXIS_Z]*gyro_t[imu_map.map[AXIS_Z]];
}

4. 民间模块

4.1 模块获取链接

在这里插入图片描述

4.2 模块资料更新记录

在这里插入图片描述

🚩


视频展示

QMI8658-6D传感器波形输出

根据引用\[1\]中的代码,qmi8658读取数值的方式取决于数据锁定机制的状态。当STATUSINT读取数据为0x81时,表示未使用数据锁定机制,此时读取的数值为实际值。而当STATUSINT读取数据为0x03时,表示使用数据锁定机制,此时读取的数值需要减去静止时读取的值,即imu.accRaw\[0\]-imu.accOffset\[0\]。\[1\] #### 引用[.reference_title] - *1* [QMI8658 - 姿态传感器学习笔记 - Ⅱ](https://blog.csdn.net/nicole088/article/details/126163082)[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] - *2* [无人机项目跟踪记录四十三---读取陀螺仪函数(ReadIMUSensorHandle)](https://blog.csdn.net/wyssailing/article/details/115272676)[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* [高通SDX12:跨子系统数据共享实例分享](https://blog.csdn.net/qq_42139745/article/details/126549301)[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 ]
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「Thunder Studio」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值