你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32CUBEMX驱动TMOS模块STHS34PF80修改检测阈值(3)

[复制链接]
攻城狮Melo 发布时间:2023-11-16 17:09
套件概述
, Z# I2 G& @3 e. p3 \3 E用于配置和设置 STHS34PF80 传感器的一些参数,以便进行存在检测和运动检测。# ^! D; R& r- v; z# H, n7 i

+ V5 `9 U4 Q, s
微信图片_20231116161600.png
0 @& G" n5 R3 i  G# k6 d
% T4 E- C! B: x: D3 V1 R. J参考程序初始化
0 ^8 L6 L" V5 a5 I6 Z9 u9 d相对于驱动人体检测demo,新的案例设置了传感器的存在和运动相关的阈值、滞后和中断配置,以实现存在检测和运动检测的功能,并在相关事件发生时触发中断。
& Y9 O/ p% w* m( u/ d" d. I! K/ i$ w0 t- Q) E: j
1.png . L( }0 Y1 S) k# `
& R# O6 E" w6 o5 J0 \8 a" U
省电模式9 f1 j. o  M4 ^0 a. A' ^2 ^
下面文本描述了关机模式的使用和功能。关机模式是一种休眠模式,用于将传感器设备置于休眠状态,从而节省功耗。在关机模式下,设备停止数据采集,并且大部分内部模块都被关闭,以最小化电流消耗。这使得传感器在供电的情况下能够实现最低的功耗水平。! A) K5 ?: U& B% y" ~3 u- `

/ P! _' Q7 {7 G/ B% R尽管设备处于关机模式,但它仍保持 I²C / SPI 通信串口处于活动状态,以便能够与设备进行通信和配置设置。关机模式下,配置寄存器的内容被保留,而输出数据寄存器不会更新,这意味着在进入关机模式前,最后一次采样的数据将保留在内存中。
- m. Z( u' x+ n  l# Q
9 C  B, z: a3 h' J8 K" r" N
为了进入关机模式并避免在重新进入连续模式时读取错误的输出数据,文本提供了正确的步骤。然而,这些步骤在你的问题中并未提供,因此无法给出完整的步骤。
( h* I: s# y1 J$ I' y' @- L- S4 P' ^! v* w# |
2.png + g7 g0 r" }+ s! N8 `' {

9 F7 g& Z: @3 _9 d2 O8 `% y. k上面文档主要对0x25,0x23,0x20寄存器进行操作,其中读取0x25多次,主要功能是对STATUS (23h)的DRDY进行清0。8 E+ x+ ?! }# u& F# I3 f

3 |* t! O  e8 n* s查看下面表格也可以得知,有多种操作可以对STATUS (23h)的DRDY 清零。
. I! l7 L* p4 J9 }& x- w2 J+ r% f) l: `
3.png ! O, W) K- x! r7 i
5 Q% P) {9 w; @$ b3 G" V" Z
其中0x20是配置速率寄存器。% d' z1 U6 V9 m6 ]: {, Z
2 E0 L2 j7 A/ s) J3 H$ }) x* g
4.png ( q( z5 F3 w& [- K

4 g2 w0 f; I, t. \9 G) U设置存在阈值 9 V- P. b( g! H0 B5 l9 {! {
存在检测如下所示。, x& ^/ ?% |( x9 z9 U% F$ G* m) G4 X

) v, S% d% L, t 5.png ) h, f. P2 C2 j& S" ]  a
3 a9 L; K: x- x0 m. a$ \% @
以设置存在阈值为例,探索设置的步骤。( R5 f. \0 ^7 M0 f. ~$ q

, {. }" V2 C, h
6.png . X, m, J' T" Y& F8 C

. j0 J9 ?- o7 W1 z. r  }这里使用的函数为 sths34pf80_presence_threshold_set(STHS34PF80_ADDRESS, 200)。
  1. /*** b  M6 d6 W0 _  h
  2.   * @brief  Presence threshold.[set]3 R3 J6 Y1 o& |% y& ~
  3.   *
    ' z" w2 Z6 F6 W
  4.   * @param  ctx      read / write interface definitions. J) \# P7 `, I0 o3 I5 q9 ?
  5.   * @param  val      presence threshold level: ~6 ^; \) A6 r3 a9 Q% K
  6.   * @retval          interface status (MANDATORY: return 0 -> no Error)1 P9 y# n3 B0 K$ d
  7.   *
    ! p9 r- V' W; d) @+ T& b
  8.   */
    1 }# i# |3 D, U3 L
  9. uint8_t sths34pf80_presence_threshold_set(uint8_t add, uint16_t val)
    ! c1 R' J2 ?2 z# Z: {
  10. {+ t3 W& y% r: ~( R, `- p# d& J
  11.   sths34pf80_ctrl1_t ctrl1;9 O7 K4 o( N6 v! r4 B: M
  12.   uint8_t odr;8 x0 g% ]6 Z- B' O, ~
  13.   uint8_t buff[2];
    . |; Y  m" ^7 |! P* P+ ^5 W
  14.   int32_t ret;" |  k, m- k: M, s1 L0 A
  15. ) s! G: J2 H+ G, B( z" e
  16.   if ((val & 0x8000U) != 0x0U) {4 q5 ]( g" u- G7 _( Y
  17.     /* threshold values are on 15 bits */
    % J% B& E0 e; {! \
  18.     return -1;
      L) E. o. L! s+ S
  19.   }
    2 y- m; F: Y" k+ l) M
  20. " D4 G, d8 w$ n; y* `( u
  21.   /* Save current odr and enter PD mode */! T/ X8 e7 X; s9 ]( l
  22.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1->0x20
    , ^5 C& G9 a7 y* [/ B4 `
  23.   odr = ctrl1.odr;4 v7 o8 |, X- o8 W: |
  24.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0);
    * O$ S0 m* H# c: G) j

  25. 4 `2 F7 l+ k6 _
  26.   buff[1] = (uint8_t)(val / 256U);/ M, b5 S, ?- C
  27.   buff[0] = (uint8_t)(val - (buff[1] * 256U));' \, E6 x5 @& T! K6 M
  28.   ret += sths34pf80_func_cfg_write(add, STHS34PF80_PRESENCE_THS, &buff[0], 2);//STHS34PF80_PRESENCE_THS->0x20U
    5 u# _- H! J6 T, V9 x
  29. 6 g7 q3 |' ~; C$ o6 Z8 t
  30.   ret += sths34pf80_algo_reset(add);( d5 K% x& r, ?: N: n2 S% |) }8 |
  31. 0 H- W* H7 j; `# Y' J1 q
  32.   /* Set saved odr back */- B3 i: w6 }5 _+ Y8 t) n
  33.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);
    $ ~" j  E5 z7 u* ^( O$ F

  34. / U7 d1 X' W7 X# r' s3 @9 o
  35.   return ret;
    7 @3 b7 o6 q/ X1 Y9 L, J
  36. }
    2 o5 k; A+ p9 |: B
复制代码
( Z5 P* Z- Q" o8 |& c
最开始读取CTRL1(20h)的数据,同时进行保存到odr变量中。
  1.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1->0x20
    & C* L2 i$ y( {! L7 q
  2.   odr = ctrl1.odr;
    ; R+ ]* @6 R  L$ N% L4 \3 L
复制代码
% p2 l5 h% j' m7 j
ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0)这行代码用于在设置存在阈值之前,通过调用 sths34pf80_tmos_odr_check_safe_set 函数来确保在设置新的参数之前传感器的状态是稳定且安全的。该函数如下所示。
  1. /**
    ' }6 h: T1 T4 x  h8 M
  2.   * @brief  Enter to/Exit from power-down in a safe way
    5 r) n# k* v; h. n# J* Z* q# H3 I6 @
  3.   *; M9 d$ k& j! s4 S/ I; d  c% D: y& ]  ^
  4.   * @param  ctx      read / write interface definitions5 Y( A7 v/ h4 @
  5.   * @param  ctrl1    Value of CTRL1 register
    3 s5 c7 ^# q  ?7 |' k/ x
  6.   * @param  odr_new  Value of new odr to be set
    8 y: J5 x( C9 U1 A- C" |" g
  7.   * @retval          interface status (MANDATORY: return 0 -> no Error)
    ; A7 v& j$ ]  P
  8.   *
    ) l7 l& _7 j5 a& r
  9.   */
    : F* H0 p: y; F: A9 c" X, e
  10. static uint8_t sths34pf80_tmos_odr_check_safe_set(uint8_t add,sths34pf80_ctrl1_t ctrl1, uint8_t odr_new)/ K' v1 S: z; E4 D; \. F
  11. {
    1 R+ T2 d2 l! |- z* q7 o5 Y) x
  12.   sths34pf80_func_status_t func_status;
    7 P/ }& \/ a: y' L
  13.   sths34pf80_tmos_drdy_status_t status;. f& \8 x- {0 Y2 J% g
  14.   int32_t ret = 0;2 G  i: o- o, r: E( n" _

  15. ; R' G9 D1 I7 Q
  16.   if (odr_new > HAL_OK) {1 ~" f# p0 K3 G2 Y
  17.     /*( m3 K1 Q- l! v* B1 {
  18.      * Do a clean reset algo procedure everytime odr is changed to an
    . Y  B( ?5 U5 x# X
  19.      * operative state.
    2 @' k/ a; L1 `) T/ \; e$ x
  20.      */
    6 n4 r! e% N2 T6 U: `9 D  R9 P, l2 |
  21.     ctrl1.odr = 0;3 ]8 z' A# P4 S0 \& E  c
  22.     ret = sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1->0x20
    6 z; F" g* v1 L6 X. C: z4 {

  23. * {, k& L- ?1 E0 m
  24.     ret += sths34pf80_algo_reset(add);
    ) `. `& _5 D: g
  25.   } else {3 s4 `, M, X. ^+ }/ a& Y
  26.     /* if we need to go to power-down from an operative state! @& T" a0 Z7 l6 w
  27.      * perform the safe power-down.
    ! V  _7 Z4 o% U$ Q' ]  r
  28.      */
    - l7 g* t  a" y
  29.     if ((uint8_t)ctrl1.odr > 0U) {/ r7 v$ |" b- j0 T, J& N' o
  30.       /* reset the DRDY bit */
    . ]6 Z7 ^4 [( W$ O! B9 }7 E& e
  31.       ret = sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&func_status, 1);//STHS34PF80_FUNC_STATUS->0x253 T1 E* d  y: d" P' G! L( h
  32. # I& z6 O) z" `  _. Z" X7 Q
  33.       /* wait DRDY bit go to '1' */
    8 A( {7 e: L  I2 Z+ U
  34.       do {
      ?# Q) x1 i1 R' _( L
  35.         ret += sths34pf80_tmos_drdy_status_get(add, &status);
    , k& {& Z$ x0 S4 ?6 J

  36. 5 P: i: L$ N. Y6 g* ^7 n' L$ h
  37.       } while (status.drdy != 0U);$ \9 y- r8 L) n

  38. " o4 X+ A" k. I4 S6 O2 Q
  39.       /* set ODR to 0 */
    $ K5 g) ^+ s) j4 ?6 }+ }! y7 k
  40.       ctrl1.odr = 0;
    ; d: ?" c4 o. Y# W3 e. V
  41.       ret += sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);
    ( o* B. c$ M! G+ b

  42. " T% h9 j5 z. ]/ e6 V
  43.       /* reset the DRDY bit */& z7 ~  d6 ?, s4 L9 G+ q
  44.       ret += sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&func_status, 1);$ P& `* w+ U; [3 z! K
  45.     }
    ' ]0 }; h2 {8 e% z
  46.   }; t7 P, }3 t  _) B

  47. # N' X6 |( u/ O# ?9 h
  48.   ctrl1.odr = (odr_new & 0xfU);* M+ R* w4 C3 v! w/ X/ F+ y
  49.   ret += sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);
    2 |; n* Y  `& c! m. E: {- W& H5 I

  50. ) s: U+ h. v7 r- _
  51.   return ret;/ R+ C& t2 U- q( b
  52. }
