基于STM32CUBEMX驱动TMOS模块STHS34PF80----4.中断获取信号
- 概述
- 样品申请
- 视频教程
- 参考Demo
- 参考程序中断
- 中断生成
- 设置中断
- 开启存在检测中断输出
- 配置中断管脚
- 主程序
- 测试结果
概述
HS34PF80的数据准备信号提供了一种机制,允许设备在新的测量数据可读取时通知系统,并触发同步操作,通过正确配置相关寄存器,可以确保系统及时捕获和处理来自设备的新数据,从而提高整体性能和响应能力。
检测人体的存在和动作,并通过特定的通信接口发送检测结果。
最近在弄ST和瑞萨RA的课程,需要样片的可以加群申请:6_15061293 。
样品申请
https://www.wjx.top/vm/OhcKxJk.aspx#
视频教程
https://www.bilibili.com/video/BV1NF41117S6/
基于STM32CUBEMX驱动TMOS模块STHS34PF80(4)----中断获取信号
参考Demo
https://github.com/STMicroelectronics/STMems_Standard_C_drivers/blob/master/sths34pf80_STdC/examples/sths34pf80_tmos_data_polling.c
参考程序中断
中断生成
STHS34PF80具有一个可配置的内置中断生成块,允许基于温度数据样本和嵌入式智能数字算法的输出标志生成中断事件。
STHS34PF80提供了一个专门的INT引脚,用于通知数据是否准备好。您可以通过配置相关寄存器,将数据准备好的信号(DRDY信号)路由到这个INT引脚。当新的测量数据可读取时,这个引脚会被触发,从而允许系统知道数据已经准备好并可供进一步的处理和读取。
设置中断
设置中断可以通过CTRL3 (22h)寄存器来配置。
这个寄存器为系统提供了有关设备当前状态的关键信息,可以用于驱动其他逻辑或触发相应的操作,如中断服务例程。例如,PRES_FLAG可用于确定是否有人进入了一个区域,MOT_FLAG可以用于检测人体是否运动,TAMB_SHOCK_FLAG可能用于环境监控系统以捕捉突然的温度变化。
通过查看FUNC_STATUS (25h)可以得知,PRES_FLAG为存在检测,MOT_FLAG为运动检测,TAMB_SHOCK_FLAG为环境温度冲击检测标志。
开启存在检测中断输出
sths34pf80_tmos_int_or_set 的主要目的是配置STHS34PF80设备的中断输出。它是用于设置和管理中断标志,其中STHS34PF80_TMOS_INT_PRESENCE为0x4,就是使能INT_MSK2为1,开启PRES_FLAG存在检测。
/* Set interrupt */
sths34pf80_tmos_int_or_set(STHS34PF80_ADDRESS, STHS34PF80_TMOS_INT_PRESENCE);
具体操作函数如下所示。
/**
* @brief Selects interrupts output.[set]
*
* @param ctx read / write interface definitions
* @param val TMOS_INT_NONE, TMOS_INT_TSHOCK, TMOS_INT_MOTION, TMOS_INT_TSHOCK_MOTION, TMOS_INT_PRESENCE, TMOS_INT_TSHOCK_PRESENCE, TMOS_INT_MOTION_PRESENCE, TMOS_INT_ALL,
* @retval interface status (MANDATORY: return 0 -> no Error)
*
*/
uint8_t sths34pf80_tmos_int_or_set(uint8_t add, sths34pf80_tmos_int_or_t val)
{
sths34pf80_ctrl3_t ctrl3;
int32_t ret;
ret = sths34pf80_read_reg(add, STHS34PF80_CTRL3, (uint8_t *)&ctrl3, 1);
if (ret == HAL_OK)
{
ctrl3.int_msk = ((uint8_t)val & 0x7U);
ret = sths34pf80_write_reg(add, STHS34PF80_CTRL3, (uint8_t *)&ctrl3, 1);
}
return ret;
}
配置中断管脚
通过配置CTRL3 (22h)寄存器的IEN[1:0] 可以设置输出模式。
IEN[1:0]位在CTRL3寄存器中,它定义了应该将哪种信号路由到INT管脚(即中断输出):
00:INT管脚处于高阻态。
01:将DRDY(数据已准备好的信号)路由到INT管脚。
10:将INT_OR信号路由到INT管脚。
这里通过将CTRL3(22h)寄存器的IEN[1:0]位范围设置为10,可以将STATUS(23h)寄存器的DRDY位的值驱动到INT引脚,操作如下所示。
sths34pf80_tmos_route_int_set(STHS34PF80_ADDRESS, STHS34PF80_TMOS_INT_OR);
具体的操作函数如下所示。这个函数基本上对应之前提到的IEN[1:0]位的功能,它允许用户选择要路由到中断输出管脚的特定中断信号。
/**
* @defgroup Interrupt PINs
* @brief Interrupt PINs
* @{/
*
*/
/**
* @brief Selects interrupts to be routed.[set]
*
* @param ctx read / write interface definitions
* @param val TMOS_INT_HIZ, TMOS_INT_DRDY, TMOS_INT_OR,
* @retval interface status (MANDATORY: return 0 -> no Error)
*
*/
uint8_t sths34pf80_tmos_route_int_set(uint8_t add, sths34pf80_tmos_route_int_t val)
{
sths34pf80_ctrl3_t ctrl3;
int32_t ret;
ret = sths34pf80_read_reg(add, STHS34PF80_CTRL3, (uint8_t *)&ctrl3, 1);
if (ret == HAL_OK)
{
ctrl3.ien = ((uint8_t)val & 0x3U);
if (val == STHS34PF80_TMOS_INT_OR) {
ctrl3.int_latched = 0; /* guarantee that latched is zero in INT_OR case */
}
ret = sths34pf80_write_reg(add, STHS34PF80_CTRL3, (uint8_t *)&ctrl3, 1);
}
return ret;
}
主程序
初始化如下。
/* USER CODE BEGIN 2 */
sths34pf80_lpf_bandwidth_t lpf_m, lpf_p, lpf_p_m, lpf_a_t;
sths34pf80_tmos_drdy_status_t status;
sths34pf80_tmos_func_status_t func_status;
HAL_Delay(200);
printf("123");
uint8_t STHS34PF80_ID =STHS34PF80_getChipID(STHS34PF80_ADDRESS);
printf("STHS34PF80_ID=0x%x\n",STHS34PF80_ID);
if (STHS34PF80_ID != 0xD3)
while(1);
/* Set averages (AVG_TAMB = 8, AVG_TMOS = 32) */
sths34pf80_avg_tobject_num_set(STHS34PF80_ADDRESS, STHS34PF80_AVG_TMOS_32);
sths34pf80_avg_tambient_num_set(STHS34PF80_ADDRESS, STHS34PF80_AVG_T_8);
/* read filters */
sths34pf80_lpf_m_bandwidth_get(STHS34PF80_ADDRESS, &lpf_m);
sths34pf80_lpf_p_bandwidth_get(STHS34PF80_ADDRESS, &lpf_p);
sths34pf80_lpf_p_m_bandwidth_get(STHS34PF80_ADDRESS, &lpf_p_m);
sths34pf80_lpf_a_t_bandwidth_get(STHS34PF80_ADDRESS, &lpf_a_t);
printf("lpf_m: %02d, lpf_p: %02d, lpf_p_m: %02d, lpf_a_t: %02d\r\n", lpf_m, lpf_p, lpf_p_m, lpf_a_t);
/* Set BDU */
sths34pf80_block_data_update_set(STHS34PF80_ADDRESS, 1);
sths34pf80_tmos_route_int_set(STHS34PF80_ADDRESS, STHS34PF80_TMOS_INT_OR);
sths34pf80_presence_threshold_set(STHS34PF80_ADDRESS, 20); //设置存在阈值。
sths34pf80_presence_hysteresis_set(STHS34PF80_ADDRESS, 2);//“存在滞后”(Presence Hysteresis)的函数
sths34pf80_motion_threshold_set(STHS34PF80_ADDRESS, 30);//设置动作阈值
sths34pf80_motion_hysteresis_set(STHS34PF80_ADDRESS, 3); 动作滞后”(Motion Hysteresis)的函数
/* Set interrupt */
sths34pf80_tmos_int_or_set(STHS34PF80_ADDRESS, STHS34PF80_TMOS_INT_PRESENCE);
sths34pf80_tmos_route_int_set(STHS34PF80_ADDRESS, STHS34PF80_TMOS_INT_OR);
/* Set ODR */
sths34pf80_tmos_odr_set(STHS34PF80_ADDRESS, STHS34PF80_TMOS_ODR_AT_30Hz);
int32_t cnt = 0;
/* USER CODE END 2 */
main函数如下所示。
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// sths34pf80_tmos_drdy_status_get(STHS34PF80_ADDRESS, &status);
// if (status.drdy)
// {
// sths34pf80_tmos_func_status_get(STHS34PF80_ADDRESS, &func_status);
// printf("-->环境温度冲击检测标志位 %d - 存在检测标志位 %d - 运动检测标志位 %d\r\n",func_status.tamb_shock_flag, func_status.pres_flag, func_status.mot_flag);
// }
printf("PA7=%d",HAL_GPIO_ReadPin ( GPIOA, GPIO_PIN_7));
sths34pf80_tmos_func_status_t func_status;
uint8_t motion;
uint8_t presence;
/* handle event in a "thread" alike code */
if(HAL_GPIO_ReadPin ( GPIOA, GPIO_PIN_7))
{
motion = 0;
presence = 0;
do {
sths34pf80_tmos_func_status_get(STHS34PF80_ADDRESS, &func_status);
if (func_status.pres_flag != presence)
{
presence = func_status.pres_flag;
if (presence) {
printf("Start of Presence\r\n");
} else {
printf("End of Presence\r\n");
}
}
if (func_status.mot_flag != motion)
{
motion = func_status.mot_flag;
if (motion) {
printf("Motion Detected!\r\n");
}
}
} while (func_status.pres_flag);
}
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
测试结果
在未有人的情况下。
在人体纯在情况下。