概述
用于配置和设置 STHS34PF80 传感器的一些参数,以便进行存在检测和运动检测。
样品申请
https://www.wjx.top/vm/OhcKxJk.aspx#
视频教程
https://www.bilibili.com/video/BV1Qm4y1p79X/
完整代码下载
https://download.csdn.net/download/qq_24312945/88216813
参考程序初始化
相对于驱动人体检测demo,新的案例设置了传感器的存在和运动相关的阈值、滞后和中断配置,以实现存在检测和运动检测的功能,并在相关事件发生时触发中断。
省电模式
下面文本描述了关机模式的使用和功能。关机模式是一种休眠模式,用于将传感器设备置于休眠状态,从而节省功耗。在关机模式下,设备停止数据采集,并且大部分内部模块都被关闭,以最小化电流消耗。这使得传感器在供电的情况下能够实现最低的功耗水平。
尽管设备处于关机模式,但它仍保持 I²C / SPI 通信串口处于活动状态,以便能够与设备进行通信和配置设置。关机模式下,配置寄存器的内容被保留,而输出数据寄存器不会更新,这意味着在进入关机模式前,最后一次采样的数据将保留在内存中。
为了进入关机模式并避免在重新进入连续模式时读取错误的输出数据,文本提供了正确的步骤。然而,这些步骤在你的问题中并未提供,因此无法给出完整的步骤。
上面文档主要对0x25,0x23,0x20寄存器进行操作,其中读取0x25多次,主要功能是对STATUS (23h)的DRDY进行清0。
查看下面表格也可以得知,有多种操作可以对STATUS (23h)的DRDY 清零。
其中0x20是配置速率寄存器。
设置存在阈值
存在检测如下所示。
以设置存在阈值为例,探索设置的步骤。
这里使用的函数为 sths34pf80_presence_threshold_set(STHS34PF80_ADDRESS, 200)。
/**
* @brief Presence threshold.[set]
*
* @param ctx read / write interface definitions
* @param val presence threshold level
* @retval interface status (MANDATORY: return 0 - > no Error)
*
*/
uint8_t sths34pf80_presence_threshold_set(uint8_t add, uint16_t val)
{
sths34pf80_ctrl1_t ctrl1;
uint8_t odr;
uint8_t buff[2];
int32_t ret;
if ((val & 0x8000U) != 0x0U) {
/* threshold values are on 15 bits */
return -1;
}
/* Save current odr and enter PD mode */
ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1- >0x20
odr = ctrl1.odr;
ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0);
buff[1] = (uint8_t)(val / 256U);
buff[0] = (uint8_t)(val - (buff[1] * 256U));
ret += sths34pf80_func_cfg_write(add, STHS34PF80_PRESENCE_THS, &buff[0], 2);//STHS34PF80_PRESENCE_THS- >0x20U
ret += sths34pf80_algo_reset(add);
/* Set saved odr back */
ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);
return ret;
}
最开始读取CTRL1(20h)的数据,同时进行保存到odr变量中。
ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1- >0x20
odr = ctrl1.odr;
ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0)这行代码用于在设置存在阈值之前,通过调用 sths34pf80_tmos_odr_check_safe_set 函数来确保在设置新的参数之前传感器的状态是稳定且安全的。该函数如下所示。
/**
* @brief Enter to/Exit from power-down in a safe way
*
* @param ctx read / write interface definitions
* @param ctrl1 Value of CTRL1 register
* @param odr_new Value of new odr to be set
* @retval interface status (MANDATORY: return 0 - > no Error)
*
*/
static uint8_t sths34pf80_tmos_odr_check_safe_set(uint8_t add,sths34pf80_ctrl1_t ctrl1, uint8_t odr_new)
{
sths34pf80_func_status_t func_status;
sths34pf80_tmos_drdy_status_t status;
int32_t ret = 0;
if (odr_new > HAL_OK) {
/*
* Do a clean reset algo procedure everytime odr is changed to an
* operative state.
*/
ctrl1.odr = 0;
ret = sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1- >0x20
ret += sths34pf80_algo_reset(add);
} else {
/* if we need to go to power-down from an operative state
* perform the safe power-down.
*/
if ((uint8_t)ctrl1.odr > 0U) {
/* reset the DRDY bit */
ret = sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&func_status, 1);//STHS34PF80_FUNC_STATUS- >0x25
/* wait DRDY bit go to '1' */
do {
ret += sths34pf80_tmos_drdy_status_get(add, &status);
} while (status.drdy != 0U);
/* set ODR to 0 */
ctrl1.odr = 0;
ret += sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);
/* reset the DRDY bit */
ret += sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&func_status, 1);
}
}
ctrl1.odr = (odr_new & 0xfU);
ret += sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);
return ret;
}
其中下电模式在else中执行。
先是执行sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&func_status, 1),读取0x25主要功能是对STATUS (23h)的DRDY进行清0,之后执行如下代码。
/* wait DRDY bit go to '1' */
do {
ret += sths34pf80_tmos_drdy_status_get(add, &status);
} while (status.drdy != 0U);
sths34pf80_tmos_drdy_status_get代码主要是对STATUS (23h)的DRDY进行读取,当读取为0,跳出上面的循环。
/**
* @brief status of drdy.[get]
*
* @param ctx read / write interface definitions
* @param val status of drdy bit (TAMB, TOBJ, TAMB_SHOCK, TPRESENCE, TMOTION).
* @retval interface status (MANDATORY: return 0 - > no Error)
*
*/
uint8_t sths34pf80_tmos_drdy_status_get(uint8_t add, sths34pf80_tmos_drdy_status_t *val)
{
sths34pf80_status_t status;
int32_t ret;
ret = sths34pf80_read_reg(add, STHS34PF80_STATUS, (uint8_t *)&status, 1);//STHS34PF80_STATUS- >0x23
val- >drdy = status.drdy;
return ret;
}
之后重新回到sths34pf80_tmos_odr_check_safe_set函数中,执行如下操作。
主要功能就是将CTRL1(20h)里面的ODR数据清零,同时读取0x25,主要功能是对STATUS (23h)的DRDY进行清0
/* set ODR to 0 */
ctrl1.odr = 0;
ret += sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1- >0x20
/* reset the DRDY bit */
ret += sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&func_status, 1);//STHS34PF80_FUNC_STATUS- >0x25
然后执行如下代码将ODR数据重新写入CTRL1(20h)寄存器中。
ctrl1.odr = (odr_new & 0xfU);
ret += sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1- >0x20
紧接着返回sths34pf80_presence_threshold_set函数中,执行如下操作。
将传入的数据保存到buff数组中,然后执行sths34pf80_func_cfg_write将buff数据传入到PRESENCE_THS (20h - 21h)中。
buff[1] = (uint8_t)(val / 256U);
buff[0] = (uint8_t)(val - (buff[1] * 256U));
ret += sths34pf80_func_cfg_write(add, STHS34PF80_PRESENCE_THS, &buff[0], 2);//STHS34PF80_PRESENCE_THS- >0x20U
查看sths34pf80_func_cfg_write函数,如下所示。
/**
* @brief Function Configuration write
*
* @param ctx read / write interface definitions
* @param addr embedded register address
* @param data embedded register data
* @param len embedded register data len
* @retval interface status (MANDATORY: return 0 - > no Error)
*
*/
uint8_t sths34pf80_func_cfg_write(uint8_t add, uint8_t addr, uint8_t *data, uint8_t len)
{
sths34pf80_ctrl1_t ctrl1;
uint8_t odr;
sths34pf80_page_rw_t page_rw = {0};
int32_t ret;
uint8_t i;
/* Save current odr and enter PD mode */
ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1- >0x20
odr = ctrl1.odr;
ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0);
/* Enable access to embedded functions register */
ret += sths34pf80_mem_bank_set(add, STHS34PF80_EMBED_FUNC_MEM_BANK);
/* Enable write mode */
page_rw.func_cfg_write = 1;
ret += sths34pf80_write_reg(add, STHS34PF80_PAGE_RW, (uint8_t *)&page_rw, 1);
/* Select register address (it will autoincrement when writing) */
ret += sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, &addr, 1);
for (i = 0; i < len; i++)
{
/* Write data */
ret += sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, &data[i], 1);
}
/* Disable write mode */
page_rw.func_cfg_write = 0;
ret += sths34pf80_write_reg(add, STHS34PF80_PAGE_RW, (uint8_t *)&page_rw, 1);
/* Disable access to embedded functions register */
ret += sths34pf80_mem_bank_set(add, STHS34PF80_MAIN_MEM_BANK);
/* Set saved odr back */
ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);
return ret;
}
分析上面代码,其中sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1)为将ODR数据读取出来,接着执行sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0),该函数上面已经讲解,主要是进入一个掉电模式,确保在设置新的参数之前传感器的状态是稳定且安全的,以防止设置参数时出现异常情况。接着执行sths34pf80_mem_bank_set(add, STHS34PF80_EMBED_FUNC_MEM_BANK),该函数具体操作如下所示。
/**
* @brief Change memory bank.[set]
*
* @param ctx read / write interface definitions
* @param val MAIN_MEM_BANK, EMBED_FUNC_MEM_BANK, SENSOR_HUB_MEM_BANK, STRED_MEM_BANK,
* @retval interface status (MANDATORY: return 0 - > no Error)
*
*/
uint8_t sths34pf80_mem_bank_set(uint8_t add, sths34pf80_mem_bank_t val)
{
sths34pf80_ctrl2_t ctrl2;
int32_t ret;
ret = sths34pf80_read_reg(add, STHS34PF80_CTRL2, (uint8_t *)&ctrl2, 1);//STHS34PF80_CTRL2- >0x21
if (ret == HAL_OK)
{
ctrl2.func_cfg_access = ((uint8_t)val & 0x1U);
ret = sths34pf80_write_reg(add, STHS34PF80_CTRL2, (uint8_t *)&ctrl2, 1);//STHS34PF80_CTRL2- >0x21
}
return ret;
}
CTRL2 (21h)如下所示,对FUNC_CFG_ACCESS设置为1主要是开启访问内嵌函数寄存器。
继续返回sths34pf80_func_cfg_write函数,
之后执行如下函数,主要为向寄存器PAGE_RW (11h)的FUNC_CFG_WRITE标志位置为为1,启用嵌入式函数的写过程。
/* Enable write mode */
page_rw.func_cfg_write = 1;
ret += sths34pf80_write_reg(add, STHS34PF80_PAGE_RW, (uint8_t *)&page_rw, 1);
继续返回sths34pf80_func_cfg_write函数,然后执行如下函数,该函数为写入或者读取嵌入式函数的地址,具体要看PAGE_RW (11h)设置为读或者写,同时写入固定的data指令,当写完之后进入PAGE_RW (11h)关闭读或写操作。