九轴运动传感器–BMX160,硬件开发与程序设计
前言
和之前OPT3001传感器一块板子上的九轴传感器的代码我写完啦,和大家分享一下
硬件部分介绍
BMX160介绍
BMX160是博世的九轴运动传感器,集成了加速度、陀螺仪、磁力计三种传感器,其中加速度传感器基于BMI160,磁力计基于BMM150,可以说是BMX160是由BMI160、BMM150组成的。但性能参数在一些地方有差距。但在程序设计过程中,可以感觉到加速度陀螺仪和磁力计两部分的寄存器之间是有割裂的。磁力计的部分需要做特殊的间接读写。
BMX160支持SPI和IIC通讯,支持FIFO、多种运动中断等高级玩法。
应用
我想集成运动传感器的最初始的想法只是想要知道目前姿态,来设置屏幕的水平和垂直,但为了学习和日后的高级玩法,我还是喜欢功能、性能多一些的传感器。
电路部分
参考官方的的电路,电路部分很简单。
程序设计
程序架构介绍
程序一共有7个文件,所以我没有直接集成在ST的库中,而是直接单列了个文件夹。
BMX160_use.c:主要存放功能函数,一般外部文件只需要调用该文件中的函数,也是架构最外层的部分
BMX160_Control.c:主要存放底层函数和设备配置策略函数,比如SPI、IIC的读写,BMX160初始化过程中的配置参数、IIC地址、中断引脚等,一般移植需要修改这部分参数。
BMX160_Algorithm.c:主要存放一些计算类的函数,方便use文件直接调用。目前因为没有涉及太多的姿态运算,所以该文件目前只有些二进制位运算函数。
BMX160_Register.h:主要存放BMX160的寄存器位置。处于架构的最内层
移植部分
移植只需要BMX160_Control.c文件中的这部分。
Sensor_BMX160 BMX160_1;
int BMX160_Pretreatment(void)
{
BMX160_1.COM_Mode = BMX160_COM_Mode;
#if BMX160_COM_Mode == BMX160_IIC
BMX160_1.IIC_Aisle = hi2c1;
BMX160_1.IIC_ADDR = 0x69;
#else
BMX160_1.SPI_Aisle;
#endif
/**********加速度策略**********/
BMX160_1.ACC_CONF_RANGE.ACC_RANGE = BMX160_ACC_RANGE_2g;
/**********陀螺仪策略**********/
BMX160_1.GYR_CONF_RANGE.GYR_RANGE = BMX160_GYR_RANGE_125;
/**********磁力计策略**********/
BMX160_1.MAG_CONF_RANGE.MAG_XY_Mode = BMX160_MAG_Mode_HighPrecision;
BMX160_1.MAG_CONF_RANGE.MAG_Z_Mode = BMX160_MAG_Mode_HighPrecision;
BMX160_1.MAG_CONF_RANGE.MAG_odr = BMX160_MAG_RANGE_12_5;
/**********校准策略**********/
BMX160_1.ACC_GYR_FOC_off.FOC_GYR_EN = BMX160_FOC_GYR_ON;
BMX160_1.ACC_GYR_FOC_off.FOC_ACC_X = BMX160_FOC_ACC_Recoup_0g;
BMX160_1.ACC_GYR_FOC_off.FOC_ACC_Y = BMX160_FOC_ACC_Recoup_0g;
BMX160_1.ACC_GYR_FOC_off.FOC_ACC_Z = BMX160_FOC_ACC_Recoup_P_1g;
BMX160_1.ACC_GYR_FOC_off.Off_ACC_EN = BMX160_off_ACC_ON;
BMX160_1.ACC_GYR_FOC_off.Off_GYR_EN = BMX160_off_GYR_ON;
return BMX160_OK;
}
默认是使用IIC通讯,SPI通讯的接口我做了兼容,但底层函数需要自己写一下。然后修改BMX160_Control.h这行代码
#define BMX160_COM_Mode BMX160_IIC //BMX160的通讯方式
修改为:
#define BMX160_COM_Mode BMX160_SPI//BMX160的通讯方式
其中如果没有其他特殊需求,四个配置策略不用修改,只需要修改接口部分的参数就可以了。
在BMX160_use.c中的初始化函数中,我做了一个例程,循环输出三种传感器的数值
int BMX160_Init(void)
{
if (BMX160_Pretreatment() != BMX160_OK) //初始化结构体
{
return BMX160_Error;
}
//读取设备ID
uint8_t DATA = {0};
BMX160_Get_ChipID(&BMX160_1, &DATA);
printf("%X\n", DATA);
//重置设备
BMX160_CMD(&BMX160_1, BMX106_CMD_Softreset);
HAL_Delay(100);
//将三个传感器设置为普通模式
BMX160_CMD(&BMX160_1, BMX106_CMD_PMU_ACC_Normal);
HAL_Delay(10);
BMX160_CMD(&BMX160_1, BMX106_CMD_PMU_GYR_Normal);
HAL_Delay(80);
BMX160_CMD(&BMX160_1, BMX106_CMD_PMU_MAG_Normal);
HAL_Delay(10);
//读取功率模式
int Mode[3];
BMX160_Get_PMU_STATUS(&BMX160_1, &Mode[0], &Mode[1], &Mode[2], Report_Y);
float DATA1 = 0;
BMX160_Get_Temperature(&BMX160_1, &DATA1);
printf("%f\n", DATA1);
//配置加速度计采样策略
BMX160_ACC_Sampling_Mode(&BMX160_1, BMX160_ACC_Normal_Oversampling, BMX160_ACC_ODR_100);
BMX160_ACC_RANGE(&BMX160_1, BMX160_1.ACC_CONF_RANGE.ACC_RANGE);
//配置陀螺仪采样策略
BMX160_GYR_Sampling_Mode(&BMX160_1, BMX160_GYR_Normal_Oversampling, BMX160_GYR_ODR_100);
BMX160_GYR_RANGE(&BMX160_1, BMX160_1.GYR_CONF_RANGE.GYR_RANGE);
//配置磁力计采样策略
BMX160_MAG_Sampling_Mode(&BMX160_1, BMX160_1.MAG_CONF_RANGE.MAG_XY_Mode, BMX160_1.MAG_CONF_RANGE.MAG_Z_Mode, BMX160_1.MAG_CONF_RANGE.MAG_odr);
//校准
BMX160_Auto_Calibration(&BMX160_1);
//读取数据
float ACC_DATA[3] = {0};
float GYR_DATA[3] = {0};
float MAG_DATA[3] = {0};
while (1)
{
BMX160_Get_ACC(&BMX160_1, &ACC_DATA[0], &ACC_DATA[1], &ACC_DATA[2]);
BMX160_Get_GYR(&BMX160_1, &GYR_DATA[0], &GYR_DATA[1], &GYR_DATA[2]);
BMX160_Get_MAG(&BMX160_1, &MAG_DATA[0], &MAG_DATA[1], &MAG_DATA[2]);
printf("加速度:");
printf("X:%.2f", ACC_DATA[0]);
printf(",");
printf("Y:%.2f", ACC_DATA[1]);
printf(",");
printf("Z:%.2f", ACC_DATA[2]);
printf("\r\n");
printf("陀螺仪:");
printf("X:%.2f", GYR_DATA[0]);
printf(",");
printf("Y:%.2f", GYR_DATA[1]);
printf(",");
printf("Z:%.2f", GYR_DATA[2]);
printf("\r\n");
printf("磁力计:");
printf("X:%.2f", MAG_DATA[0]);
printf(",");
printf("Y:%.2f", MAG_DATA[1]);
printf(",");
printf("Z:%.2f", MAG_DATA[2]);
printf("\r\n\r\n\r\n");
HAL_Delay(500);
}
}
在校准程序之后的代码都可以根据自己需要进行修改,但不建议删除输出数据上面的一些配置代码。配置策略的配置参数在BMX160_Control.h中存放,可以直接赋值过来修改。
API介绍
当初始化完成之后,最主要的就是三个传感器+温度的数据获取了。
/**
* @brief 直接获取磁力计的三轴参数
* @param BMX160:目标设备
* @param DATA_X:X轴参数
* @param DATA_Y:Y轴参数
* @param DATA_Z:Z轴参数
* @retval 初始化结果
*/
int BMX160_Get_MAG(Sensor_BMX160 *BMX160, float *DATA_X, float *DATA_Y, float *DATA_Z)
/**
* @brief 直接获取加速度计的三轴参数
* @param BMX160:目标设备
* @param DATA_X:X轴参数
* @param DATA_Y:Y轴参数
* @param DATA_Z:Z轴参数
* @retval 初始化结果
*/
int BMX160_Get_ACC(Sensor_BMX160 *BMX160, float *DATA_X, float *DATA_Y, float *DATA_Z)
/**
* @brief 直接获取陀螺仪的三轴参数
* @param BMX160:目标设备
* @param DATA_X:X轴参数
* @param DATA_Y:Y轴参数
* @param DATA_Z:Z轴参数
* @retval 初始化结果
*/
int BMX160_Get_GYR(Sensor_BMX160 *BMX160, float *DATA_X, float *DATA_Y, float *DATA_Z)
/**
* @brief 获取传感器温度
* @param BMX160:目标设备
* @param DATA:温度值
* @retval 获取是否成功
*/
int BMX160_Get_Temperature(Sensor_BMX160 *BMX160, float *DATA)
BMX160比较有意思的是,有一个寄存器比较特殊,CMD命令寄存器,重置、调整三传感器的功率模式等都需要通过该寄存器实现。
/**
* @brief CMD命令
* @param BMX160:目标设备
* @param CMD:CMD命令
* @retval 发送结果
*/
int BMX160_CMD(Sensor_BMX160 *BMX160, uint8_t CMD)
CMD命令可以为(在BMX_use.h文件中复制):
#define BMX160_CMD_PMU_ACC_Suspend 0x10 //加速度计暂停模式
#define BMX160_CMD_PMU_ACC_Normal 0x11 //加速度计普通模式
#define BMX160_CMD_PMU_ACC_LowPower 0x12 //加速度计低功耗模式
#define BMX160_CMD_PMU_GYR_Suspend 0x14 //陀螺仪计暂停模式
#define BMX160_CMD_PMU_GYR_Normal 0x15 //陀螺仪计普通模式
#define BMX160_CMD_PMU_GYR_FastStartUp 0x17 //陀螺仪计快速启动模式
#define BMX160_CMD_PMU_MAG_Suspend 0x18 //磁力计计暂停模式
#define BMX160_CMD_PMU_MAG_Normal 0x19 //磁力计计普通模式
#define BMX160_CMD_PMU_MAG_LowPower 0x1a //磁力计计低功耗模式
#define BMX160_CMD_StartFoc 0x03 //加速度和陀螺仪的快速偏移校准
#define BMX160_CMD_ProgNvm 0xa0 //写入NVM
#define BMX160_CMD_FifoFlush 0xb0 //清除Fifo中所有数据
#define BMX160_CMD_IntReset 0xb1 //重置中断引擎
#define BMX160_CMD_Softreset 0xb6 //重启
#define BMX160_CMD_StepCntClr 0xb2 //步数计数器重置
中断部分
BMX160的中断部分比较复杂,我目前还不打算写,一是目前没有这个需求,因为只是在面包板阶段,等到了集成到总电路板的时候,我也会写。二是需要运动测试,面包板太大不太方便测试,到做成手持设备时候在测试就好多了。可以期待一下吧,当然,我如果写中断部分也是全部写完了,不会需要那部分写哪部分了。
开源地址
和OPT3001是一个库,后续的两个传感器我也会抓紧开发。
可以去白嫖了~下载的时候求求点一下星星,抱拳了!
github :https://github.com/lijinlong21549/Sensor-collection
关于硬件有什么问题欢迎私信。
版权声明:本文为CSDN博主「zhe_boy_is_z」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhe_boy_is_z/article/details/120140240
暂无评论