博世BMA400传感器API (中文说明)

最近项目中要使用BMA400(sensor),为了以后查找,这里只是对API进行翻译,有些地方翻译可能出错,请指出来一起探讨。谢谢各位看官^_^

BMA_400数据手册:https://download.csdn.net/download/qq_36075612/10861941

BMA400传感器API

内容表

导言<a name=Intro></a>

这个包包含Bosch Sensortec的BMA400传感器驱动程序(传感器API)

传感器驱动程序包包括bma400.h、bma400.c和bma400_defs.h文件。

版本和日期<a name=Ver></a>

Driver files Version Date
bma400.c 1.4.0 07 Dec 2017
bma400.h 1.4.0 07 Dec 2017
bma400_defs.h 1.4.0 07 Dec 2017

集成细节a name=Integration></a>

  • bma400.hbma400_defs.hbma400.c文件集成到项目中。

  • 在代码中包含bma400.h文件,如下所示。

#include "bma400.h"

设备文件信息<a name=file></a>

  • bma400.c : 这个源文件包含传感器API接口的函数定义

  • bma400.h : 这个头文件包含传感器API接口的函数声明

  • bma400_defs.h : 这个头文件具有常量、宏和数据类型声明。

传感器接口<a name=interface></a>

  • I2C

  • SPI 4-wire

集成示例<a name=examples></a>

初始化传感器

要初始化传感器,首先需要创建一个设备结构。

可以通过创建结构bma400_dev的实例来实现这一点。

然后更新结构中的各种参数,如下所示。

SPI 4-Wire接口的初始化

int8_t rslt;
struct bma400_dev accel;
​
/* SPI与本机芯片选择线的传感器接口 */
accel.id = 0;
accel.interface = BMA400_SPI_INTF;
accel.read = user_spi_read;
accel.write = user_spi_write;
accel.delay_ms = user_delay_ms;
​
rslt = bma400_init(&accel);
​
if (rslt == BMA400_OK) {
    /* 如果初始化成功,将打印传感器芯片ID。 */
    printf("\n Chip ID of the BMA400 is : %d",accel.chip_id);
}

初始化I2C接口

int8_t rslt;
struct bma400_dev accel;
​
/* 基于I2C的传感器接口 */
accel.id = BMA400_I2C_ADDRESS_SDO_LOW;
accel.interface = BMA400_I2C_INTF;
accel.read = user_i2c_read;
accel.write = user_i2c_write;
accel.delay_ms = user_delay_ms;
​
rslt = bma400_init(&accel);
​
if(rslt == BMA400_OK) {
    /* 如果初始化成功,将打印传感器芯片ID。 */
    printf("\n Chip ID of the BMA400 is : %d",accel.chip_id);
}

传感器配置设置

先决条件:在SPI或I2C中初始化传感器

示例以将传感器的功率模式设置为正常模式

int8_t rslt;
struct bma400_dev accel;
​
/* 从bma400_defs.h文件中设置所需的电源模式宏 */
rslt = bma400_set_power_mode(BMA400_SET_NORMAL_MODE, &accel);
​

示例设置传感器配置

int8_t rslt;
struct bma400_dev accel;
/* 加速度计设置结构 */
struct bma400_setting accel_setting;
​
/* 选择要修改的配置类型 */
accel_setting.type = BMA400_ACCEL;
​
/* 获取传感器中设置的加速器配置 */
rslt = bma400_get_sensor_setting(&accel_setting, 1, &accel);
​
/* 根据宏修改所需的配置
 *在bma400_defs.h文件中可用 */
accel_setting.conf.accel.odr = BMA400_ODR_100HZ;
accel_setting.conf.accel.range = BMA400_2G_RANGE;
accel_setting.conf.accel.data_src = BMA400_DATA_SRC_ACCEL_FILT_1;
​
/* 在传感器中设置所需的配置 */
rslt = bma400_set_sensor_setting(&accel_setting, 1, &accel);

BMA400数据读取

示例读取传感器数据以及传感器时间

int8_t rslt;
struct bma400_dev accel;
/* 用于存储传感器数据的结构 */
struct bma400_sensor_data data;
​
/* 为了只读加速数据,我们应该使用宏BMA400_DATA_ONLY
 *为了只读accel和sensortime,我们应该使用宏BMA400_DATA_SENSOR_TIME */