复制代码
' L$ i6 g+ ?; T9 t
其中下电模式在else中执行。
9 k. \5 l' n, {; g3 N先是执行sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&func_status, 1),读取0x25主要功能是对STATUS (23h)的DRDY进行清0,之后执行如下代码。
  1.       /* wait DRDY bit go to '1' */
    1 N+ s" i3 f  N3 G
  2.       do {; ~- G$ i. R( y0 Z0 F/ z
  3.         ret += sths34pf80_tmos_drdy_status_get(add, &status);
    / k% t' _* a# |2 @. k& Z
  4. ) {% d% m: t! t& }! [
  5.       } while (status.drdy != 0U);2 b. m- L0 r* M  N
复制代码

# j, C2 K7 b5 R& D- Psths34pf80_tmos_drdy_status_get代码主要是对STATUS (23h)的DRDY进行读取,当读取为0,跳出上面的循环。
  1. /**/ o; z4 h9 @, Y
  2.   * @brief  status of drdy.[get]
    0 C8 k) L3 |7 |7 w; ^5 v% g) Z% Z
  3.   *
    2 t- X; o3 l/ j& z
  4.   * @param  ctx      read / write interface definitions) G  j: g( ?$ J: A* m+ f
  5.   * @param  val      status of drdy bit (TAMB, TOBJ, TAMB_SHOCK, TPRESENCE, TMOTION).& |3 u. F/ m8 U9 K* P5 z( }
  6.   * @retval          interface status (MANDATORY: return 0 -> no Error)
    $ _* M8 J" L) [
  7.   *
    0 r* y4 q/ Y  K
  8.   */- n6 P( H& |: Y1 y/ A
  9. uint8_t sths34pf80_tmos_drdy_status_get(uint8_t add, sths34pf80_tmos_drdy_status_t *val)# T$ ^7 s, K8 F
  10. {- T. e2 \2 }) y8 P2 E$ u
  11.   sths34pf80_status_t status;
    8 z& p2 `, m4 P9 R) H7 W/ ~( y
  12.   int32_t ret;$ }" V3 l! O0 w; r* V5 Z% {0 p1 ?5 I

  13. 0 a. [! S* K# V3 [6 a% \5 u
  14.   ret = sths34pf80_read_reg(add, STHS34PF80_STATUS, (uint8_t *)&status, 1);//STHS34PF80_STATUS->0x23
    . r4 X; P9 b4 Z8 `
  15. ! _# s. B0 B; h4 L; ?% Y2 r& s6 c
  16.   val->drdy = status.drdy;# m/ V: e, n" x% l$ ]* I4 I' |

  17. ! ]; Z# W5 e! g* r+ C. y! T3 ^, Y2 N
  18.   return ret;
    " i0 N, K. v- d) D; s& U& V+ f8 N
  19. }& h& }6 y) D' n; L( T* m
