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

【经验分享】STM32F0 定时器中断 小白掉进的坑(FreeModbus)Timeout

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn
+ S7 v( w  t! G0 y+ D: Y1 c
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */
    2 P5 U9 g, U( F$ T1 ?  i
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */
    2 s+ o) A6 \. {% e: }) d# @5 @
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */
    1 Q9 e7 m/ b& j# s  K. z& L2 M3 w4 G1 w
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */5 Z6 O" Q: G3 F' P& _7 T( C
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */
    / y" P- Y8 s# q* N* \. [1 ]( B6 @
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
    4 @6 t$ e1 g9 b, C
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */9 ?8 v  c3 z7 y* ^9 q5 ?
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码

9 X. c6 `; Y* }+ x* C+ F2)通常每个IRQn对应一个zho中断函数) Z9 X" H& x; \" I( J6 L
  1. /**5 g6 y: k; ?& V" B( M, {# k! M) z
  2.   * @brief  This function handles TIM14 global interrupt request.
    / Z/ M5 z3 f9 i% A3 N& v3 @- L
  3.   * @param  None& ]5 D$ B% n9 k9 u  e* S, r4 q
  4.   * @retval None( p3 P. J' ~# n  H' a
  5.   */, {- I& j3 A# i. c) u; {* E
  6. void TIM14_IRQHandler(void)5 Y) m" j5 o' z
  7. { ( r$ E9 ?5 j( t& D$ y: x
  8.   HAL_TIM_IRQHandler(&Input_Handle);
    1 D8 f5 ~  z* j# I4 m% d
  9. }
复制代码
1 ]6 T6 m! {$ `+ C
3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断
1 W# `" m" o: O; v8 o
$ |* t8 M, D( D
  1. /**
      [% ~8 M4 ~3 H
  2.   * @brief  This function handles TIM interrupts requests.
    1 k8 {' e* D  ?" j, _# x6 B
  3.   * @param  htim TIM  handle
    * G9 v9 c# p! }9 g$ Y
  4.   * @retval None3 P  U: k( h, T/ F+ a6 |; K0 g2 Q' N
  5.   */
    ; n3 H$ T/ V8 S9 w' \
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)& o4 K6 S+ R& g$ t( ]$ j
  7. {, Z" J( a- m/ J1 U6 ]6 _  m, Z
  8.   /* Capture compare 1 event */; A; {3 U6 [4 y9 }, G2 p
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET), C  B  v$ m, W% _
  10.   {
    , U' t) l- z8 p4 l$ Y
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)( v- s5 m# k1 ^3 |+ |
  12.     {
    3 o( ~0 n3 S. q  m, x& \
  13.       {; l6 Q2 N; `2 {) Q
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
    & ?" z: {+ c4 d" d+ J7 U
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
    ! q1 J/ v3 o0 b% n/ D. A  k

  16. : R: X0 K7 s, t
  17.         /* Input capture event */
    $ \( C' C. x$ q: i( ?! A0 k
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
    - {1 ]- u' {/ ^/ A7 g
  19.         {
    , p: W" U% f% }% N
  20.           HAL_TIM_IC_CaptureCallback(htim);
    ! N$ R& w! r8 G% p& S( K5 e& x
  21.         }9 k: d* c: l  y, r; V; M
  22.         /* Output compare event */
    + S, Q, S8 z; a; A
  23.         else: o+ Q+ O* S- f4 e# C+ ^
  24.         {
    8 R( I+ d) P. u2 ?& \1 \+ j
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);
    ' I6 T  C, i4 x$ `0 h3 `
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);
    0 S% s' J0 j0 d- ]) g# B
  27.         }
    8 q# P. }# E5 l& J6 U5 r5 O# _
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    , I8 m' c; R& M$ i; x
  29.       }
    4 |& H. J0 I+ ]
  30.     }
    2 C; E3 e- f! N6 I+ a, p
  31.   }
    . S6 j& T% }  \( v  V& r
  32.   /* Capture compare 2 event */: _' j: N7 N# f( m. T
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
    $ c1 X  y2 ?0 W% t3 O! a
  34.   {  N" {, @9 z9 K$ t# o, Q
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
    # l# M7 U3 n3 y. b& h
  36.     {
      U2 G4 T+ d) u2 F8 A- ^5 t
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
    % V3 L! ^) J) @) q5 ]7 Y1 ?% C
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;5 H0 h. ~9 a) I0 k* K6 W4 I: \& K2 v) c
  39.       /* Input capture event */# ]4 M1 M, G1 y! h
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
    + ^0 V  H$ c. U  @( l. e
  41.       {: v2 W) [; A/ p+ G
  42.         HAL_TIM_IC_CaptureCallback(htim);
    & ]$ l/ k: j' `9 Y- P$ y1 L0 q& h
  43.       }$ }# X& A+ F/ B' O" d) @( g8 |
  44.       /* Output compare event */
      R( R+ o( u) s7 ]6 _
  45.       else
    ' b9 D0 W; `4 {% V$ v8 V$ i( C
  46.       {" z) e  f8 {9 F8 z1 h/ z# S
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);
    # Z/ V& U) G' \( s
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);- z4 z" I% h/ A2 I, [) O% u8 u
  49.       }
    % Z5 H- t$ t& d; v( Z7 h+ I
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;; q3 y7 U  B& D" ?- R0 D; u/ q
  51.     }
    - s: ~9 B! a, `0 m. P; C6 ~
  52.   }$ h0 {, j  @% @5 y# g5 [. w( S
  53.   /* Capture compare 3 event */
    * @0 b- ?; j& H& v; e7 M/ Z$ b
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)$ J! K( m7 t- p; q! r* Q  j
  55.   {
    4 ?! s+ D; o0 F% y
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
    ( b+ \# r8 a+ e3 H
  57.     {% c/ V9 e9 B8 H" Q5 G( y
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
    8 p7 X' M% [# q9 C7 G) S
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
    1 \( S$ C. K" A4 I
  60.       /* Input capture event */, M' w& Q# q1 L+ n
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
    9 P2 v1 t1 ^; N& M; d" Q' C$ _. u
  62.       {1 }9 x1 d  q& l+ \- o
  63.         HAL_TIM_IC_CaptureCallback(htim);
    - y  A9 O; `: j& n* ?: C
  64.       }
    # Y$ ~' i0 [1 Q1 u
  65.       /* Output compare event */1 @' d( C: g0 {: V
  66.       else
    # ^, z8 _1 a. ^$ t, p. k1 J5 o
  67.       {
    9 I4 V$ R; p1 C1 O4 l& L
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);/ i- D7 [. Q, ^4 w  V+ V$ P
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);5 u6 {7 p1 v# S* x. E& H
  70.       }; l5 f6 ^; G7 @- |3 h  o* B
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    ; U5 P: E# Q) p( |5 \& B& q
  72.     }6 k# t; N/ A( u8 z
  73.   }
    # [- K1 D  h1 z2 g
  74.   /* Capture compare 4 event */
    ) h; E7 t4 \  r' `2 a  `
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
    * h; W7 e6 q# O2 N# w
  76.   {
    + m: r* X' D7 {8 a0 y$ z6 A# _4 K
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET): x2 I5 U! o; w' Y5 t$ |- [
  78.     {
    : Q7 @! C8 ^4 P9 |2 r$ a5 k( R
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
    ! U3 z8 N* J9 ]2 ]
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;6 g! A  V  \( T. w/ l- u
  81.       /* Input capture event */
    4 j2 c7 C4 n# X
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
    * B4 C: s& l  D$ ~
  83.       {* f2 r' z: B& `# A0 k
  84.         HAL_TIM_IC_CaptureCallback(htim);
    ) `, |0 }/ o! C/ H
  85.       }
    , U$ }$ y7 K) H' O- o9 V
  86.       /* Output compare event */
    4 k- z6 l/ H4 o
  87.       else' U( J% H: q0 S8 f& [. L
  88.       {
    1 |! H, x. ]# u/ f
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);+ a5 W$ l6 t, {# M+ g4 \
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    - z2 l( j) A; g) ]( P
  91.       }
    8 ]3 e3 t0 f" j' B: {* a
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    . s% J1 N: [+ R4 W" }" l
  93.     }. A" B0 t% R$ k+ D) o
  94.   }
    + v1 e+ f' M% |6 X0 q$ v( M% m
  95.   /* TIM Update event */
    $ P  g# p% z7 Z) ~
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)0 I* H' f  x5 y* P0 m
  97.   {3 {5 q6 i3 M$ a$ S9 x6 v2 l7 f7 w
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)* v! D' z9 M2 I/ h0 q7 \2 w6 @
  99.     {- V2 R* h/ e0 p0 T9 b5 [
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);: k6 F! s+ K$ i' r: s: Z; _  x# H" W
  101.       HAL_TIM_PeriodElapsedCallback(htim);
    1 j7 Y' Z+ J  p! W( H1 L
  102.     }
    - y! u. ?) x2 K2 e
  103.   }  |: x' p) K( W9 n; G
  104.   /* TIM Break input event */
    / |3 [1 X+ ^6 s( o9 _
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
    " o: h4 c% b) P  ]3 ?2 B
  106.   {, h8 ^: ]' I6 T: r# t
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)1 z# T9 j3 f- T; y" L7 ~" k
  108.     {
    , [3 m. {/ Y  X7 i1 z
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
    2 [! D+ u7 x4 t3 R
  110.       HAL_TIMEx_BreakCallback(htim);
    ' N) Y- i4 i. K: W
  111.     }. H9 Y& Z* U7 I& p5 f
  112.   }
    ( c; ~/ ]2 v4 x& ~9 W- w, [
  113.   /* TIM Trigger detection event */2 W/ ?8 D- w8 h5 L$ S) ^' d" o  J
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)1 J7 X3 U! h( _5 z) f6 B" V* W
  115.   {
    - E3 R- H' R' L2 L5 m; i
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)6 Z2 b9 W+ L5 C' C4 {! b
  117.     {
    % M$ K/ S. }! s2 \4 t
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
    * \8 {& f6 t1 \8 [2 w  j
  119.       HAL_TIM_TriggerCallback(htim);
    ! I  E5 U6 V# [+ a* V; U" H
  120.     }
    0 |/ z2 p' l# B* k, _) q
  121.   }
    ( z6 ?- l' |$ q6 M) v
  122.   /* TIM commutation event */
    ! ?5 M! u6 K# Q4 z+ E' n
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)6 g6 ~: ]/ F! d+ ?$ }" t
  124.   {) A2 p4 w6 a9 r! R
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)1 P; A: D& v. H' {8 V; u
  126.     {
    $ J# N5 S. l9 O6 J  R' u
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
    * ^8 Q( i: ?* B) `* t! j
  128.       HAL_TIMEx_CommutationCallback(htim);) l+ i/ {- |! M7 H, W
  129.     }
    : w/ B" ]8 Y8 d# U& J
  130.   }" Q# ?; l4 V, n; L& K, s
  131. }