rslt = bma400_get_accel_data(BMA400_DATA_SENSOR_TIME, &data, &accel);
if (rslt == BMA400_OK) {
    printf("\n Accel data : X : %d \t Y : %d \t  Z : %d \t Sensor time: %d"
            ,data.x,data.y,data.z,data.sensortime);
}

BMA400自动唤醒和自动低功耗特性

在传感器中使用自动唤醒和自动低功耗特性

/* 自动唤醒超时测试设置 */
int8_t bma400_timeout_autowakeup_auto_lp(struct bma400_dev *dev)
{
    int8_t rslt = 0;
    uint8_t power_mode;
    uint16_t int_status;
    struct bma400_device_setting dev_setting[2];
​
    /* 选择超时自动唤醒 */
    dev_setting[0].type = BMA400_AUTOWAKEUP_TIMEOUT;
    
    /* 选择自动低功耗模式 */
    dev_setting[1].type = BMA400_AUTO_LOW_POWER;
​
    /* 获取先前设置的设置 */
    rslt = bma400_get_device_setting(&dev_setting, 1, dev);
    if (rslt == BMA400_OK) {
        /* 启用超时自动唤醒功能 */
        dev_setting[0].conf.auto_wakeup.wakeup_timeout = BMA400_ENABLE;
        /* 将超时值设置为最大(10.24s) */
        dev_setting[0].conf.auto_wakeup.timeout_thres = BMA400_AUTO_WAKEUP_TIMEOUT_MAX;
​
        /* 设置自动低功耗超时功能  */
        dev_setting[1].conf.auto_lp.auto_low_power_trigger = BMA400_AUTO_LP_TIMEOUT_EN;
        /* 将超时值设置为最大(10.24s) */
        dev_setting[1].conf.auto_lp.auto_lp_timeout_threshold = BMA400_AUTO_LP_TIMEOUT_MAX;
​
        /* 设置传感器中的配置 */
        rslt = bma400_set_device_setting(&dev_setting, 1, dev);
​
        /* 传感器每10.24秒在低功率模式和正常模式之间切换。
         *由用户配置,可以通过读取电源模式进行测试和验证
         *并连续打印如下
         *  while (1) {
         *      rslt = bma400_get_power_mode(&power_mode, dev);
         *      printf("\n POWER MODE : %d",power_mode);
         *  }
         * 电源模式切换可以从打印的控制台输出中看到
         */
    }
     
    return rslt;
}

BMA400中断配置

可以通过以下方式配置BMA400中断 下面描述的用于配置通用中断的方法

BMA400通用中断配置

通用中断1和2的使用,用于传感器中的活动/非活动检测_