复制代码

+ g5 V5 p" A: _之后重新回到sths34pf80_tmos_odr_check_safe_set函数中,执行如下操作。- j6 y& e" D2 B0 L7 s% h
主要功能就是将CTRL1(20h)里面的ODR数据清零,同时读取0x25,主要功能是对STATUS (23h)的DRDY进行清0
  1.       /* set ODR to 0 */! n8 Q/ V9 C' \+ q
  2.       ctrl1.odr = 0;
    $ M+ P% ~  a* w( d" [
  3.       ret += sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1->0x203 P2 E; A. k0 ]/ Y. o  Y& E

  4. ' T* I: v/ p( f# |. n6 _3 e2 C. R
  5.       /* reset the DRDY bit */
    9 d. ?: B3 a' y: s9 p! o9 h& o
  6.       ret += sths34pf80_read_reg(add, STHS34PF80_FUNC_STATUS, (uint8_t *)&func_status, 1);//STHS34PF80_FUNC_STATUS->0x25
    0 R  i, h5 y. R, I: A. m/ R
复制代码

8 O3 b. y6 b9 r; I) K' `0 z然后执行如下代码将ODR数据重新写入CTRL1(20h)寄存器中。
  1.   ctrl1.odr = (odr_new & 0xfU);
    : Y9 I5 B0 n5 D& c; j
  2.   ret += sths34pf80_write_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1->0x208 Q. B. w# G* ?6 k* y+ x$ I
复制代码

! u8 B" n9 W/ |& v0 A. Q" V3 J紧接着返回sths34pf80_presence_threshold_set函数中,执行如下操作。' a; u0 T/ R* T, E- ^
将传入的数据保存到buff数组中,然后执行sths34pf80_func_cfg_write将buff数据传入到PRESENCE_THS (20h - 21h)中。1 E; R% E0 l, ?6 y
  1. buff[1] = (uint8_t)(val / 256U);# J! G* `; G' s: w; E6 i- M
  2.   buff[0] = (uint8_t)(val - (buff[1] * 256U));
    / T) e5 p% P0 \3 o5 u
  3.   ret += sths34pf80_func_cfg_write(add, STHS34PF80_PRESENCE_THS, &buff[0], 2);//STHS34PF80_PRESENCE_THS->0x20U
