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

sylar^z   2019-8-11 14:16 楼主

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

    LIS2DW12是一款高性能超低功耗三轴加速度计。供电电压1.62V-3.6V,可以通过常用的SPI与I2C进行通讯。LIS2DW12带有静止检测、运动检测功能。

    计步手环使用LIS2DW12的运动检测来实现唤醒功能。在之前添加计步功能的程序(参看《 基于F103与X-NUCLEO-IKS01A3的计步手环之计步功能》)基础上进行功能添加。LIS2DW12传感器在(灵敏度可通过设置调整)受到震动后通过INT引脚输出高电平信号,通知F103核心板执行唤醒动作。实际操作时只要轻点X-NUCLEO-IKS01A3,产生震动效果就可触发唤醒功能。

     首先对之前的程序作了一些改动,使能了LIS2DW12传感器,并增加了一个检测LIS2DW12的INT1的中断的引脚PB11。接着就是添加唤醒功能。在完成对LIS2DW12的初始化之后,需要使能LIS2DW12的唤醒功能,并配置相应的参数及中断输出。然后是检测唤醒中断及事件处理(这里是点亮OLED屏)。

 

1.设置LIS2DW12的输出频率、运行模式选择及满量程设置

运行可选模式如下:

1.模式选择.png

根据选择的模式,对以下三个寄存器进行配置。

1.CTRL1.png 1.CTRL3.png 1.CTRL6.png

 

2.设置唤醒参数

 

2.WAKE_UP_THS.png

2.WAKE_UP_DUR.png

 

3.设置唤醒中断通过INT1输出

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

 唤醒中断为INT1_WU。

3.CTRL4_INT1_PAD_CTRL.png

3.CTRL7.png


使能LIS2DW12的唤醒功能,并配置相应的参数及中断输出

/**
 * @brief  Enable wake up detection
 * @param  pObj the device pObj
 * @retval 0 in case of success, an error code otherwise
 */
int32_t LIS2DW12_ACC_Enable_Wake_Up_Detection(LIS2DW12_Object_t *pObj)
{
  int32_t ret = LIS2DW12_OK;
  lis2dw12_ctrl4_int1_pad_ctrl_t val;

  /* Output Data Rate selection */
  if (LIS2DW12_ACC_SetOutputDataRate(pObj, 200.0f) != LIS2DW12_OK)
  {
    return LIS2DW12_ERROR;
  }

  /* Full scale selection */
  if (LIS2DW12_ACC_SetFullScale(pObj, 2) != LIS2DW12_OK)
  {
    return LIS2DW12_ERROR;
  }

  /* WAKE_DUR setting */
  if (lis2dw12_wkup_dur_set(&(pObj->Ctx), 0x00) != LIS2DW12_OK)
  {
    return LIS2DW12_ERROR;
  }

  /* Set wake up threshold. */
  if (lis2dw12_wkup_threshold_set(&(pObj->Ctx), 0xf) != LIS2DW12_OK)
  {
    return LIS2DW12_ERROR;
  }

  if (lis2dw12_pin_int1_route_get(&(pObj->Ctx), &val) != LIS2DW12_OK)
  {
    return LIS2DW12_ERROR;
  }

  val.int1_wu = PROPERTY_ENABLE;

  if (lis2dw12_pin_int1_route_set(&(pObj->Ctx), &val) != LIS2DW12_OK)
  {
    return LIS2DW12_ERROR;
  }

  return ret;
}


4.事件确认及处理

    检测STATUS寄存器中的WU_IA标志位,为1,则表示检测到有唤醒行为。执行唤醒后的动作,点亮OLED屏显示当前步数。

4.STATUS.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 LIS2DW12_ACC_Get_Event_Status(LIS2DW12_Object_t *pObj, LIS2DW12_Event_Status_t *Status)
{
  lis2dw12_status_t status_reg;
  lis2dw12_ctrl4_int1_pad_ctrl_t ctrl4_int1_reg;
  lis2dw12_ctrl5_int2_pad_ctrl_t ctrl5_int2_reg;

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

  if (lis2dw12_read_reg(&(pObj->Ctx), LIS2DW12_STATUS, (uint8_t *)&status_reg, 1) != LIS2DW12_OK)
  {
    return LIS2DW12_ERROR;
  }

  if (lis2dw12_read_reg(&(pObj->Ctx), LIS2DW12_CTRL4_INT1_PAD_CTRL, (uint8_t *)&ctrl4_int1_reg, 1) != LIS2DW12_OK)
  {
    return LIS2DW12_ERROR;
  }

  if (lis2dw12_read_reg(&(pObj->Ctx), LIS2DW12_CTRL5_INT2_PAD_CTRL, (uint8_t *)&ctrl5_int2_reg, 1) != LIS2DW12_OK)
  {
    return LIS2DW12_ERROR;
  }

  if (ctrl4_int1_reg.int1_wu == 1U)
  {
    if (status_reg.wu_ia == 1U)
    {
      Status->WakeUpStatus = 1;
    }
  }

  if (ctrl4_int1_reg.int1_6d == 1U)
  {
    if (status_reg._6d_ia == 1U)
    {
      Status->D6DOrientationStatus = 1;
    }
  }

  if (ctrl5_int2_reg.int2_sleep_chg == 1U)
  {
    if (status_reg.sleep_state == 1U)
    {
      Status->SleepStatus = 1;
    }
  }

  return LIS2DW12_OK;
}


 

附源码:

CORE-STM32F103C8_FOR_X-NUCLEO_IKS01A3-WAKEUP.rar (13.29 MB)
(下载次数: 11, 2019-8-11 14:13 上传)

LIS2DW12手册:

lis2dw12.pdf (1.82 MB)
(下载次数: 2, 2019-8-11 21:18 上传)

本帖最后由 sylar^z 于 2019-8-11 21:19 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复