IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 九轴运动传感器--BMX160,硬件开发与程序设计 -> 正文阅读

[嵌入式]九轴运动传感器--BMX160,硬件开发与程序设计

九轴运动传感器–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
关于硬件有什么问题欢迎私信。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-07 10:59:11  更:2021-09-07 10:59:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:31:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码