/* 通用中断特性 */
int8_t bma400_generic_interrupts(struct bma400_dev *dev)
{
    int8_t rslt = 0;
    /* 变量以存储中断状态 */
    uint16_t int_status;
    /* 传感器配置结构 */
    struct bma400_setting accel_settin[2];
    /* 中断配置结构 */
    struct interrupt_enable int_en[2];
​
    /* 为配置 选择GEN1和GEN2中断 */
    accel_settin[0].type = BMA400_GEN1_INT;
    accel_settin[1].type = BMA400_GEN2_INT;
​
    /* 获取传感器中设置的配置 */
    rslt = bma400_get_sensor_setting(&accel_settin[0], 2, dev);
​
    /* 从当前的“gen_int”结构中修改所需的参数
     *在“bma400_set”结构内部配置所选的
     *GEN1/GEN2中断 */
    
    if (rslt == BMA400_OK) {
        /* 设置用于活动检测的GEN 1中断 */
        accel_settin[0].conf.gen_int.int_map          =   BMA400_INT_CHANNEL_1;
        accel_settin[0].conf.gen_int.axes_sel         =   BMA400_XYZ_AXIS_EN;
        accel_settin[0].conf.gen_int.criterion_sel    =   BMA400_ACTIVITY_INT;
        accel_settin[0].conf.gen_int.evaluate_axes    =   BMA400_ANY_AXES_INT;
        accel_settin[0].conf.gen_int.ref_update       =   BMA400_ONE_TIME_UPDATE;
        accel_settin[0].conf.gen_int.data_src         =   BMA400_DATA_SRC_ACC_FILT1;
        accel_settin[0].conf.gen_int.gen_int_thres    =   0x10;
        accel_settin[0].conf.gen_int.gen_int_dur      =   0x01;
        accel_settin[0].conf.gen_int.hysteresis       =   BMA400_HYST_0_MG;
​
        /* 设置GEN 2中断用于活动内检测 */
        accel_settin[1].conf.gen_int.int_map          =   BMA400_INT_CHANNEL_2;
        accel_settin[1].conf.gen_int.axes_sel         =   BMA400_XYZ_AXIS_EN;
        accel_settin[1].conf.gen_int.criterion_sel    =   BMA400_INACTIVITY_INT;
        accel_settin[1].conf.gen_int.evaluate_axes    =   BMA400_ANY_AXES_INT;
        accel_settin[1].conf.gen_int.ref_update       =   BMA400_ONE_TIME_UPDATE;
        accel_settin[1].conf.gen_int.data_src         =   BMA400_DATA_SRC_ACC_FILT1;
        accel_settin[1].conf.gen_int.gen_int_thres    =   0x10;
        accel_settin[1].conf.gen_int.gen_int_dur      =   0x01;
        accel_settin[1].conf.gen_int.hysteresis       =   BMA400_HYST_0_MG;
        
        /* 设置传感器中的配置 */
        rslt = bma400_set_sensor_setting(&accel_settin[0], 2, dev);
​
        if (rslt == BMA400_OK) {
        
            /* 启用传感器中的通用中断 */
            int_en[0].int_sel = BMA400_GEN1_INT_EN;
            int_en[0].conf = BMA400_ENABLE;
            
            int_en[1].int_sel = BMA400_GEN2_INT_EN;
            int_en[1].conf = BMA400_ENABLE;
​
            rslt = bma400_enable_interrupt(&int_en[0], 2, dev);
​
            /* 传感器被移动或保持静止,并且是靠的。
             *在GEN1/GEN2上触发活动/非活动中断
             *根据设置中断 */
            if (rslt == BMA400_OK) {
                while (1) {
                    rslt = bma400_get_interrupt_status(&int_status, dev);
                    printf("\t INT STATUS : %x", int_status);
​
                    if (int_status & BMA400_GEN1_INT_ASSERTED) {
                        printf("\n GEN1 INT ASSERTED (ACTIVITY DETECTION)");
                    }
​
                    if (int_status & BMA400_GEN2_INT_ASSERTED) {
                        printf("\n GEN2 INT ASSERTED (IN-ACTIVITY DETECTION)");
                    }
                }
            }
        }
​
    }
​
    return rslt;
}

检查传感器中是否启用/禁用中断的示例

int8_t bma400_check_int_en(struct bma400_dev *dev)
{
    int8_t rslt = 0;
    struct interrupt_enable int_en[6];
    
    /* 选择我们需要知道的中断
     *是否在传感器中启用它们 */
    int_en[0].int_sel = BMA400_STEP_INT_EN;
    int_en[1].int_sel = BMA400_DRDY_INT_EN;
    int_en[2].int_sel = BMA400_ACTIVITY_CHANGE_INT_EN;
    int_en[3].int_sel = BMA400_ORIENT_CHANGE_INT_EN;
    int_en[4].int_sel = BMA400_FIFO_FULL_INT_EN;
    int_en[5].int_sel = BMA400_FIFO_WM_INT_EN;
    
    /* 从传感器获取启用/禁用状态 */
    rslt = bma400_get_interrupts_enabled(&int_en[0], 6, dev);
​
    /* 打印结果0-means禁用;1-measn启用 */
    printf("\n Step interrupt enabled/disabled : %d",int_en[0].conf);
    printf("\n DRDY interrupt enabled/disabled : %d",int_en[1].conf);
    printf("\n Activity change interrupt enabled/disabled : %d",int_en[2].conf);
    printf("\n ORIENT interrupt enabled/disabled : %d",int_en[3].conf);
    printf("\n FIFO Full interrupt enabled/disabled : %d",int_en[4].conf);
    printf("\n FIFO watermark interrupt enabled/disabled : %d",int_en[5].conf);
​
    return rslt;
}

BMA400的自检

int8_t bma400_self_test(struct bma400_dev *dev)
{
    int8_t rslt = 0;
    
    rslt = bma400_perform_self_test(dev);
    
    if (rslt == BMA400_OK) {
        printf("\n Self test success ");
    } else {
        printf("\n Self test failed ");
    }
​
    return rslt;
}

BMA400温度数据读出

