前言
最近项目中要使用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.h和bma400_defs.h和bma400.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的资料,在这我就把它贴出来:链接