基于STM32CUBEMX驱动TMOS模块STHS34PF80----4.中断获取信号
概述
STHS34PF80传感器项目种修改 Arduino 脚本,重新移植到STM32的MCU中。
该项目基于STHS34PF80 IR温度传感器,能够检测环境和物体温度,并且在最大4米范围内检测存在和运动。有一个Arduino脚本,显示如何为基本环境和物体温度测量配置传感器,并如何配置嵌入式功能算法,并使用它们检测存在和运动。脚本允许连续或一次性模式,允许更改低通滤波器和检测阈值以实现各种检测行为。脚本利用内嵌的中断引擎来检测温度数据的就绪状态,以及通知存在和运动事件。
总的来说,这是一个有趣的项目,使用STHS34PF80 IR温度传感器进行存在和运动检测,适用于各种应用,从环境和物体温度监测到人员和动物计数。该项目已经有一个功能强大的Arduino脚本作为起点,适合任何有兴趣使用这个传感器的人进一步开发和测试。
传感器的内置智能数字算法。该传感器具有三种不同的检测模式:存在检测、运动检测和环境温度冲击检测,通过配置嵌入式函数寄存器,来实现嵌入式函数的参数调整。
最近在弄ST和瑞萨RA的课程,需要样片的可以加群申请:6_15061293 。
视频教学
https://www.bilibili.com/video/BV1kF411C71S/
基于STM32CUBEMX驱动TMOS模块STHS34PF80(5)----配置嵌入式函数
样品申请
https://www.wjx.top/vm/OhcKxJk.aspx#
视频教程
参考Demo
参考Demo
hthttps://github.com/kriswiner/STHS34PF80/tree/main
内嵌函数地址
STHS34PF80传感器中的内嵌功能寄存器。这些寄存器可用于配置内嵌算法,用于补偿物体温度中的环境温度变化,以及内嵌的智能数字算法。
串口配置
查看原理图,PA9和PA10设置为开发板的串口。
配置串口。
IIC配置
在这个应用中,STS34PF80模块通过I2C(IIC)接口与主控器通信。具体来说,STS34PF80模块的I2C引脚连接到主控器的PB6(引脚B6)和PB7(引脚B7)两个IO口。
配置IIC为普通模式,速度为100k。
IO口设置
STS34PF80IO设置如下所示。
在IIC模式下CS需要给个高电平。
官方提供IIC接线如下所示。
需要把PA8配置为输出模式,默认高电平,配置PA7为输入模式。
串口重定向
打开魔术棒,勾选MicroLIB
在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
函数声明和串口重定向:
/* USER CODE BEGIN PFP */
int fputc(int ch, FILE *f){
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END PFP */
参考程序初始化
IIC写函数
STHS34PF80地址为101 1010(0x5A),如果是写操作,那么具体的地址为1011 0100(0xB4)。
/**
* @brief 读取数据
*
* @param add 模块地址
* @param reg 寄存器地址
* @param data buffer 缓冲区
* @param len 读取长度
* @retval ret 正常返回HAL_OK
*
*/
uint8_t sths34pf80_read_reg(uint8_t add,uint8_t reg, uint8_t * data, uint8_t len)
{
uint8_t ret;
ret=HAL_I2C_Mem_Read(&hi2c1 ,(add<<1)|1,reg,I2C_MEMADD_SIZE_8BIT,data,len,0xffff);
return ret;
}
IIC读函数
STHS34PF80地址为101 1010(0x5A),如果是读操作,那么具体的地址为1011 0101(0xB5)。
/**
* @brief 写入数据
*
* @param add 模块地址
* @param reg 寄存器地址
* @param data buffer 缓冲区
* @param len 写入长度
* @retval ret 正常返回HAL_OK
*
*/
uint8_t sths34pf80_write_reg(uint8_t add,uint8_t reg, uint8_t * data, uint8_t len)
{
uint8_t ret;
HAL_I2C_Mem_Write(&hi2c1 ,(add<<1)|0,reg,I2C_MEMADD_SIZE_8BIT,data,len,0xffff);
return ret;
}
获取ID
参考例程序中对应的获取ID驱动程序,如下所示。
获取ID可以查看0x0F,读出来的值应该为0xD3。
读取函数如下所示。
/**
* @brief 获取设备ID
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
uint8_t STHS34PF80_getChipID(uint8_t add)
{
uint8_t temp[1]={0};
sths34pf80_read_reg(add,STHS34PF80_WHO_AM_I,temp,1);
return temp[0];
}
驱动如下所示。
uint8_t STHS34PF80_ID = STHS34PF80_getChipID(STHS34PF80_ADDRESS); // Read CHIP_ID register for STHS34PF80
printf("STHS34PF80_ID=0x%x\n",STHS34PF80_ID);
设备的自动引导过程和关机模式配置
在设备上电后,它会执行一个2.5毫秒的引导过程,将校准系数从嵌入式闪存下载到内部寄存器,并加载AVG_TRIM(10h)、CTRL0(17h)和SENS_DATA(1Dh)寄存器的默认内容。在引导过程中,设备的寄存器是不可访问的。
引导完成后,设备会自动配置为关机模式。在上电后,通过将CTRL2(21h)寄存器的BOOT位设置为1,可以重新启动引导过程,以重新加载上述寄存器的默认值。无需对设备的电源线进行切换操作。
在重新引导过程中,设备的寄存器是不可访问的。重新引导完成后,设备会自动配置为先前的工作模式,并且BOOT位会自动清零为0。
修改后如下所示。
/**
* @brief 传感器重置
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
uint8_t STHS34PF80_reset(uint8_t add)
{
uint8_t temp = 0;
int32_t ret;
//STHS34PF80_CTRL2->0x21
ret=sths34pf80_read_reg(add,STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
if (ret == HAL_OK)
{
temp=temp | 0x80;
ret = sths34pf80_write_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);// set bit 7 to force device reset, wait 2.5 ms for reboot
}
HAL_Delay(3);
return ret;
}
省电模式
下面文本描述了关机模式的使用和功能。关机模式是一种休眠模式,用于将传感器设备置于休眠状态,从而节省功耗。在关机模式下,设备停止数据采集,并且大部分内部模块都被关闭,以最小化电流消耗。这使得传感器在供电的情况下能够实现最低的功耗水平。
尽管设备处于关机模式,但它仍保持 I²C / SPI 通信串口处于活动状态,以便能够与设备进行通信和配置设置。关机模式下,配置寄存器的内容被保留,而输出数据寄存器不会更新,这意味着在进入关机模式前,最后一次采样的数据将保留在内存中。
为了进入关机模式并避免在重新进入连续模式时读取错误的输出数据,文本提供了正确的步骤。然而,这些步骤在你的问题中并未提供,因此无法给出完整的步骤。
上面文档主要对0x25,0x23,0x20寄存器进行操作,其中读取0x25多次,主要功能是对STATUS (23h)的DRDY进行清0。
查看下面表格也可以得知,有多种操作可以对STATUS (23h)的DRDY 清零,其中读取FUNC_STATUS (25h)可以清零DRDY。
其中0x20是配置速率寄存器。
参考文档提供的关闭电源代码如下所示。
修改后如下。
void STHS34PF80_powerDown(uint8_t add)
{
uint8_t stat = 0;
//STHS34PF80_FUNC_STATUS->0x25
STHS34PF80_ReadByte(add,STHS34PF80_FUNC_STATUS); // This is done to reset the DRDY bit of the STATUS (23h) register to 0
//STHS34PF80_STATUS->0x23
stat=STHS34PF80_ReadByte(add,STHS34PF80_STATUS);
while( (stat & 0x04) )
{
stat=STHS34PF80_ReadByte(add,STHS34PF80_STATUS);
HAL_Delay(1);
} // wait for STATUS DR bit --> 0
uint8_t temp=0;
//STHS34PF80_CTRL1->0x20
temp=STHS34PF80_ReadByte(add,STHS34PF80_CTRL1);
STHS34PF80_WriteByte(add,STHS34PF80_CTRL1, temp & ~(0x07));// set bits 0 - 3 to 0 to power downt
//STHS34PF80_FUNC_STATUS->0x25
STHS34PF80_ReadByte(add,STHS34PF80_FUNC_STATUS); // reset DR bit of STATUS to
}
温度数据的灵敏度值
τ 表示光学系统在操作波长范围内的透射率(取值范围从0到1),SENSITIVITY DEFAULT 是对象温度数据的默认灵敏度值(通常约为2000 LSB/°C)。默认的灵敏度值是通过使用黑体覆盖传感器的全视场而无需光学元件(即,τ = 1)进行每个单元的校准获得的。
透射率的变化可能会影响传感器的读数,因此在有光学元件的情况下使用传感器时,可能需要根据透射率调整或考虑灵敏度。
可以读取SENS_DATA (1Dh)寄存器进行获取。
参考代码如下所示。
修改后如下。
/**
* @brief 获取设备灵敏度
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
int16_t STHS34PF80_readSenseData(uint8_t add)
{
uint8_t temp = 0;
int32_t ret;
//STHS34PF80_SENS_DATA->0x1D
ret = sths34pf80_read_reg(add, STHS34PF80_SENS_DATA, (uint8_t *)&temp, 1);
return (int16_t)((int16_t)temp << 8 | 0x00);
}
主程序打印保存的数值。
// 获取设备灵敏度
ObjSense = (STHS34PF80_readSenseData(STHS34PF80_ADDRESS) / 16) + 2048;
printf("Object Sense Data (LSB/oC) =%d \n",ObjSense)
设置低通滤波器
配置低通滤波器可以通过LPF1 (0Ch)和LPF2 (0Dh)进行配置。
STHS34PF80内置嵌入式算法,设备具有三种嵌入式的检测模式,包括存在检测、运动检测和环境温度冲击检测。
每种算法使用不同的低通滤波器 (LPF_P, LPF_M 和 LPF_A_T)。存在和运动检测算法还共同使用另一个低通滤波器 (LPF_P_M)。这些滤波器用于生成中间信号 (TPRESENCE, TMOTION 和 TAMB_SHOCK),可以用来微调算法本身。
下面分别是存在检测和运动检测的框图。
参考文档设置如下所示。
修改如下。
/**
* @brief 设置低通滤波器
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
uint8_t STHS34PF80_setLowpassFilters(uint8_t add,uint8_t lpf_P, uint8_t lpf_M, uint8_t lpf_PM, uint8_t lpf_Tshock)
{
int32_t ret;
uint8_t LPF1,LPF2;
LPF1=lpf_PM << 3 | lpf_M;
LPF2=lpf_P << 3 | lpf_Tshock;
//STHS34PF80_LPF1->0x0C
ret = sths34pf80_write_reg(add, STHS34PF80_LPF1, (uint8_t *)&LPF1, 1);
if(ret==HAL_OK)
{ //STHS34PF80_LPF2->0x0D
ret=sths34pf80_write_reg(add, STHS34PF80_LPF2, (uint8_t *)&LPF2, 1);
}
return ret;
}
温度测量滤波方式
首先需要设置AVG_TRIM (10h) 寄存器用于配置温度平均值滤波的参数,以控制环境温度和目标温度测量的平滑度和稳定性。在温度测量中,可能会受到噪声和干扰的影响,这可能导致短期内测量值的波动。通过应用平均值滤波,可以平滑这些波动,从而得到更加稳定的温度数据。AVG_TRIM 寄存器中的设置会决定平均值滤波的级别,从而影响滤波的时间常数以及平滑度。
这里默认参数如下
- 在AVG_TRIM(10h)寄存器中写入02h // AVG_T = 8,AVG_TMOS = 32
- 在CTRL1(20h)寄存器中写入07h // ODR = 15 Hz
AVG_T[1:0]: 这个设置位用于选择环境温度的平均值滤波样本数。
AVG_TMOS[2:0]: 这个设置位用于选择目标温度的平均值滤波样本数以及与之相关的噪声水平。
之后需要去设置温度范围,CTRL0 (17h)主要用于配置设备的增益,以适应不同的操作温度范围。具体的增益设置将决定设备可以工作的温度范围。
值000表示宽模式(wide mode)。
值111表示默认增益模式(default gain mode)。
查看下表得知,当房间和传感器温度差别不大时候,可以设置默认增益模式。
设置中断可以通过CTRL3 (22h)寄存器来配置。
这个寄存器为系统提供了有关设备当前状态的关键信息,可以用于驱动其他逻辑或触发相应的操作,如中断服务例程。例如,PRES_FLAG可用于确定是否有人进入了一个区域,MOT_FLAG可以用于检测人体是否运动,TAMB_SHOCK_FLAG可能用于环境监控系统以捕捉突然的温度变化。
通过查看FUNC_STATUS (25h)可以得知,PRES_FLAG为存在检测,MOT_FLAG为运动检测,TAMB_SHOCK_FLAG为环境温度冲击检测标志。
通过配置CTRL3 (22h)寄存器的IEN[1:0] 可以设置输出模式。
IEN[1:0]位在CTRL3寄存器中,它定义了应该将哪种信号路由到INT管脚(即中断输出):
00:INT管脚处于高阻态。
01:将DRDY(数据已准备好的信号)路由到INT管脚。
10:将INT_OR信号路由到INT管脚。
参考程序配置如下。
修改后如下所示。
/**
* @brief 设置温度测量滤波方式
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
uint8_t STHS34PF80_config(uint8_t add,uint8_t avgt, uint8_t avgtmos, uint8_t gain, bool functions)
{
int32_t ret;
uint8_t temp;
uint8_t AVG_TRIM;
AVG_TRIM = avgt << 4 | avgtmos;
//STHS34PF80_AVG_TRIM->0x10//设置滤波样本数
ret = sths34pf80_write_reg(add, STHS34PF80_AVG_TRIM, (uint8_t *)&AVG_TRIM, 1);
if(ret==HAL_OK)
{//STHS34PF80_CTRL0->0x17//设置温度增益
sths34pf80_read_reg(add, STHS34PF80_CTRL0, (uint8_t *)&temp, 1);
temp=temp | gain << 4;
ret = sths34pf80_write_reg(add, STHS34PF80_CTRL0, (uint8_t *)&temp, 1);
// Configure interrupt behavior
// select active HIGH (bit 7 == 0), push-pull (bit 6 == 0), pulsed mode (bit 2 == 0)
temp=0x01;//STHS34PF80_CTRL3->0x22
ret = sths34pf80_write_reg(add, STHS34PF80_CTRL3, (uint8_t *)&temp, 1);
temp=0x3A;//0011 1010
// if(functions) _i2c_bus->writeByte(STHS34PF80_ADDRESS, STHS34PF80_CTRL3, 0x32 ); // configure INT_OR for either Presence or Motion detection
if(functions)
ret = sths34pf80_write_reg(add, STHS34PF80_CTRL3, (uint8_t *)&temp, 1);
}
return ret;
}
写入嵌入式函数
嵌入式函数写操作如下所示。
案例实现如下。
CTRL2 (21h)如下所示,对FUNC_CFG_ACCESS设置为1主要是开启访问内嵌函数寄存器。
寄存器PAGE_RW (11h)的FUNC_CFG_WRITE标志位置为为1,启用嵌入式函数的写过程。
/************开启嵌入式函数读写************/
uint8_t temp ; //STHS34PF80_CTRL2->0x21
sths34pf80_read_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
temp = temp | 0x10;//STHS34PF80_CTRL2->0x21 //开启嵌入式函数访问
sths34pf80_write_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);//允许访问嵌入式函数寄存器
temp = 0x40; //STHS34PF80_FUNC_PAGE_RW->0x11 //开启嵌入式函数写操作
sths34pf80_write_reg(add, STHS34PF80_FUNC_PAGE_RW, (uint8_t *)&temp, 1); //允许写入嵌入函数寄存器
寄存器FUNC_CFG_ADDR (08h)为配置嵌入式函数的地址,FUNC_CFG_DATA (09h)为传入数据到嵌入式函数中。
这里传入的地址addr为STHS34PF80_PRESENCE_THS,这是个15位的寄存器,PRESENCE_THS 寄存器(地址范围为 0x20 到 0x21)主要用于存在检测算法的存在阈值设置。存在检测算法用于判断是否存在某种状态或条件,通常与传感器测量数据相关。
具体解释如下:
存在阈值(Presence Threshold): 这是一个用于存在检测算法的阈值。阈值定义了在测量数据中何时认为存在某种条件。在这里,阈值是一个 15 位的无符号整数(范围在 0 到 32767 之间)。
默认值: 预设的存在阈值默认值是 200(0x00C8)。
/************设置存在阈值************/
temp = STHS34PF80_PRESENCE_THS_L;//STHS34PF80_FUNC_CFG_ADDR->0x08 嵌入式地址PRESENCE_THS (20h - 21h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为PRESENCE_THS_L
temp =presence_ths ;//STHS34PF80_FUNC_CFG_DATA->0x09
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//写入低字节
temp = STHS34PF80_PRESENCE_THS_H;//STHS34PF80_FUNC_CFG_ADDR->0x08 嵌入式地址PRESENCE_THS (20h - 21h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为PRESENCE_THS_H
temp = presence_ths>>8;
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//写入高字节
MOTION_THS (22h - 23h) 这个寄存器用于设置运动检测算法的阈值。在实际应用中,你可能需要读取或设置这个寄存器,以调整或查看运动检测算法的阈值。如果值过高,可能会导致运动检测不灵敏;而值过低则可能会导致误报。这个值的范围从0到32767。默认值是200。
/************设置运动阈值************/
temp = STHS34PF80_MOTION_THS_L;//嵌入式地址MOTION_THS (22h - 23h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为MOTION_THS_L
temp = motion_ths ;
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//写入低字节
temp = STHS34PF80_MOTION_THS_H;//嵌入式地址MOTION_THS (22h - 23h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为MOTION_THS_H
temp = motion_ths >>8;
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//写入高字节
TAMB_SHOCK_THS (24h - 25h)这个寄存器是用来设置环境温度震荡检测算法的阈值。简而言之,当环境温度突然变化到某一程度时(超过这个设定的阈值),系统可能会认为发生了一个"温度震荡"事件。这是一个15位的无符号整数。这意味着它的范围是0到32767。
/************设置环境温度冲击阈值************/
temp = STHS34PF80_TAMB_SHOCK_THS_L;//嵌入式地址TAMB_SHOCK_THS (24h - 25h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为TAMB_SHOCK_THS_L
temp = tamb_shock_ths ;
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//写入低字节
temp = STHS34PF80_TAMB_SHOCK_THS_H;//嵌入式地址TAMB_SHOCK_THS (24h - 25h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为TAMB_SHOCK_THS_H
temp = tamb_shock_ths >>8;
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//写入高字节
HYST_PRESENCE (27h)这个寄存器是用来设置存在检测算法的滞后配置值。滞后(hysteresis)在很多传感器应用中是一个重要的概念,它可以帮助减少由于小的或暂时的输入变化而导致的输出频繁切换。简而言之,滞后会为传感器的读数提供一定的"容差",只有当输入值超过了这个容差范围时,输出才会发生变化。这是一个8位的无符号整数,所以它的范围是0到255,默认值是32。
/************设置存在滞后值************/
temp = STHS34PF80_HYST_PRESENCE;//嵌入式地址HYST_PRESENCE (27h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为HYST_PRESNCE
temp = presence_hyst;
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//写入1字节
HYST_MOTION (26h)这个寄存器用于设置运动检测算法的滞后配置值。这是一个8位的无符号整数,所以它的范围是0到255,默认值是32。
/************设置运动滞后值************/
temp = STHS34PF80_HYST_MOTION;//嵌入式地址HYST_MOTION (26h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为HYST_MOTION
temp = motion_hyst;
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//写入1字节
ALGO_CONFIG (28h)寄存器用于配置和调整算法的行为,包括中断脉冲模式、温度补偿和存在检测算法的绝对值选择。适当的配置可以使算法更适合特定应用的需求。
INT_PULSED: 当设置为1时,算法产生的标志会在INT引脚上脉冲输出(高电平持续ODR定义的时间)。默认值为0。
0: 锁存模式
1: 脉冲模式
COMP_TYPE: 启用内置线性算法,用于在物体温度中补偿环境温度变化。默认值为0。
0: 禁用
1: 启用
SEL_ABS: 在存在检测算法中选择绝对值。默认值为0。
0: 不应用绝对值
1: 应用绝对值
这里设置为脉冲输出模式,将算法中断设置为脉冲模式(位3 = 1)。
// set algorithm interrupt to pulsed mode (bit 3 = 1) or latch mode (bit 3 = 0)
/************设置脉冲模式************/
temp = STHS34PF80_ALGO_CONFIG;//嵌入式地址ALGO_CONFIG (28h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为ALGO_CONFIG
temp = 0x08;
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//写入0x08(位3)使能脉冲模式
最后关闭嵌入式写操作。
/************关闭嵌入式函数读写************/
temp = 0x00;//STHS34PF80_FUNC_PAGE_RW->0x11 //关闭嵌入式函数写
sths34pf80_write_reg(add, STHS34PF80_FUNC_PAGE_RW, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为STHS34PF80_FUNC_PAGE_RW
//STHS34PF80_CTRL2->0x21 //读取CTRL2 (21h)
sths34pf80_read_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
temp = temp & ~(0x10); //STHS34PF80_CTRL2->0x21 //清除FUNC_CFG_ACCESS
sths34pf80_write_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
读取嵌入式函数
嵌入式函数读操作如下所示。
案例实现如下。
CTRL2 (21h)如下所示,对FUNC_CFG_ACCESS设置为1主要是开启访问内嵌函数寄存器。
寄存器PAGE_RW (11h)的FUNC_CFG_READ标志位置为为1,启用嵌入式函数的读过程。
uint8_t rawData[2] = {0, 0}; // register data stored here
uint8_t temp ; //STHS34PF80_CTRL2->0x21
sths34pf80_read_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
temp = temp | 0x10;//STHS34PF80_CTRL2->0x21 //开启嵌入式函数访问
sths34pf80_write_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);//允许访问嵌入式函数寄存器
temp = 0x20; //STHS34PF80_FUNC_PAGE_RW->0x11 //开启嵌入式函数读操作
sths34pf80_write_reg(add, STHS34PF80_FUNC_PAGE_RW, (uint8_t *)&temp, 1); //允许写入嵌入函数寄存器
寄存器FUNC_CFG_ADDR (08h)为配置嵌入式函数的地址,FUNC_CFG_DATA (09h)为传入数据到嵌入式函数中。
这里传入的地址addr为STHS34PF80_PRESENCE_THS,这是个15位的寄存器,PRESENCE_THS 寄存器(地址范围为 0x20 到 0x21)主要用于存在检测算法的存在阈值设置。存在检测算法用于判断是否存在某种状态或条件,通常与传感器测量数据相关。
/************读取存在阈值************/
temp = STHS34PF80_PRESENCE_THS_L;//嵌入式地址PRESENCE_THS (20h - 21h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为PRESENCE_THS_L
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[0], 1);
temp = STHS34PF80_PRESENCE_THS_H;//嵌入式地址PRESENCE_THS (20h - 21h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为PRESENCE_THS_H
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[1], 1);
dest[0] = (uint16_t)(((uint16_t)rawData[1]) << 8 | rawData[0]);
MOTION_THS (22h - 23h) 这个寄存器用于设置运动检测算法的阈值。在实际应用中,你可能需要读取或设置这个寄存器,以调整或查看运动检测算法的阈值。如果值过高,可能会导致运动检测不灵敏;而值过低则可能会导致误报。这个值的范围从0到32767。默认值是200。
/************读取运动阈值************/
temp = STHS34PF80_MOTION_THS_L;//嵌入式地址MOTION_THS (22h - 23h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为MOTION_THS_L
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[0], 1);
temp = STHS34PF80_MOTION_THS_H;//嵌入式地址MOTION_THS (22h - 23h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为MOTION_THS_H
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[1], 1);
dest[1] = (uint16_t)(((uint16_t)rawData[1]) << 8 | rawData[0]);
TAMB_SHOCK_THS (24h - 25h)这个寄存器是用来设置环境温度震荡检测算法的阈值。简而言之,当环境温度突然变化到某一程度时(超过这个设定的阈值),系统可能会认为发生了一个"温度震荡"事件。这是一个15位的无符号整数。这意味着它的范围是0到32767。
/************读取环境温度冲击阈值************/
temp = STHS34PF80_TAMB_SHOCK_THS_L;//嵌入式地址TAMB_SHOCK_THS (24h - 25h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为TAMB_SHOCK_THS_L
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[0], 1);
temp = STHS34PF80_TAMB_SHOCK_THS_H; //嵌入式地址TAMB_SHOCK_THS (24h - 25h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为TAMB_SHOCK_THS_H
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[1], 1);
dest[2] = (uint16_t)(((uint16_t)rawData[1]) << 8 | rawData[0]);
HYST_MOTION (26h)这个寄存器用于设置运动检测算法的滞后配置值。这是一个8位的无符号整数,所以它的范围是0到255,默认值是32。
/************读取运动滞后值************/
temp = STHS34PF80_HYST_MOTION;//嵌入式地址HYST_MOTION (26h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为HYST_MOTION
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[0], 1);
HYST_PRESENCE (27h)这个寄存器是用来设置存在检测算法的滞后配置值。滞后(hysteresis)在很多传感器应用中是一个重要的概念,它可以帮助减少由于小的或暂时的输入变化而导致的输出频繁切换。简而言之,滞后会为传感器的读数提供一定的"容差",只有当输入值超过了这个容差范围时,输出才会发生变化。这是一个8位的无符号整数,所以它的范围是0到255,默认值是32。
/************读取存在滞后值************/
temp = STHS34PF80_HYST_PRESENCE;//嵌入式地址HYST_PRESENCE (27h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为HYST_PRESNCE
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[1], 1);
dest[3] = (uint16_t)(((uint16_t)rawData[1]) << 8 | rawData[0]);
ALGO_CONFIG (28h)寄存器用于配置和调整算法的行为,包括中断脉冲模式、温度补偿和存在检测算法的绝对值选择。适当的配置可以使算法更适合特定应用的需求。
INT_PULSED: 当设置为1时,算法产生的标志会在INT引脚上脉冲输出(高电平持续ODR定义的时间)。默认值为0。
0: 锁存模式
1: 脉冲模式
COMP_TYPE: 启用内置线性算法,用于在物体温度中补偿环境温度变化。默认值为0。
0: 禁用
1: 启用
SEL_ABS: 在存在检测算法中选择绝对值。默认值为0。
0: 不应用绝对值
1: 应用绝对值
这里设置为脉冲输出模式,将算法中断设置为脉冲模式(位3 = 1)。
// set algorithm interrupt to pulsed mode (bit 3 = 1) or latch mode (bit 3 = 0)
/************读取脉冲模式************/
temp = STHS34PF80_ALGO_CONFIG;//嵌入式地址ALGO_CONFIG (28h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为ALGO_CONFIG
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[0], 1);
HYST_TAMB_SHOCK (29h)寄存器用于设置环境温度突变检测算法的滞后配置值。滞后(hysteresis)在传感器应用中很常见,用于防止小范围、暂时的信号变化而导致的输出频繁切换。通过为传感器的读数提供一个“容差”,滞后确保只有当输入值超出这个容差范围时,输出才会发生变化。这是一个8位的无符号整数,意味着它的范围是0到255。
/************读取环境温度滞后值************/
temp = STHS34PF80_HYST_TAMB_SHOCK;//嵌入式地址HYST_TAMB_SHOCK (29h)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为HYST_TAMB_SHOCK
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&rawData[1], 1);
dest[4] = (uint16_t)(((uint16_t)rawData[1]) << 8 | rawData[0]);
最后关闭嵌入式写操作。
/************设置中断模式************/
temp = 0x00;//STHS34PF80_FUNC_PAGE_RW->0x11 //关闭嵌入式函数写
sths34pf80_write_reg(add, STHS34PF80_FUNC_PAGE_RW, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为STHS34PF80_FUNC_PAGE_RW
//STHS34PF80_CTRL2->0x21 //读取CTRL2 (21h)
sths34pf80_read_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
temp = temp & ~(0x10); //STHS34PF80_CTRL2->0x21 //清除BOOT和ONE_SHOT
sths34pf80_write_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
重置模块
当更改与算法相关的参数或滤波器的截止频率,或当启用/禁用嵌入式补偿算法时,需要按照上述步骤重置算法。这个过程涉及进入掉电模式、更改算法配置、启用和禁用嵌入式功能寄存器的访问和写操作,并在最后的步骤中设置所需的输出数据速率或触发单次采集。
/**
* @brief 重置STHS34PF80传感器内置的算法
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
void STHS34PF80_resetAlgo(uint8_t add)
{
uint8_t temp ; //STHS34PF80_CTRL2->0x21 //读取CTRL2 (21h)
sths34pf80_read_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
temp= temp | 0x10;//STHS34PF80_CTRL2->0x21 //开启嵌入式函数访问
sths34pf80_write_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);//允许访问嵌入式函数寄存器
temp = 0x40; //STHS34PF80_FUNC_PAGE_RW->0x11 //开启嵌入式函数写操作
sths34pf80_write_reg(add, STHS34PF80_FUNC_PAGE_RW, (uint8_t *)&temp, 1); //允许写入嵌入函数寄存器
temp = STHS34PF80_RESET_ALGO;//嵌入式地址STHS34PF80_RESET_ALGO (2Ah)
sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, (uint8_t *)&temp, 1); //设置嵌入式寄存器地址为STHS34PF80_RESET_ALGO
temp = 0x01;
sths34pf80_read_reg(add, STHS34PF80_FUNC_CFG_DATA, (uint8_t *)&temp, 1);//设置ALGO_ENABLE_RESET位
temp = 0x00;//STHS34PF80_FUNC_PAGE_RW->0x11 //关闭嵌入式函数写
sths34pf80_write_reg(add, STHS34PF80_FUNC_PAGE_RW, (uint8_t *)&temp, 1);//设置嵌入式寄存器地址为STHS34PF80_FUNC_PAGE_RW
//STHS34PF80_CTRL2->0x21 //读取CTRL2 (21h)
sths34pf80_read_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
temp = temp & ~(0x10); //STHS34PF80_CTRL2->0x21 //清除FUNC_CFG_ACCESS
sths34pf80_write_reg(add, STHS34PF80_CTRL2, (uint8_t *)&temp, 1);
}
最后第九步需要设置BDU速率。
/**
* @brief 关闭低功耗,进入正常模式,设置ODR
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
uint8_t STHS34PF80_powerUp(uint8_t add,uint8_t odr)
{
uint8_t temp = 0;
int32_t ret; //STHS34PF80_CTRL1->0x20
ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&temp, 1);
temp=temp | 0x10 | odr;// set bdu = 1 (bit 4 == 1) and odr
if(ret==HAL_OK)
ret = sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&temp, 1);
return ret;
}
清零DRDY
可以通过读取0x25,主要功能是对STATUS (23h)的DRDY进行清0。
查看下面表格也可以得知,有多种操作可以对STATUS (23h)的DRDY 清零。
/**
* @brief 清零DRDY
*
* @param add 设备地址
* @param val 设备ID.
* @retval ret 正常返回HAL_OK
*
*/
uint8_t STHS34PF80_getFuncStatus(uint8_t add)
{
uint8_t temp = 0;//STHS34PF80_FUNC_STATUS->0x25
sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&temp, 1);
return temp;
}