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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn
0 I* X9 L9 I, _  m2 D# O- W. h
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */% n0 i8 a  |3 k6 d* k+ M5 s
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */' [: ]+ P+ c# m0 |8 }4 A
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */2 C2 A. Q  d" [$ M; @, e0 j, D
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */6 W  {/ P1 J/ }& Q. A% v* Y
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */
    " S6 `+ v4 W; j
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
    ( w, n9 z# o0 {% [$ t/ r- H
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */
    $ _& E- }2 @; n
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码
5 F% [. d& d* R$ ^  b0 a
2)通常每个IRQn对应一个zho中断函数) h+ v* H4 n" T2 k5 E/ q
  1. /**5 N' ^0 g3 }' }; u) q3 h$ n
  2.   * @brief  This function handles TIM14 global interrupt request.
    2 I$ E# y; N  D2 }
  3.   * @param  None
    4 F9 p# f/ J4 C, D- p
  4.   * @retval None
    6 }) y2 p0 j. P9 B: g9 T
  5.   */8 b5 p. L) R' H/ m
  6. void TIM14_IRQHandler(void)
    8 q9 b% R5 G; ^& |
  7. {
    / o( R/ ^  F1 i+ M! I2 u; O( j
  8.   HAL_TIM_IRQHandler(&Input_Handle);
    ' K5 w6 }( A2 d, L9 @3 ^
  9. }
复制代码
1 {5 M" U7 {+ T4 O% G+ y3 R
3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断9 n3 S$ W' @5 b) y1 }
7 D3 j" J& W9 h
  1. /**
    1 _. o) D% m% J9 Z6 d# ]. z
  2.   * @brief  This function handles TIM interrupts requests.
    : y1 D6 S8 k4 v& d
  3.   * @param  htim TIM  handle
    & e0 g* z& u. z/ }  G4 y' G6 L
  4.   * @retval None
    : U' {/ H& |. Q) g* I) b8 z
  5.   */7 E5 i( f+ B1 `4 e: A
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
    ( E. R. G' y& v: l& x$ [: l7 T
  7. {9 A1 [, r9 n3 n
  8.   /* Capture compare 1 event */; M8 f5 X" M$ r
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
    ) G/ T% \/ n- h- g% ?1 {
  10.   {
    " v/ j+ {, {% v& ]8 a+ ~6 e
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
    , V0 D6 B. Z' |( _& Z+ m
  12.     {' V( Z4 \8 a& z+ _! u* `
  13.       {6 T* O% |+ X8 N( `1 B+ Y6 }6 l
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);! g; C/ F6 S) `$ K% ]% H
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
    ' W- I+ {9 d# X# L2 U4 c1 J6 e

  16. , O  l& B) ?$ Z3 s+ ]) [* }; D: X
  17.         /* Input capture event */0 p* h3 d+ z/ F+ \8 ?
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
    ) u- _  u! S& y6 `' P* Y2 M
  19.         {+ [2 V0 S# ]0 e& D/ @
  20.           HAL_TIM_IC_CaptureCallback(htim);6 u6 D: x9 t2 }0 t% J3 g( N' @
  21.         }& Y4 |, J0 s( ]: h8 [
  22.         /* Output compare event */" ^' S' q0 Z* X: M
  23.         else& I2 g: _4 U+ _5 p- M3 z* S
  24.         {6 `  Z+ ]2 C! Q$ s
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);
    : F5 b7 @1 Z. v' [* B; Y
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);; p# [) j1 X$ L, z
  27.         }
    * J8 C, S1 @7 P/ R! z6 i
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;7 e' \7 S7 V( h! I
  29.       }0 p9 ]- q& K# o' o# H* I
  30.     }4 M  {6 ]0 ^$ _0 d& Z
  31.   }
    ( n+ g- U+ K* x5 H1 G% T
  32.   /* Capture compare 2 event */
    - |9 y+ ^3 H0 g
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)( |0 U1 w$ M  b( c. ~% V# K
  34.   {
    + d$ T: h4 @, |' a! c
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
    $ a; J9 }) \+ c) z# v, n
  36.     {
    7 ^" a# S- r. G
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);7 E/ A; h0 L" P9 w# a
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
      V) `% Q$ B7 n
  39.       /* Input capture event */
    # A  ?# k& j' Q8 m8 @! t( `
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)- `5 [, Q1 c$ S
  41.       {2 E# v7 X( n7 Y* j) n; v
  42.         HAL_TIM_IC_CaptureCallback(htim);
    9 q  Q7 Z$ R/ l( H
  43.       }7 _" G8 i. \- t; C9 M) _) I
  44.       /* Output compare event */
    : Z5 U4 o0 E7 W" _4 C) U6 }0 w2 s
  45.       else
      I( d- P8 ]. w; d
  46.       {
    ) B; _, q9 J& e
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);
    9 i% C  W8 U9 C4 J! V9 o
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);! q# t* ]8 d& V- B; I! s) J
  49.       }7 ?3 |$ Q) B' n* A2 v5 Y
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;! h) t- R$ C0 K  f# j( I
  51.     }
    3 N1 ]3 L/ a$ A. f, P+ S$ F% j# s
  52.   }5 [( Z) C! k5 S9 o7 _! j: o
  53.   /* Capture compare 3 event */
    # Z( S) l6 P$ i) F* e2 R
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)9 h# U& k6 b! X' }  V, k+ i
  55.   {
    0 C7 `0 y6 l9 N
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
    & f. R* K% o+ ]2 B# M, X7 B. o  l
  57.     {+ h9 I1 `8 S2 n: ~
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
    9 {. H- T) k2 Z! C
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;( h) `" ]0 D  v5 j
  60.       /* Input capture event */
    ; p" ]: g0 C& ?) N
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)9 ]' X4 t, D3 l; @. w# P4 ?% u
  62.       {
    7 l8 t; a- S, ?
  63.         HAL_TIM_IC_CaptureCallback(htim);, t) ~$ c" A+ o. X9 D; Z( S( [
  64.       }$ i1 G+ N7 y2 k3 ^+ z" F
  65.       /* Output compare event */- Q4 @9 j# l8 H% q" K% |6 O" L
  66.       else8 s) f7 W3 U7 Z; v
  67.       {3 ^# h% h0 T% D, R! K! Z, y' T
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);2 O* R$ {4 Z' G5 d; T. B
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    ' O; P0 j$ H( B4 L; t, L
  70.       }
    ' v9 V' {1 n7 h* j0 K5 c7 s/ `
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    4 Z; N2 H- r' L. r8 i& u
  72.     }
    7 ?4 q+ V5 b) _! K
  73.   }
    8 N+ \! D$ S# |+ [
  74.   /* Capture compare 4 event */
    8 I! [+ V: d! q/ ?- C# E3 o
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
    # @; R9 R, m  D
  76.   {" E; L' H# |8 w! r' |+ R# T
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)
    ! ]' ~5 B; h9 F7 i) `
  78.     {2 r( a: ^0 z7 W
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);. `& f5 G$ K  p! k7 q! F6 h0 Q8 x
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;/ T) f. O( P; g3 d  s: O
  81.       /* Input capture event */
    # p4 M6 K  S4 n3 A* b
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)+ i& b3 c  i* c$ m1 S. O( O
  83.       {3 [0 Z3 p: j+ D3 u
  84.         HAL_TIM_IC_CaptureCallback(htim);
    - ]& r% m/ y# y
  85.       }1 f6 p% }6 [+ S
  86.       /* Output compare event */- \3 t% Z$ m1 j# h1 c
  87.       else8 I9 S) o: v# D7 I1 t
  88.       {
    & G' I0 y" s9 B$ W+ u# R
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);
    4 |; X. |/ ~* n( |9 E: |
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);# H1 a+ N: ^' I% K" Q
  91.       }
    2 e" @+ V) q. p3 w
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    6 A% b: f# M3 P- b: T6 Y
  93.     }4 `* P- W/ Z- J& p. r$ X! |: ]
  94.   }6 i+ m/ Y" J2 q/ G5 g
  95.   /* TIM Update event */
    - q  K, J# U+ b# i# E/ F
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
    $ ~" ^8 w5 e4 Q: y4 I# H9 }
  97.   {4 Y# c5 q% d* |7 n
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)6 m$ F6 |# x/ c3 ?4 Q9 b
  99.     {
    8 b2 [4 e6 `+ L) M! x+ q! h/ G( t5 v
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
    4 C; t3 u3 w% I" X# K2 k
  101.       HAL_TIM_PeriodElapsedCallback(htim);
    $ @" ]! ]4 P2 A* K7 U% P: o
  102.     }
    ; o$ A+ w& F2 O
  103.   }
    & u- q' H. a6 M
  104.   /* TIM Break input event */
    # ]$ T7 P& x5 n! N% |
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)' r) @1 o# [5 g
  106.   {% J9 o! `/ x- p2 p$ Z. L
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
    % a. P. K4 t& H, ?, b! T7 ~( b
  108.     {( }( @5 V& a5 j$ e
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
      f" R: T) X& t# R' ]) t0 f
  110.       HAL_TIMEx_BreakCallback(htim);5 X1 {; U* I9 I6 J' j+ j5 t
  111.     }  T# t2 M4 T" U1 t' \
  112.   }
    $ O- T1 o1 N/ q2 O' W
  113.   /* TIM Trigger detection event */
    , j8 _) |0 {1 r# D: E1 H$ x
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
      q0 D- X: B0 x* u9 Y! I
  115.   {
    ! Q" o0 s5 j+ f; F
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
    8 V& T1 M: m* s7 j8 m, x5 C: [) W
  117.     {
    0 h2 K; n0 q6 u' M( C" m" D
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);: R6 j5 }. W. g
  119.       HAL_TIM_TriggerCallback(htim);' O, ?  ]: h# [5 u4 D0 _
  120.     }8 V6 E* U0 s, T
  121.   }$ f' c1 f4 w1 q& n; c. C( c; C
  122.   /* TIM commutation event */
    ( Q/ U/ q( L5 x% K+ o2 \
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
    5 j. k7 C9 E8 h' B) M6 Q$ O
  124.   {% a$ w/ p' X5 H) A/ {$ y
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)
    * Y! L( Z" j6 g' ]! E. }. Y1 G. N
  126.     {0 K6 l2 {$ B, H/ v: _
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
    0 i, ~0 t+ }' j" }" h0 ~2 b1 |7 g
  128.       HAL_TIMEx_CommutationCallback(htim);
    9 I8 S* N4 G$ ?- q0 t7 }9 }) E6 N9 f/ r
  129.     }' }; e6 M0 x/ u4 a" B0 b
  130.   }
    2 U0 s7 L( D7 s7 c0 _
  131. }
复制代码
: _) ?; T9 Y) M( T' Q
4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);- w: P' {# [& }% v; s4 ^2 G) h& V' }
; `: d# j! h8 G6 G) ^
5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码
    4 F* b+ p0 I( R8 ^" H! q

  2. % c) R" p4 P# P6 Q8 T8 T" H( F! x
  3. void TIM14_IRQHandler(void)7 ~/ e4 e5 Z5 J( _
  4. {
    9 q9 G8 [( h5 x# J( [
  5.   HAL_TIM_IRQHandler(&Input_Handle);
    " q) j7 [% j  g, x9 c

  6. ! S* ]! n# x: W+ S9 @6 O
  7. //其他处理代码
    9 [: F* q6 h, X* Z. T9 X: r1 ~$ K5 m
  8. }
复制代码
5 k& Q" g, r& t, j1 c
6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。& M/ N1 n/ g: _1 j7 a* L9 G

1 M( ^( c# ^# n; |7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。5 Z% ~+ S( l$ U; S
1 h. S% |0 q+ h' b0 }4 r
8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。
! h. m  m  P' y! B% i' [7 v
/ I( b& A: q; ?7 v# J+ _, z在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。
4 V4 _" z6 Q/ _0 ~
7 l, e# ?5 b) f- e5 ^; p& [% a9)ken坑啊,都怪对库的执行sh顺序不了解。
* ~5 o. X6 T: e+ b! x# R5 F
7 ~! B( z1 N9 E/ d  ?
7 l8 t7 }% s4 P" D
收藏 评论0 发布时间:2021-11-25 16:00

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版