社区导航

 

搜索
查看: 282|回复: 0

[分享] 基于F103与X-NUCLEO-IKS01A3的计步手环之计步功能

[复制链接]

57

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-8-10 23:08 | 显示全部楼层 |阅读模式
本帖最后由 sylar^z 于 2019-8-11 21:21 编辑

    本次计步手环设计基于F103核心板与X-NUCLEO-IKS01A3传感器开发板。计步功能通过X-NUCLEO-IKS01A3上的LSM6DSO传感器来实现。

    LSM6DSO是一款6轴传感器,包含3轴加速度与3轴陀螺仪。供电电压1.7V-3.6V,可以通过常用的SPI与I2C进行通讯。LSM6DSO带有丰富的运动检测功能,包含计步器、自由落体、唤醒、6d/4d方向、点击和双击等。

    计步手环使用LSM6DSO的计步检测来实现计步功能。在正常移植X-NUCLEO-IKS01A3的驱动的程序(可参看《基于F103与X-NUCLEO-IKS01A3的计步手环之驱动移植》)上进行功能添加。

     首先对之前的程序作了一些改动,让多传感器可以同时工作,并增加了一个检测LSM6DSO的INT1的中断的引脚PB7。接着就是添加计步功能。在完成对LSM6DSO的初始化之后,需要使能LSM6DSO的计步功能,并配置相应的参数及中断输出,以及清除当前步数。然后是检测步行及计算步数。

 

1.设置LSM6DSO的输出频率与满量程值

1.设置输出频率与满量程值.png

 

2.启用计步算法,设置模式。

可选模式如下:

2.PEDO_MODE.png

根据选择的模式,会对一下三个寄存器进行配置,达到计步模式设置。

2.EMB_FUNC_EN_A.png

2.EMB_FUNC_EN_B.png

2.PEDO_CMD_REG.png

 

3.设置计步中断通过INT1输出

    INT1 pin可以绑定多个功能或状态同时使用。当检测到中断后,通过读取对应的事件状态寄存器来确定事件源。

    计步中断属于INT1_EMB_FUNC这个分类

3.MD1_CFG.png


使能LSM6DSO的计步功能,并配置相应的参数及中断输出
/**
 * @brief  Enable pedometer
 * @param  pObj the device pObj
 * @retval 0 in case of success, an error code otherwise
 */
int32_t LSM6DSO_ACC_Enable_Pedometer(LSM6DSO_Object_t *pObj)
{
    lsm6dso_pin_int1_route_t val;

  /* Output Data Rate selection */
  if (LSM6DSO_ACC_SetOutputDataRate(pObj, 26.0f) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  /* Full scale selection */
  if (LSM6DSO_ACC_SetFullScale(pObj, 2) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  /* Enable pedometer algorithm. */
  if (lsm6dso_pedo_sens_set(&(pObj->Ctx), LSM6DSO_PEDO_BASE_MODE) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  /* Enable step detector on INT1 pin */
  if (lsm6dso_pin_int1_route_get(&(pObj->Ctx), &val) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  val.emb_func_int1.int1_step_detector = PROPERTY_ENABLE;

  if (lsm6dso_pin_int1_route_set(&(pObj->Ctx), &val) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  return LSM6DSO_OK;
}


 

4.事件确认及处理

    检测EMB_FUNC_SRC中的STEP_DETECTED标志位,为1,则表示检测到有步行行为。计步数量加1。

4.EMB_FUNC_SRC.png


/**
 * @brief  Get the status of all hardware events
 * @param  pObj the device pObj
 * @param  Status the status of all hardware events
 * @retval 0 in case of success, an error code otherwise
 */
int32_t LSM6DSO_ACC_Get_Event_Status(LSM6DSO_Object_t *pObj, LSM6DSO_Event_Status_t *Status)
{
  uint8_t tilt_ia;
  lsm6dso_wake_up_src_t wake_up_src;
  lsm6dso_tap_src_t tap_src;
  lsm6dso_d6d_src_t d6d_src;
  lsm6dso_emb_func_src_t func_src;
  lsm6dso_md1_cfg_t md1_cfg;
  lsm6dso_md2_cfg_t md2_cfg;
  lsm6dso_emb_func_int1_t int1_ctrl;
  lsm6dso_emb_func_int2_t int2_ctrl;

  (void)memset((void *)Status, 0x0, sizeof(LSM6DSO_Event_Status_t));

  if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_WAKE_UP_SRC, (uint8_t *)&wake_up_src, 1) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_TAP_SRC, (uint8_t *)&tap_src, 1) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_D6D_SRC, (uint8_t *)&d6d_src, 1) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_mem_bank_set(&(pObj->Ctx), LSM6DSO_EMBEDDED_FUNC_BANK) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_EMB_FUNC_SRC, (uint8_t *)&func_src, 1) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_EMB_FUNC_INT1, (uint8_t *)&int1_ctrl, 1) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_EMB_FUNC_INT2, (uint8_t *)&int2_ctrl, 1) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_mem_bank_set(&(pObj->Ctx), LSM6DSO_USER_BANK) != 0)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_MD1_CFG, (uint8_t *)&md1_cfg, 1) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_read_reg(&(pObj->Ctx), LSM6DSO_MD2_CFG, (uint8_t *)&md2_cfg, 1) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if (lsm6dso_tilt_flag_data_ready_get(&(pObj->Ctx), &tilt_ia) != LSM6DSO_OK)
  {
    return LSM6DSO_ERROR;
  }

  if ((md1_cfg.int1_ff == 1U) || (md2_cfg.int2_ff == 1U))
  {
    if (wake_up_src.ff_ia == 1U)
    {
      Status->FreeFallStatus = 1;
    }
  }

  if ((md1_cfg.int1_wu == 1U) || (md2_cfg.int2_wu == 1U))
  {
    if (wake_up_src.wu_ia == 1U)
    {
      Status->WakeUpStatus = 1;
    }
  }

  if ((md1_cfg.int1_single_tap == 1U) || (md2_cfg.int2_single_tap == 1U))
  {
    if (tap_src.single_tap == 1U)
    {
      Status->TapStatus = 1;
    }
  }

  if ((md1_cfg.int1_double_tap == 1U) || (md2_cfg.int2_double_tap == 1U))
  {
    if (tap_src.double_tap == 1U)
    {
      Status->DoubleTapStatus = 1;
    }
  }

  if ((md1_cfg.int1_6d == 1U) || (md2_cfg.int2_6d == 1U))
  {
    if (d6d_src.d6d_ia == 1U)
    {
      Status->D6DOrientationStatus = 1;
    }
  }

  if (int1_ctrl.int1_step_detector == 1U)
  {
    if (func_src.step_detected == 1U)
    {
      Status->StepStatus = 1;
    }
  }

  if ((int1_ctrl.int1_tilt == 1U) || (int2_ctrl.int2_tilt == 1U))
  {
    if (tilt_ia == 1U)
    {
      Status->TiltStatus = 1;
    }
  }

  return LSM6DSO_OK;
}


 

附源码: CORE-STM32F103C8_FOR_X-NUCLEO_IKS01A3-PEDOMETER.rar (13.26 MB, 下载次数: 16)



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐上一条 /3 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2019-8-23 00:14 , Processed in 0.081916 second(s), 18 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表