复制代码
. l) _) r7 u  Z. {7 Q0 ~: u5 v+ `
查看sths34pf80_func_cfg_write函数,如下所示。
  1. /**& P2 e1 z3 W) [9 E) M' \  U8 W" M
  2.   * @brief  Function Configuration write  Z" g$ o$ U  ^0 e4 @2 U
  3.   *
    5 R4 s: ?* M9 ~( N
  4.   * @param  ctx      read / write interface definitions
    + T% u! Z6 T9 ]
  5.   * @param  addr     embedded register address
    ' S* Q, Z$ }7 X" H
  6.   * @param  data     embedded register data3 {9 \. Y6 L: E
  7.   * @param  len      embedded register data len
    9 D" m% m( b1 \9 p2 K0 u5 d* z
  8.   * @retval          interface status (MANDATORY: return 0 -> no Error)- C. y+ l2 F( G9 k. W
  9.   *
    7 E. b4 \8 P" ~, `; X
  10.   */
    1 b5 {$ F) Z# x5 M; d
  11. uint8_t sths34pf80_func_cfg_write(uint8_t add, uint8_t addr, uint8_t *data, uint8_t len), z! |  G* K( ^" g& u4 M9 h9 R
  12. {" ]- q4 S& ?; c/ q% B9 o
  13.   sths34pf80_ctrl1_t ctrl1;
    ! p, _2 L+ I7 n2 n/ w
  14.   uint8_t odr;
    6 E# s$ s9 C' L$ r6 j* O
  15.   sths34pf80_page_rw_t page_rw = {0};
    ) @3 j/ ?4 U- f
  16.   int32_t ret;; X  \$ _* |3 B$ g8 p
  17.   uint8_t i;
    0 j! u. k" `' p0 }
  18.   c, R" Y4 {# _" e( k/ [
  19.   /* Save current odr and enter PD mode */
    ( D% S& x  z( T( L+ }( H
  20.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1->0x202 r# C- \5 b9 o8 S7 q; d
  21.   odr = ctrl1.odr;
    3 h' p3 l$ P" b" k: i$ s
  22.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0);' K0 A( Z  p' e3 h' r9 t3 D
  23. 6 x7 _" y9 o+ c: N6 H1 G
  24.   /* Enable access to embedded functions register */
    % V- l0 ?7 F: r" y5 z+ L
  25.   ret += sths34pf80_mem_bank_set(add, STHS34PF80_EMBED_FUNC_MEM_BANK);
    ; c  v' N1 T; ~8 v  \4 ~
  26. 4 U+ {% K& r7 F  W
  27.   /* Enable write mode */
    0 l! k- A+ U& d# h  K: R5 g1 H
  28.   page_rw.func_cfg_write = 1;
      D9 k7 T2 ?* t8 m; j* r
  29.   ret += sths34pf80_write_reg(add, STHS34PF80_PAGE_RW, (uint8_t *)&page_rw, 1);) q  A0 x1 _0 J, o  }9 p$ g

  30. : A" l' P$ X/ ~" y) L/ A: l
  31.   /* Select register address (it will autoincrement when writing) */  S; f* W& p( Q6 P' `
  32.   ret += sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, &addr, 1);
    ! ?9 N+ z1 s: a9 [8 Q

  33. ( ?7 w1 f" J; o0 W6 G( ~+ }
  34.   for (i = 0; i < len; i++)
    5 |; a4 ~* K* {" D- H
  35.   {" |' b- K* J! w
  36.     /* Write data */; k" x* X& [  p/ k
  37.     ret += sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, &data[i], 1);
    ( T4 u0 ]1 p+ w  D
  38.   }
    ' s7 e! @, g  k9 C7 }3 f: w

  39. 7 v, P1 u( v# @7 T2 r: I
  40.   /* Disable write mode */
    6 g- S& q  P2 {& X' z, I+ h* G
  41.   page_rw.func_cfg_write = 0;* R. g& w( t+ B) N; O; ~9 r
  42.   ret += sths34pf80_write_reg(add, STHS34PF80_PAGE_RW, (uint8_t *)&page_rw, 1);; E3 I7 G! [3 L
  43. % Y" h- [$ {( T9 j' F7 P6 D. N
  44.   /* Disable access to embedded functions register */
    ' \7 v3 t8 @, B% W8 w  E2 b
  45.   ret += sths34pf80_mem_bank_set(add, STHS34PF80_MAIN_MEM_BANK);
    - Q  G1 b- O9 w4 W! N7 K" i, w

  46. 3 W" f+ t) U, `4 x
  47.   /* Set saved odr back */
    . e# h1 S; h5 e' W
  48.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);5 o. y& ]$ j( s8 w% I; a- U

  49. , _* k$ A# E0 K/ a
  50.   return ret;( p! h. t# k8 h/ X
  51. }
复制代码
% N) g8 O" P+ ]* W
分析上面代码,其中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),该函数具体操作如下所示。
  1. /**( r' I5 d5 I( Z, ~8 z5 s
  2.   * @brief  Change memory bank.[set]
      b9 l- E7 j; t, m
  3.   *
    , D& t: A, E. ~, A& a
  4.   * @param  ctx      read / write interface definitions5 X! \9 T8 g) [9 p2 T( }5 `3 Q
  5.   * @param  val      MAIN_MEM_BANK, EMBED_FUNC_MEM_BANK, SENSOR_HUB_MEM_BANK, STRED_MEM_BANK,
    & f2 H9 K: W' R. N6 ^
  6.   * @retval          interface status (MANDATORY: return 0 -> no Error)
    ' T  [% m/ e7 v+ n' _! c" a3 N
  7.   *; C" |' W" l4 R( S, P
  8.   *// [9 B  r  D. K% _
  9. uint8_t sths34pf80_mem_bank_set(uint8_t add, sths34pf80_mem_bank_t val)9 R' u4 W; C0 O$ E
  10. {
    ) B% `2 y9 j8 a2 q" B) Q0 k
  11.   sths34pf80_ctrl2_t ctrl2;
    # n4 v7 R- t3 ^
  12.   int32_t ret;
    - j) ?/ k0 }* C* m
  13. ) m% o# [, S/ ?5 Y6 }4 ^6 e
  14.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL2, (uint8_t *)&ctrl2, 1);//STHS34PF80_CTRL2->0x21
    7 z$ Q* `; O7 e; t! |
  15. 3 W+ P! a9 U, v8 x3 J* f3 R
  16.   if (ret == HAL_OK)
    7 k, Y" z8 r! k" r; U. v. \
  17.   {  I' G9 U- ?- n. T
  18.     ctrl2.func_cfg_access = ((uint8_t)val & 0x1U);
    2 g0 ]! H& s/ J/ w* I5 [& T1 H
  19.     ret = sths34pf80_write_reg(add, STHS34PF80_CTRL2, (uint8_t *)&ctrl2, 1);//STHS34PF80_CTRL2->0x21
    ) a3 [/ _0 m9 g6 e& b
  20.   }
    2 }) J! f/ |) Z! o0 A
  21. 4 \4 }( ?' W9 F2 f2 D
  22.   return ret;
    - S0 @/ J8 @4 |) {9 J
  23. }
复制代码
  1. CTRL2 (21h)如下所示,对FUNC_CFG_ACCESS设置为1主要是开启访问内嵌函数寄存器。
    : S7 U; J* m7 S. d: U

  2. + W% l1 v; \2 Z6 s- P+ ]
  3. 3 `# }% ]# z6 _) G* z
  4. 继续返回sths34pf80_func_cfg_write函数,
    5 z/ ]! z: D3 t5 S* ]
  5. 之后执行如下函数,主要为向寄存器PAGE_RW (11h)的FUNC_CFG_WRITE标志位置为为1,启用嵌入式函数的写过程。
复制代码
  1.   /* Enable write mode */
      |; r! h5 Y, t, V% {/ _
  2.   page_rw.func_cfg_write = 1;
    2 `! S: n9 Z. b/ g9 `1 }& n6 m
  3.   ret += sths34pf80_write_reg(add, STHS34PF80_PAGE_RW, (uint8_t *)&page_rw, 1);+ u5 J& a, I4 e# g6 Y7 R; n
复制代码

) Q1 O2 r3 `7 N* ^2 E9 [ 7.png
& B2 h9 u( W. i( u& g
$ z# y6 Z. \3 r/ O' }& s; U, q继续返回sths34pf80_func_cfg_write函数,然后执行如下函数,该函数为写入或者读取嵌入式函数的地址,具体要看PAGE_RW (11h)设置为读或者写,同时写入固定的data指令,当写完之后进入PAGE_RW (11h)关闭读或写操作。
( e# m1 ]* D1 ^( x
  1.   /* Select register address (it will autoincrement when writing) */3 l: D0 E; E  e$ k, L. ^1 j* x
  2.   ret += sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_ADDR, &addr, 1);+ j! K+ t) y6 K( ~0 N0 D+ H7 K
  3.   for (i = 0; i < len; i++)6 N: W7 q" k2 |; _' Z3 T2 B
  4.   {$ |/ \3 g: [' q) F* o' ^2 L
  5.     /* Write data */% h  N4 L6 n4 O$ d
  6.     ret += sths34pf80_write_reg(add, STHS34PF80_FUNC_CFG_DATA, &data[i], 1);( }- K7 ?8 D( h! y
  7.   }
    6 _  V; K4 ?% e6 f, j* q3 q
  8.   /* Disable write mode */6 W  Q6 E% t; ~
  9.   page_rw.func_cfg_write = 0;
    0 B1 [! Z* D5 h: |+ h
  10.   ret += sths34pf80_write_reg(add, STHS34PF80_PAGE_RW, (uint8_t *)&page_rw, 1);
复制代码

( H& g/ z+ Q3 ?3 h6 l" E* E0 f% ?  w 8.png . W) }3 `! v# O, @- N
1 m' J5 ]* Y0 {% Y. n. Y& l
这里传入的地址addr为STHS34PF80_PRESENCE_THS,这是个15位的寄存器,PRESENCE_THS 寄存器(地址范围为 0x20 到 0x21)主要用于存在检测算法的存在阈值设置。存在检测算法用于判断是否存在某种状态或条件,通常与传感器测量数据相关。
6 z, F) f5 V% K
/ m6 d4 B$ U) Z1 V
, K- n: f4 _+ D# r0 W/ _$ ~9 m7 \
具体解释如下:; |1 t& M' f) V; q9 H5 P% g
存在阈值(Presence Threshold): 这是一个用于存在检测算法的阈值。阈值定义了在测量数据中何时认为存在某种条件。在这里,阈值是一个 15 位的无符号整数(范围在 0 到 32767 之间)。
& ]. W2 Q6 d3 L8 }$ r
' A2 c+ ?7 i( b+ T5 v
8 p( Q7 h9 D% d$ F5 P" Q
默认值: 预设的存在阈值默认值是 200(0x00C8)。
+ L/ q4 K- d6 S
( o6 I, [- G1 Y+ V9 d( \1 { 9.png
6 i! k+ _1 E4 z4 h9 w0 ?
" T0 p" {0 h! u( o0 h接着执行sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr),将odr重新写入。( u' s- \: W/ P# F) `) P
* W) h, i8 j+ U. e7 K6 B- r/ h
  1.   /* Set saved odr back */
    ' w9 H; C% y! T6 b1 e" u% @
  2.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);5 m+ }- @0 v/ g
复制代码

5 `: H+ q; U; c1 D! n! y& {到此sths34pf80_func_cfg_write就已经设置完毕,返回sths34pf80_presence_threshold_set函数中,执行sths34pf80_algo_reset操作。: g/ c: l# B# C% l

! _& Q# M, B& P% d! _! R) W  U1 f% R
  1.   ret += sths34pf80_algo_reset(add);
复制代码

- ^" g) S6 u0 _* f该函数具体操作如下所示。
  1. /**
    6 \5 ]8 [( W5 K' C& P
  2.   * @brief  Reset algo& o( R' u0 p* X7 L+ N
  3.   *, Z4 D# Y! `: J) m
  4.   * @param  ctx      read / write interface definitions
    0 n0 @% v0 f# Z" |$ ?* N
  5.   * @param  val      reset algo structure  x" \+ F+ s- C+ J" T' S2 X+ b, t
  6.   * @retval          interface status (MANDATORY: return 0 -> no Error)
    3 o9 f/ @% o8 R5 s
  7.   *
    9 I8 G/ [1 f9 P4 t0 T! ?$ v. U
  8.   */
    . X4 ^3 z1 @8 Y& u
  9. uint8_t sths34pf80_algo_reset(uint8_t add)$ C( I& o0 Q# V& Z3 b! }- E
  10. {
    ! V9 |  _* L, w, q! }' G% v
  11.   uint8_t tmp;! x- p7 G, }/ D! h2 ^
  12.   int32_t ret;
    , s% I% g$ o5 _9 Z+ j; k' s  b3 e

  13. 3 L) b) j: E9 j. Q. _# e
  14.   tmp = 1;; d, h3 ~! N* H" C& S4 g
  15.   ret = sths34pf80_func_cfg_write(add, STHS34PF80_RESET_ALGO, &tmp, 1);//STHS34PF80_RESET_ALGO->0x2A
    9 z$ M8 v* R5 o8 c( }# V  j1 F% ^0 C. q
  16. 4 N7 w  R) V, r+ `7 P8 N
  17.   return ret;
    ' V* R$ H0 b' U' U: p' s
  18. }  r: b  N2 A) ~0 J5 V
复制代码
0 J9 t" F4 v' u" x) b
该函数对RESET_ALGO (2Ah)的ALGO_ENABLE_RESET 置为位1,执行算法重置操作。默认情况下,这个位的值为 0,表示不进行算法重置。当用户修改了与算法相关的参数时(例如阈值、滞后等),需要将 ALGO_ENABLE_RESET 位设置为 1。重置完成后,ALGO_ENABLE_RESET 位应返回到默认值 0。6 A2 d. _& X# R" n: O7 G0 p! P( b
( K& ^! @! A+ p: e
10.png
9 e7 Z2 c" r  y! y& Y  r1 ]6 P8 Q
0 v) l. Y, f. b$ V! f3 A5 @" G* e接着执行sths34pf80_tmos_odr_check_safe_set,将刚刚保存的ODR数据重新导入进入。
  1.   /* Set saved odr back */
    5 s: y  s" ~/ J+ s7 N
  2.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);
复制代码
$ X. Z+ k  q3 m4 ^, \/ J$ s5 P
到此,sths34pf80_presence_threshold_set函数就已经执行完毕。+ e% R. P, H" c6 |6 ?. ?

+ A$ M' E5 r# Y- T* u2 g
1 P: y# a+ I1 t2 ]1 x
设置存在滞后 / o1 l& P* ?  l# y; V0 d/ S
这里使用的函数为sths34pf80_presence_hysteresis_set(STHS34PF80_ADDRESS, 20)。
  1. /**5 z+ o) Z1 N, |
  2.   * @brief  Presence hysteresis.[set]) N# h) j8 O- v+ F
  3.   *$ U: z6 e+ k# x( Z9 H1 j
  4.   * @param  ctx      read / write interface definitions
    % e# v, K1 V4 O* ?6 p8 x* B) l
  5.   * @param  val      Presence hysteresis value
      J( d! D5 n2 Q( i) r, X3 f. x, e
  6.   * @retval          interface status (MANDATORY: return 0 -> no Error)$ H9 A$ d1 p1 T# O8 }' e! z
  7.   *
    7 x7 |9 {* E4 p& P
  8.   */. a7 r8 m0 d1 K9 B5 ~. z1 Y
  9. uint8_t sths34pf80_presence_hysteresis_set(uint8_t add, uint8_t val)3 R6 g, }2 y+ l8 M/ r; A/ Y  n4 `
  10. {5 O; u  _2 r' l% \* j
  11.   sths34pf80_ctrl1_t ctrl1;" k3 @# ]  r$ j. @4 k
  12.   uint8_t odr;& ~- c1 U% s7 {  [9 ?+ A
  13.   int32_t ret;
    ) _' c0 H% j9 ^8 \

  14. - `; ]. {1 H" b; u2 n5 E
  15.   /* Save current odr and enter PD mode */
    , |7 s) v5 l" U5 A% F* D" Q! c2 A
  16.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);- a/ g! z6 D% X! `4 R8 R
  17.   odr = ctrl1.odr;
    $ m7 J4 ?* a" F
  18.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0);
    3 e- _, ^- k0 w1 ]) a0 X0 @! R
  19. 7 q! t, J: c% i7 L8 Q* h
  20.   ret += sths34pf80_func_cfg_write(add, STHS34PF80_HYST_PRESENCE, &val, 1);
    # r* [& A/ z& q3 r$ |* F+ @. O
  21.   G# q: W1 c* Z! c
  22.   ret += sths34pf80_algo_reset(add);
    0 h4 d) D( c- _0 q# X) X2 Y$ U" }  r

  23. 6 g! \8 Y. b3 B5 l9 U4 x, x
  24.   /* Set saved odr back */  m! z# D, p2 K/ q# e
  25.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);
    8 ^6 o4 R/ q  e& L
  26. 7 D/ c- U; e! J
  27.   return ret;
    # n4 p  x& G% M! g( S4 z! O- A' M- k* o
  28. }
复制代码
7 s. ^7 `+ r) z: I7 ^6 B! f+ L" S! Z
最开始读取CTRL1(20h)的数据,同时进行保存到odr变量中。
  n+ q# y3 k" o  N; `
  1.   /* Save current odr and enter PD mode */
    ( f* O9 M/ Y8 ]8 \; u: {! @  ^' ]
  2.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1->0x20; v# Y7 T2 ]2 _! }) v2 p: g  h
  3.   odr = ctrl1.odr;
    " K' y1 d. I8 x  E0 a3 Z$ L
复制代码

, @4 ]7 x7 C4 l7 K3 Mret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0)这行代码用于在设置存在阈值之前,通过调用 sths34pf80_tmos_odr_check_safe_set 函数来确保在设置新的参数之前传感器的状态是稳定且安全的。
' Y& `7 m8 Q7 \* y! U: D4 L/ E! h- ^

0 u3 X0 f4 N: l. @) V% S紧接着将传入的数据保存到val数组中,然后执行sths34pf80_func_cfg_write将val数据传入到HYST_PRESENCE (27h)中。& j4 N& k1 H, h1 f
  1.   ret += sths34pf80_func_cfg_write(add, STHS34PF80_HYST_PRESENCE, &val, 1);
复制代码
$ t! F; V: j$ T" w& y9 G
这个滞后值有助于避免在边界值附近产生频繁的状态切换。7 }9 J7 |8 o% g