复制代码

! F$ e. T: u$ U4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);
' }  ^! }; w% l/ C  {4 s
- J$ n) |4 J- Q6 {5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码
    4 K4 z" E' `4 S- m1 a+ z, k1 `( {

  2. ( h+ S5 `1 o& r2 g) B' ]4 k+ r
  3. void TIM14_IRQHandler(void)5 r  f6 }# i5 q, E6 I
  4. {
    , ~% l, `" A& Q
  5.   HAL_TIM_IRQHandler(&Input_Handle);
    . @4 d7 v/ A" H* ?  l( ~

  6. 3 w  c+ g, {; d0 e
  7. //其他处理代码4 z. R) h0 D$ B
  8. }
复制代码
2 b* Y$ T. F9 Y* Z) Y8 n' e. X
6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。
1 L. [! o9 g  _. y# ~  J: G7 k% Y+ d' B
7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。
' J3 h5 L: d, [& Q: I; ], K
3 e4 B2 u3 T! n: b& d8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。
/ T$ W6 {1 N# C' A: M  n7 u
" F' D# U/ {% G6 y' y) G在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。
. R) x) u6 U+ |3 Z
0 P! V+ _$ T& g3 }9)ken坑啊,都怪对库的执行sh顺序不了解。3 ~2 Z; d2 u8 p& O
& L% P" ]& Z# y& ]; y% `9 D& B
# `1 |( _1 C) z- ^2 }; |8 C
收藏 评论0 发布时间:2021-11-25 16:00

举报

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