/* 要传递给API的变量 */
int16_t temp_data = 0;
/* 用于存储最终温度数据的变量 */
float temperature_data = 0;
​
rslt = bma400_get_temperature_data(&temp_data, dev);
​
/* 除以10倍以得到准确度
 *具有1小数精度的温度数据 */
temperature_data = ((float)temp_data) / 10.0f;
​
printf("\n Temperature data : %0.1f",temperature_data);

BMA400步骤计数器和活动状态(step_stat_field)

/* 变量以存储步骤计数器数据 */
uint32_t step_count = 0;
/* 变量以存储活动状态 */
uint8_t step_stat_activity = 0;
​
rslt = bma400_get_steps_counted(&step_count, &step_stat_activity, dev);
​
printf("\n Steps Counted : %ld", step_count);
​
switch(step_stat_activity) {
case BMA400_STILL_ACT:
    printf("\n Activity : Staying Still");
    break;
case BMA400_WALK_ACT:
    printf("\n Activity : Walking ");
    break;
case BMA400_RUN_ACT:
    printf("\n Activity : Running ");
    break;
default:
    printf("\n Activity : undefined");
    break;
}

BMA400 FIFO的使用

BMA400 FIFO具有一个FIFO,该FIFO可以被配置为获得 来自FIFO的12/8位模式下数据的x,y,z,x y,y z,x z组合

在BMA400中配置和读取FIFO数据的示例

/* 使用FIFO中启用的xyz数据读取FIFO数据 */
int8_t bma400_fifo_read(struct bma400_dev *dev)
{
    int8_t rslt;
    
    /* 用于解析和打印数据的索引 */
    uint16_t index;
    
    /* 设置和配置FIFO缓冲区 */
    /* 声明内存以存储原始FIFO缓冲区信息 */
    uint8_t fifo_buff[500] = {0};
    
    /* 声明传感器数据结构的实例以存储解析后的FIFO数据 */
    struct bma400_sensor_data accel_data[50] = {0};
    
    /* 用户需要的加速度计框架 */
    uint16_t accel_frames_req = 50;
    
    /* 由用户定义的FIFO配置结构 */
    struct bma400_fifo_frame fifo_frame = {0};
    
    /* 修改FIFO缓冲实例并链接到设备实例 */
    fifo_frame.data = fifo_buff;
    fifo_frame.length = 500;
    dev->fifo = &fifo_frame;
    
    /* 将FIFO配置设置为XYZ在12位模式下启用 */
    struct bma400_device_setting accel_sett;
​
    accel_sett.type = BMA400_FIFO_CONF;
​
    rslt = bma400_get_device_setting(&accel_sett, 1, dev);
​
    if (rslt == BMA400_OK) {
        /* 为了启用8位模式,我们需要显式地使用宏
         *“BMA400_FIFO_8_BIT_EN” */
        accel_sett.conf.fifo_conf.conf_regs = BMA400_FIFO_X_EN | BMA400_FIFO_Y_EN | BMA400_FIFO_Z_EN;
        accel_sett.conf.fifo_conf.conf_status = BMA400_ENABLE;
        
        rslt = bma400_set_device_setting(&accel_sett, 1, dev);
        
        if (rslt == BMA400_OK) {
            /*延迟以填充FIFO数据
             *在ODR为100Hz时,1帧在1/100=0.01s内更新。
             *即,对于50帧,我们需要50*0.01=0.5秒延迟*/
            dev->delay_ms(500);
        
            /* 读取FIFO数据 */
            printf("\n Requested FIFO length : %d \n",dev->fifo->length);
            rslt =  bma400_get_fifo_data(dev);
            if (rslt != BMA400_OK) {
                printf("\n FIFO read failed ");
            }
            printf("\n Available FIFO length : %d \n",dev->fifo->length);
            
            /* 打印FIFO数据缓冲区 */
            for (index = 0; index <= dev->fifo->length; index++) {
                printf("\n FIFO INDEX[%d] = %d", index, dev->fifo->data[index]);
            }
            
            printf("\n Requested FIFO frames : %d \n", accel_frames_req);
            rslt =  bma400_extract_accel(accel_data, &accel_frames_req, dev);
​
            if (rslt != BMA400_OK) {
                printf("\n Accel data extraction failed");
            }
            
            printf("\n Extracted FIFO frames : %d \n", accel_frames_req);
            
            /* 打印来自FIFO缓冲区的加速数据 */
            for (index = 0; index < accel_frames_req + 1; index++) {
                printf("FIFO FRAME[%d] ACCEl X DATA : %d \t  Y DATA : %d \t  Z DATA : %d \n"
                    , index, accel_data[index].x, accel_data[index].y
                    , accel_data[index].z);
            }
            
            printf("\n FIFO SENSOR TIME : %d",dev->fifo->fifo_sensor_time);
            printf("\n FIFO CONF CHANGE : %d",dev->fifo->conf_change);
            
            if (dev->fifo->conf_change & BMA400_FIFO_CONF0_CHANGE) {
                printf("\n FIFO data source configuration changed \n");
            }
            
            if (dev->fifo->conf_change & BMA400_ACCEL_CONF0_CHANGE) {
                printf("\n Accel filt1_bw configuration changed \n");
            }
            
            if (dev->fifo->conf_change & BMA400_ACCEL_CONF1_CHANGE) {
                printf("\n Accel odr/osr/range configuration changed \n");
            }
        }
    }
    
    return rslt;
}