& |5 ~6 R; K7 ]/ a( x2 A; R默认值: 预设的滞后值默认值是 32(0x32)。; O8 _, {. M. D: X) ?
1 V2 z# |$ w: h2 w: g' N' I
11.png 9 c7 M! k0 T6 w6 g- i
) o$ m, T3 {2 z2 \$ F% H! ]
例如,假设 PRESENCE_THS 设置为 200,而 HYST_PRESENCE 设置为 32。当测量值超过 200 时,传感器会认为存在某种状态。然后,要从存在状态切换到非存在状态,传感器必须降低测量值至少到达 200 - 32 = 168。只有当测量值降低到 168 以下时,传感器才会触发状态切换。
; D7 h. z2 o4 J
9 {: Q  l& d+ X
通过设置适当的滞后值,可以防止在测量值在阈值附近波动时出现不必要的状态切换,从而提高存在检测的稳定性。+ \/ ^# ]8 z- C; w
5 k) O) c' C2 D9 _0 ?" A; \
接着执行sths34pf80_algo_reset函数,该函数主要对RESET_ALGO (2Ah)的ALGO_ENABLE_RESET 置为位1,执行算法重置操作。
+ h) G# E" e% B5 t: F$ d1 z4 F& U. M5 w: n4 @2 b
  1. ret += sths34pf80_algo_reset(add);
