这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » [分享] 基于F103与X-NUCLEO-IKS01A3的计步手环之计步功能

共1条 1/1 1 跳转至

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

工程师
2019-08-13 19:11:45     打赏

本次计步手环设计基于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.jpg

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

可选模式如下:

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

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

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

    计步中断属于INT1_EMB_FUNC这个分类

3.jpg

使能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.jpg

/**
 * @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;
}




共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]