配置FIFO水印中断并启用FIFO完全中断的示例

/* 配置FIFO水印中断和FIFO完全中断 */
int8_t bma400_fifo_interrupts(struct bma400_dev *dev)
{
    int8_t rslt;
​
    /* 包含加速设置的结构 */
    struct bma400_device_setting accel_sett;
​
    /* 包含中断设置的结构 */
    struct interrupt_enable int_select[2];
​
    /* 选择类型为BMA400_FIFO_CONF */
    accel_sett.type = BMA400_FIFO_CONF;
​
    /* 变量以存储中断状态 */
    uint16_t int_status;
​
    /* 获取FIFO配置 */
    rslt = bma400_get_device_setting(&accel_sett, 1, dev);
​
    if (rslt == BMA400_OK) {
        /* 设置FIFO配置 */
        accel_sett.conf.fifo_conf.conf_regs = BMA400_FIFO_X_EN | BMA400_FIFO_Y_EN |BMA400_FIFO_Z_EN;
        accel_sett.conf.fifo_conf.conf_status = BMA400_ENABLE;
​
        /* 将FIFO水印设置为500字节 */
        accel_sett.conf.fifo_conf.fifo_watermark = 500;
​
        /* 将水印中断映射到INT引脚2 */
        accel_sett.conf.fifo_conf.wm_int_map = BMA400_INT_CHANNEL_2;
        /* 将FIFO完全中断映射到INT引脚1 */
        accel_sett.conf.fifo_conf.fifo_full_int_map = BMA400_INT_CHANNEL_1;
​
        /* 设置FIFO配置 */
        rslt = bma400_set_device_setting(&accel_sett, 1, dev);
​
        if (rslt == BMA400_OK) {
            /* 刷新FIFO */
            rslt = bma400_set_fifo_flush(dev);
​
            /* 选择指定的中断并启用它们 */
            int_select[0].int_sel = BMA400_FIFO_FULL_INT_EN;
            int_select[0].conf = BMA400_ENABLE;
​
            int_select[1].int_sel = BMA400_FIFO_WM_INT_EN;
            int_select[1].conf = BMA400_ENABLE;
​
            /* 启用传感器中的中断 */
            rslt = bma400_enable_interrupt(int_select, 2, dev);
​
            while (1) {
                /* 获取中断状态 */
                rslt = bma400_get_interrupt_status(&int_status, dev);
​
                if (int_status & BMA400_FIFO_WM_INT_ASSERTED) {
                    printf("\n FIFO WM INT ASSERTED");
                    /* 断言水印中断,如果
                     *用户希望他可以在这个实例读取FIFO数据 */
                }
​
                if (int_status & BMA400_FIFO_FULL_INT_ASSERTED) {
                    printf("\n FIFO FULL INT ASSERTED");
                    /* 断言FIFO完全中断,如果
                     *用户希望他可以在这个实例读取FIFO数据 */
                }
            }
        }
    }
​
    return rslt;
}

下面三个文件,购买芯片时,厂家会提供,这里我就不贴出来了。

bma400.c

bma400.h

bma400_defs.h

有几位看官,都在询问我关于BMA400的资料,在这我就把它贴出来:链接

发布了41 篇原创文章 · 获赞 63 · 访问量 57万+

猜你喜欢

转载自blog.csdn.net/qq_36075612/article/details/85099313