复制代码
- I* u7 p$ F4 d6 H9 ~( R
接着执行sths34pf80_tmos_odr_check_safe_set,将刚刚保存的ODR数据重新导入进入。
  1.   /* Set saved odr back */1 H$ B5 w4 Z8 p* `! A
  2.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);
复制代码

& C- }5 q% h9 F5 o2 p4 _4 v, {# q到此,sths34pf80_presence_hysteresis_set函数就已经执行完毕。. u0 V" O. C% k4 c) ^4 c

  ?5 k$ z! C  i

$ H/ ]% ?! \0 Z" T- N设置动作阈值
3 o/ W0 j" L+ z, h2 r, C, r这里使用的函数为sths34pf80_motion_threshold_set(STHS34PF80_ADDRESS, 300)。
  1. /**
    ' ]9 f4 j4 X, n8 v% ~; R2 S% g
  2.   * @brief  Motion threshold.[set]6 L& N: Y0 p& `! r: E; Q
  3.   *7 L' ^+ b3 v  `" c! x; B4 S
  4.   * @param  ctx      read / write interface definitions9 l, t% Y, A  p3 k$ P& N
  5.   * @param  val      motion threshold level' F- K+ S( q# Q4 j# I
  6.   * @retval          interface status (MANDATORY: return 0 -> no Error)$ H/ ^+ \( u/ V9 }6 h& Y+ R: _
  7.   *
    3 V: {' x- M% g4 T- ?# [7 ~2 [- F$ ]' j
  8.   */, |1 R  s- l1 d
  9. uint8_t sths34pf80_motion_threshold_set(uint8_t add,  uint16_t val)
    3 s- d, w  }4 W# ?, p/ m
  10. {) h4 X# D! V& s0 S4 Z$ u2 i4 g
  11.   sths34pf80_ctrl1_t ctrl1;
    ' B% S/ [5 c+ M' H9 }) j
  12.   uint8_t odr;3 Y/ n# Y7 e0 z3 W: c
  13.   uint8_t buff[2];
    ' n+ f- `6 C9 w; E
  14.   int32_t ret;
    8 n7 |% N: r" w. b; R+ e

  15. ) q* L1 b+ |) H" E8 @6 q9 b) x
  16.   if ((val & 0x8000U) != 0x0U) {7 p( j$ Z: w1 ~; l
  17.     /* threshold values are on 15 bits */% A6 L, l6 b( K0 C4 w5 J
  18.     return -1;( f  T( E$ f6 B; V8 |0 R
  19.   }, r' S( T" u  Z1 M0 J
  20. 2 [2 }& Y: @/ X6 j* d, X
  21.   /* Save current odr and enter PD mode */
    / l$ v: h8 V* I5 W) m
  22.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);: v$ l, ~6 k5 k, \% D+ s
  23.   odr = ctrl1.odr;
    - Z3 z6 ?  v& z8 G
  24.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0);4 @; e) [! b7 \& q5 o

  25. ; t$ Q: @% O6 J7 v8 ?& Q* R$ `
  26.   buff[1] = (uint8_t)(val / 256U);% ~& t7 M& `$ ?# t7 i. S3 f
  27.   buff[0] = (uint8_t)(val - (buff[1] * 256U));
    $ T7 b: ?1 R, f* k6 I
  28.   ret += sths34pf80_func_cfg_write(add, STHS34PF80_MOTION_THS, &buff[0], 2);' l4 m1 K2 D: b; u0 w) n

  29. $ g! o+ ^: h9 {; ^# \  Z1 b
  30.   ret += sths34pf80_algo_reset(add);
    % |, T, y* T4 T$ R

  31. # I% L2 _9 k7 k9 t
  32.   /* Set saved odr back */
      L3 h$ w+ S/ G/ L0 p
  33.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);
    6 X2 `( {- f3 P" m9 a, o
  34. 7 ~( i# H8 k( }: z- W3 `* W& U
  35.   return ret;; i% w7 }2 {# W4 M1 g( R3 j, _( `
  36. }
复制代码
; W  F5 C# ?5 x: b/ i
最开始读取CTRL1(20h)的数据,同时进行保存到odr变量中。
  1.   /* Save current odr and enter PD mode */
    , ^( o9 \' B0 c  i0 @3 Z( o
  2.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);
    7 s# t, `) j' g
  3.   odr = ctrl1.odr;1 t9 m# m: i7 v) f5 }
复制代码

) i- J) y: J2 N# s# f1 ^, n: D9 `ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0)这行代码用于在设置存在阈值之前,通过调用 sths34pf80_tmos_odr_check_safe_set 函数来确保在设置新的参数之前传感器的状态是稳定且安全的。0 t7 `$ p& v. R8 e
+ Q( D! w" v' Y" Z" k, ?
  1.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0);
复制代码

  O" @" Q9 S* x. H5 c) C8 h+ t接着将传入的数据保存到buff数组中,然后执行sths34pf80_func_cfg_write将buff数据传入到MOTION_THS (22h - 23h)中。
# W% L' v4 k* y& @4 z+ S( ~% n
  1.   buff[1] = (uint8_t)(val / 256U);7 A4 u" s& x* p% P) v# l0 ]' c
  2.   buff[0] = (uint8_t)(val - (buff[1] * 256U));
    - T1 P, _" l* O  k5 t% m! l
  3.   ret += sths34pf80_func_cfg_write(add, STHS34PF80_MOTION_THS, &buff[0], 2);; M  c# G2 q; b1 y, |% I
复制代码
1 v. a8 v, e, U) @" m9 a/ h
MOTION_THS 寄存器(地址范围为 0x22 到 0x23)用于设置运动检测算法的阈值。运动检测算法用于检测是否发生了物体的运动或动作。
6 X1 d" X2 X( h2 d( |, `# c5 p

) T; I+ i( c( a8 Z以下是这个寄存器的作用:
: g0 B6 J% W$ c1 ^! ^: s* x  u- g% f1 |' {' r) k
运动阈值(Motion Threshold): 这是一个用于运动检测算法的阈值。阈值定义了在测量数据中,何时认为发生了物体的运动或动作。阈值是一个 15 位的无符号整数,其取值范围在 0 到 32767 之间。
) p, _, U" u  ?* D5 n/ t
* r  p3 Y. @+ @: X7 o2 G
默认值: 预设的运动阈值默认值是 200(0x00C8)。3 @7 ?6 c; U. X/ _: ^; ?
+ h% x6 e+ J3 b- U0 h0 s6 P& n4 o
例如,如果 MOTION_THS 设置为 300,这意味着当传感器测量的某个特定值超过了 300,传感器会认为发生了运动或动作状态。
# ~- s) Y; q# N4 ?( g( p

