当前位置:网站首页>QMI8658 - 6轴传感器学习笔记
QMI8658 - 6轴传感器学习笔记
2022-07-29 17:23:00 【nicole088】
文章目录
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 初始化
- I2c_addr:
write 0x6B(SA0 = 0) / 0x6A (SA0 = 1)- 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; /开启加速度计和陀螺仪/- Sensor Data Lock register:
0x2D[bit1 bit0] Sensor Data Available and lock:
“0x00”: no new data; “0x03": Sensor Data Locked for reading;- Read output data register:
0x35~0x40- 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. 民间模块
边栏推荐
猜你喜欢

蓝色社交图标登录页面

Out of breath!After 23 years of operation, the former "China's largest e-commerce website" has turned yellow...

分析师:百度到2030年可能成为中国市值最高的公司

巴比特 | 元宇宙每日必读:连续七个季度出现亏损,Meta元宇宙部门Q2亏损28 亿美元,扎克伯格称这种情况可能会持续数年...

leetcode94 -- 二叉树的中序遍历

Chapter 7 XGBoost

go的堆内存结构分析

【STM32CubeMX】STM32H743配置IAP升级

hihoCoder#1037 : 数字三角形(DP)

周末分享-关于微信生态变化和5G
随机推荐
直播实录 | 37 手游如何用 StarRocks 实现用户画像分析
[网络]WAN技术组播
“大龄”裸辞的“孤勇者”们
多智能体协同控制研究中光学动作捕捉与UWB定位技术比较
抗HER2/neu受体拟肽修饰的紫杉醇自蛋白纳米粒/环境敏感型多糖纳米粒的制备,
Thread Dump分析方法
go的堆内存结构分析
service事物失效如何获取代理事物
【深度学习】使用yolov5对数据进行预标注
Blender 源码分析(2)
针不戳!腾讯云架构师出品的《MySQL性能优化和高可用架构实践》
解决报错Unsupported field: HourOfDay
最大化平均值
不堆概念、换个角度聊多线程并发编程
一个redis工具类解决缓存击穿,缓存穿透
【WSL】wsl pip NewConnectionError
How different DAOs are changing the world
【码蹄集新手村600题】求空间直角坐标系中俩点之间的距离
js图片等分对比插件
刚刚,60后复旦校友IPO敲钟:市值400亿