" k7 X2 O5 `4 u! y通过设置适当的运动阈值,可以根据应用需求来调整运动检测的敏感度。更高的阈值会导致较大的变化才能被视为运动,而较低的阈值则会使传感器更敏感,甚至可能在较小的变化时触发运动检测。
. n9 ?8 e$ _* Y) R: u' c
% k/ ^) M7 u3 d, J, b
12.png ; o0 a1 L1 l; ]9 d

( w/ p( @5 V7 T1 _8 T; r( m. A% T接着执行sths34pf80_algo_reset函数,该函数主要对RESET_ALGO (2Ah)的ALGO_ENABLE_RESET 置为位1,执行算法重置操作。# L! w) V& c' j# D

* p3 t4 T  \" j7 y( ?3 M1 w
  1. ret += sths34pf80_algo_reset(add);
复制代码
' |9 g* v# J  r0 a- w
接着执行sths34pf80_tmos_odr_check_safe_set,将刚刚保存的ODR数据重新导入进入。
  1.   /* Set saved odr back */# G7 K6 D( o9 {1 U' K# l) ^( R
  2.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);
    7 p1 t$ D5 t- m0 q; W
  3. 3 A( h" C5 c  p
复制代码
1 M0 P. T3 s5 A+ [
到此,sths34pf80_motion_threshold_set函数就已经执行完毕。+ |1 a2 C( p% Q4 L3 m0 H
) C. [5 t# l8 Q

  g8 c- @  q4 N8 E, A. ?& T设置动作滞后 / u$ G& Q) c: _1 B3 I9 k' }) C
这里使用的函数为sths34pf80_motion_hysteresis_set(STHS34PF80_ADDRESS, 30)。
  1. /**$ ~- H% |. U" [4 S
  2.   * @brief  Motion hysteresis threshold.[set]  g( o6 v! G- m5 T) z) E
  3.   *
    7 M3 |1 C1 I" t6 g0 z" S" \: ~
  4.   * @param  ctx      read / write interface definitions
    ( r+ d& d$ }+ l8 v
  5.   * @param  val      Motion hysteresis value+ \# F& L) [- e+ C& c
  6.   * @retval          interface status (MANDATORY: return 0 -> no Error)3 ~7 x( r8 N! g  Y$ A" O# \
  7.   *
    4 R( f* ~' }# {) B( m+ W
  8.   */& w) v  y# J( @$ M: K$ s3 a' n1 C5 b
  9. uint8_t sths34pf80_motion_hysteresis_set(uint8_t add, uint8_t val)( n# [, H: m4 M4 g" W6 m6 P
  10. {, a& z8 @  s/ ?; O' K. N
  11.   sths34pf80_ctrl1_t ctrl1;
    9 g$ [7 V( U- c+ W- K3 \# e5 {
  12.   uint8_t odr;
      r" y3 U7 I% R' B8 G( |- ?3 W3 w
  13.   int32_t ret;
    # P4 C- W$ g" B0 W; ?3 _6 U
  14. ; ^$ r* S# ]" F5 }& k
  15.   /* Save current odr and enter PD mode */, m, t$ ^9 B3 ]! [
  16.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);" W2 j5 p8 {' D+ P! D
  17.   odr = ctrl1.odr;" E; M! r& Y; K3 a
  18.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0);
    6 J1 f* @% m7 P
  19. ) N+ N/ I+ T+ ~! @6 V  y
  20.   ret += sths34pf80_func_cfg_write(add, STHS34PF80_HYST_MOTION, &val, 1);
    ' x2 l" J1 ]$ Y1 n# Y0 ?

  21. - p  I! K: h0 N  m. n. c2 m, L$ V
  22.   ret += sths34pf80_algo_reset(add);' a2 L* b% J% @+ j
  23.   _# i+ U3 E2 f1 k! f( S  h
  24.   /* Set saved odr back */0 u% O4 k  g1 s" h
  25.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);6 P7 Y1 i' J3 e* ?0 A9 _8 F# Z

  26. 7 C3 h$ q& v% r1 d
  27.   return ret;0 o4 {6 w& [4 F1 s* Z5 B7 E
  28. }
复制代码

% z9 j: B& {5 Q. ~9 r3 o最开始读取CTRL1(20h)的数据,同时进行保存到odr变量中。
  1.   /* Save current odr and enter PD mode */* ]5 c4 s7 [0 X; i& ^( g
  2.   ret = sths34pf80_read_reg(add, STHS34PF80_CTRL1, (uint8_t *)&ctrl1, 1);//STHS34PF80_CTRL1->0x208 g* s% F# I* H  C3 Y( y
  3.   odr = ctrl1.odr;
复制代码
; K! z) C2 `0 Q" x
ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, 0)这行代码用于在设置存在阈值之前,通过调用 sths34pf80_tmos_odr_check_safe_set 函数来确保在设置新的参数之前传感器的状态是稳定且安全的。5 K; W! f" q9 u0 H, c7 s/ \' O2 m

! ?# d3 k0 V5 N( {5 ]4 k$ V) u紧接着将传入的数据保存到val数组中,然后执行sths34pf80_func_cfg_write将val数据传入到HYST_MOTION (26h)中。: t! y; y& y& n
; b. k6 }1 |+ @" R7 q, Z" w0 y
  1.   ret += sths34pf80_func_cfg_write(add, STHS34PF80_HYST_MOTION, &val, 1);
复制代码
7 I* Q! Z& [, _# z# _
在运动检测算法中,滞后指的是当从运动状态切换到静止状态时,需要等待的时间或条件,以防止在短时间内频繁地切换状态。
$ L# i8 ]# ~8 e) G# H7 Y9 j
& w: y0 Q" s  N& }0 T1 v$ G默认值: 预设的滞后值默认值是 32(0x32)。
) K& ?% ?% V" B7 B* \3 P
) `9 f6 \" x2 d/ h
13.png
: J6 p# H* q/ x8 Z

2 o6 k8 G, W* h例如,如果 MOTION_THS 设置为 300,而 HYST_MOTION 设置为 32。当测量值超过 300 时,传感器会认为发生了运动。然后,要从运动状态切换到非运动状态,传感器必须降低测量值至少到达 300 - 32 = 268。只有当测量值降低到 268 以下时,传感器才会触发状态切换。5 D6 q) c5 ~4 J! S; U; G' @: u6 X
: W* T- x# B: t! g. F
通过设置适当的运动滞后值,可以避免在测量值在运动状态附近波动时产生不必要的状态切换,从而提高运动检测的稳定性。这类似于存在检测中的概念,但针对的是运动状态。9 V! _5 J( u0 [2 Y3 Y' ^( f2 A

7 O1 n2 {- K, d7 b# b9 g% t# }接着执行sths34pf80_algo_reset函数,该函数主要对RESET_ALGO (2Ah)的ALGO_ENABLE_RESET 置为位1,执行算法重置操作。3 r+ p: k/ }' e3 b2 ]
7 `$ m" k! A2 F
  1. ret += sths34pf80_algo_reset(add);
复制代码

1 u  {# R3 g* i4 Z接着执行sths34pf80_tmos_odr_check_safe_set,将刚刚保存的ODR数据重新导入进入。0 e$ A7 a& `- ?- s
  1.   /* Set saved odr back */
    6 Z$ a+ l1 B6 S3 v0 V2 W
  2.   ret += sths34pf80_tmos_odr_check_safe_set(add, ctrl1, odr);
    . v- K* }# S& Z) P
复制代码
1 p  k7 B- W% e% p+ C' X* f
到此,sths34pf80_motion_hysteresis_set函数就已经执行完毕。) t# w! i8 _! u2 ]
) U: @' L2 K6 y  Y/ q) ^8 W
主程序   @  G& J. X6 u: Z7 v0 ~6 U
初始化如下。
  1.   /* USER CODE BEGIN 2 */; j9 u1 J+ T5 d, b
  2.   sths34pf80_lpf_bandwidth_t lpf_m, lpf_p, lpf_p_m, lpf_a_t;  
      S+ A. O3 e( i" j8 \2 _$ p; N
  3.   sths34pf80_tmos_drdy_status_t status;  
    ! ]( c  ?0 j9 Z
  4.   sths34pf80_tmos_func_status_t func_status;   
    ; U" b) M& Z9 ?( l* l. M
  5.   " N7 H- r  P" [: l# b. `: c
  6.   HAL_Delay(200);  7 `. o! U" a/ j0 w* R! H: s4 D6 ]: Q
  7.   printf("123");0 I' B4 v) C& K, w/ m% N
  8.   uint8_t STHS34PF80_ID =STHS34PF80_getChipID(STHS34PF80_ADDRESS);2 z; J) J# x/ x
  9.   printf("STHS34PF80_ID=0x%x\n",STHS34PF80_ID);  
      A0 I5 s' E1 g" M
  10.   if (STHS34PF80_ID != 0xD3)+ U. J- l3 m" u1 f) g
  11.     while(1);1 A: }" i2 d5 g0 o
  12. /* Set averages (AVG_TAMB = 8, AVG_TMOS = 32) */
    5 s1 {6 X1 g: p1 ~5 i9 R% V) f
  13.   sths34pf80_avg_tobject_num_set(STHS34PF80_ADDRESS, STHS34PF80_AVG_TMOS_32);% @" f' r% V" w+ A( w+ @0 E
  14.   sths34pf80_avg_tambient_num_set(STHS34PF80_ADDRESS, STHS34PF80_AVG_T_8);
    : m0 W& o5 o) M
  15. : _0 x. j" m$ r6 [* x; a( o/ j
  16.   /* read filters */
    & x3 a& x! M% l, E& y
  17.   sths34pf80_lpf_m_bandwidth_get(STHS34PF80_ADDRESS, &lpf_m);
    ; [% m) S' B4 a6 j" L  I* l
  18.   sths34pf80_lpf_p_bandwidth_get(STHS34PF80_ADDRESS, &lpf_p);
    2 n2 S& w" d2 p: h  y. y+ D
  19.   sths34pf80_lpf_p_m_bandwidth_get(STHS34PF80_ADDRESS, &lpf_p_m);4 S0 Q  r" X; ]9 w7 E! A8 b# B
  20.   sths34pf80_lpf_a_t_bandwidth_get(STHS34PF80_ADDRESS, &lpf_a_t);& I! V2 |- ~1 \3 o' O: [6 K# U

  21. / ~+ k0 `6 n2 z9 a/ c6 k
  22. 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);
    + L9 a, L! e2 ?1 g. w6 q
  23.   ; E3 ]3 J3 U7 n
  24.     /* Set BDU */" x2 J$ V. u5 ?" h' |
  25.   sths34pf80_block_data_update_set(STHS34PF80_ADDRESS, 1);
    ( O* j: L* C$ H. w/ B% ?
  26.   ; A( P" ^4 g/ D; I+ e6 ]) a9 e3 w
  27.   sths34pf80_presence_threshold_set(STHS34PF80_ADDRESS, 300);  //设置存在阈值。8 C; R$ o7 `9 G3 d7 _
  28.   sths34pf80_presence_hysteresis_set(STHS34PF80_ADDRESS, 20);//“存在滞后”(Presence Hysteresis)的函数( b3 w% ?  J& \4 d  C8 j, a
  29.   sths34pf80_motion_threshold_set(STHS34PF80_ADDRESS, 300);//设置动作阈值
    ( E- [5 s3 y% ?( S# u
  30.   sths34pf80_motion_hysteresis_set(STHS34PF80_ADDRESS, 30);  动作滞后”(Motion Hysteresis)的函数! r, R. Y7 B: ?; F* |9 o! \, @7 x
  31.   /* Set ODR */
    + X$ c8 S: f' d; o  Z
  32.   sths34pf80_tmos_odr_set(STHS34PF80_ADDRESS, STHS34PF80_TMOS_ODR_AT_30Hz);7 `! X/ Q# [0 ^+ o
  33. & J2 v& `' E8 T
  34.     int32_t cnt = 0;
    + W+ P. t; E# ^+ y* y+ b' ^6 n; U
  35.   
    , q( S6 N: q& @8 J$ J: V1 s+ z3 u6 z
  36.   /* USER CODE END 2 */
复制代码
7 M6 G& y7 A7 o& o0 M% D0 a4 G; X
main函数如下所示。
  1.   /* Infinite loop */: y$ z5 H; |/ J1 y9 F
  2.   /* USER CODE BEGIN WHILE */
    2 W2 l) t, d* N% ]; I. l
  3.   while (1), t4 u+ u& f+ ]' L
  4.   {
    7 J; }! z! x, u) I: n4 }. @
  5.     sths34pf80_tmos_drdy_status_get(STHS34PF80_ADDRESS, &status);
    ) t; E( i. N; o
  6.     if (status.drdy)
    ' D! C- D5 s: t- d4 M* `' L% Z% r
  7.     {8 U7 S7 o. s' u  S6 G. f
  8.       sths34pf80_tmos_func_status_get(STHS34PF80_ADDRESS, &func_status);
    9 ~( E: l, H) O. _6 |
  9.       printf("-->环境温度冲击检测标志位 %d - 存在检测标志位 %d - 运动检测标志位 %d\r\n",func_status.tamb_shock_flag, func_status.pres_flag, func_status.mot_flag);) a, Y% ?6 Y& C6 v
  10.    }2 p$ C" g) s9 p, t: Y
  11.       HAL_Delay(1000);# D. E, K! T- O
  12. + ~! x; F; x" v2 ~! ]
  13.     /* USER CODE END WHILE */( z: F6 I! M7 K

  14. 7 O+ s! q# K1 p# C- J- d) @
  15.     /* USER CODE BEGIN 3 */
    ! w$ P. n+ G% c
  16.   }
    ) O8 x; J2 }. k+ [/ E
  17.   /* USER CODE END 3 */# Y. I0 b5 Q9 {# M4 S1 o0 f5 F3 c
复制代码
9 Z' ^  Q, y0 _7 l1 q

1 @- d9 K, m& }. s, I& |转载自:记帖
) Q5 D9 T& S% }4 @3 k如有侵权请联系删除8 f/ `$ y: U5 s+ \# j! P% k

* S  R/ R5 l6 }. i6 m
7 P9 |0 C" a- T( A4 Q6 n% V. L: R2 v0 w0 U

8 \% C* {1 n5 w; j& \% F. J1 Y9 [- i3 G* T0 K' i
收藏 评论0 发布时间:2023-11-16 17:09

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版