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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn
+ d6 [; _/ [1 q% N2 C! I" \3 x
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */; D  q3 g6 B1 K& i# I8 J8 I
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */
    7 {' ~& i& d* |; l" p
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */
    3 [6 Z3 A: |" V$ @! K
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */7 E) L0 r4 W2 ]& g
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */
    2 }1 N! Z% I9 w/ ?5 U' m
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
    & `. W  T6 ~# A! }( D( G
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */: R. q( j" m9 u4 l6 r% @" q
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码

3 t6 Q# E  ?. ~$ F2)通常每个IRQn对应一个zho中断函数
3 }! L7 @# M; b" E% D- t
  1. /**/ D  o( c& P8 v5 u8 j6 W
  2.   * @brief  This function handles TIM14 global interrupt request.. T: j4 V, e) d( W# A" o1 r
  3.   * @param  None' ~# |& q- l* K# j% i& M0 B
  4.   * @retval None: e* `/ a# F; y9 c  r6 g) u
  5.   */
    3 a' G! W. p/ t
  6. void TIM14_IRQHandler(void)8 {6 a, N5 K5 A8 v7 B
  7. {
    ; c( y2 r3 ~, F" }; k! `7 A
  8.   HAL_TIM_IRQHandler(&Input_Handle);
    7 k; H( U* e; e) _1 b
  9. }
复制代码
0 A* r0 e  m- ~6 I
3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断
% e  i/ Y! E9 g. r. Z
2 ~2 S" V# e' Y' \/ m7 u
  1. /**% A2 ~' w2 w* U" R! ^
  2.   * @brief  This function handles TIM interrupts requests.* b0 b' F* A( y0 J
  3.   * @param  htim TIM  handle
    ) v$ T4 x# m8 m  |( Y+ w) C& s- _
  4.   * @retval None, V( T* K" ?, p9 [$ P8 z" Z
  5.   */5 f% Z! g# \( C  F* a
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
    & F( h% z+ _& k& O
  7. {
    6 }  S+ g) |& t) b# X
  8.   /* Capture compare 1 event */
    + W$ @3 p9 B7 d5 A5 \7 h- Q
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
    3 I4 K5 p/ O# K1 r% i: [
  10.   {
    - W( }1 d" m' D
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)/ q/ m) p+ O5 K! O3 p2 w  p( }% f/ @
  12.     {
    9 R; _& {" i0 r- V0 K
  13.       {
      m0 h$ x3 J# S( M8 T' g
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);/ Y( a& b+ U$ U! r! O& H' g
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
    ! F1 u( s" C, J# V3 W

  16. 1 w5 O: \  k  Q; ^2 w# w
  17.         /* Input capture event */
    , Y! Q. e: Y" n: S$ ^/ B
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
    & o4 b  M/ @! C  c8 t7 S0 B  ~
  19.         {: J7 i( q4 ^  y( o" n4 f
  20.           HAL_TIM_IC_CaptureCallback(htim);7 `$ h, @2 H: k& O( T
  21.         }
    ( o8 e: ]; a/ S' W$ F
  22.         /* Output compare event */
    ( l9 Q# Q  L1 Z2 O  S* l
  23.         else
    2 C5 ]9 v+ Q8 S! w. C
  24.         {
    7 }5 A0 |/ l: }4 f7 h0 |" \
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);$ W# g6 _0 c' G8 J; ?: s' ]' O
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);; e4 |1 b2 F* `/ q) v1 p
  27.         }
    + m5 {$ V+ l( R/ n0 ^7 Y
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    # l3 D5 i3 J* S8 @
  29.       }
    & q8 l, J# \  Y1 V! R
  30.     }
    : w2 D. H0 g  |  J3 I: h
  31.   }8 P* U( y2 w) h
  32.   /* Capture compare 2 event */2 A; D0 `8 m, V- c
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
    ; Y! W( N/ s" m  m# m' i
  34.   {
    2 P: L! F9 D/ }  W. u7 y
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
      q- u3 [! f' h5 Q
  36.     {
    1 b* r3 N  J, b5 Q
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);' E0 C- y3 ^8 `9 r
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
    & P/ B' s* o! n6 k: a' z
  39.       /* Input capture event */7 f6 k! A& [2 @) f! f4 y% |
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
    ! `# e& p5 V# }9 R/ A4 c
  41.       {7 H4 t! Q8 l& ]3 a* o' F
  42.         HAL_TIM_IC_CaptureCallback(htim);$ I( {2 J8 f4 m
  43.       }0 D% Y: n! A; O5 O  s
  44.       /* Output compare event */
    , D! |1 h5 o" o: \! i
  45.       else. @4 E( b  F/ p
  46.       {
    4 {- n, G( D' n; L
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);
    . }: _% }3 D: U/ M
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    3 J6 D8 }: ~: j# T+ _" e
  49.       }4 D% N! |6 O# Q1 l9 r# e+ d) B7 w
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;* P7 T* o, W, I8 I+ o: q' ]
  51.     }
    ( p2 R4 x" A0 C1 i5 }% V
  52.   }+ b$ {$ Y) O5 D  I
  53.   /* Capture compare 3 event */
    ) W. }& h* C: ^, b1 u+ F3 W% }
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)4 z, N; \! h0 k
  55.   {+ z6 w2 _& t# I$ i9 X
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
    9 H; F. L' d  e/ n
  57.     {
    + ~; i0 }8 A3 k4 h
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
    ! p# s3 w& K2 R) n* F
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
    ( O2 B( z% `) D0 I) i1 g# q
  60.       /* Input capture event */# X4 q% N) r& q# }6 Q3 A4 P2 [
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
    ' l+ y5 g9 ?) K. T# ^2 p+ u% v$ S5 T0 R* ]
  62.       {9 T; Z0 c6 U/ O6 r$ K7 K# C
  63.         HAL_TIM_IC_CaptureCallback(htim);3 c& V3 f# M) A% g8 P' C8 Y4 W
  64.       }
    & E" \" b. u5 S  m
  65.       /* Output compare event */
    " e1 X1 J$ f2 J& c$ {5 J! }
  66.       else
    1 `/ a' H; O2 s6 ~; T$ k& ?
  67.       {* Q5 J8 ?8 I0 y4 v$ F5 B
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);& i1 F1 \+ a( j; A) T0 h
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    ! |0 E$ p) ~" |# {1 d: C# t: ?: |
  70.       }3 s4 [& I  E5 g! R
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    & e  c5 }' c! Z! C9 Z4 e
  72.     }5 h9 Q( w% r/ f. G3 \0 |" t7 B
  73.   }4 d+ Y! m0 f9 g2 [# `8 I
  74.   /* Capture compare 4 event */
    : J- S0 R( C* |. _1 @. _
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
    4 ]+ e' ?+ w, x
  76.   {* ^" q* f. c$ D* ^6 V
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)
    1 Y: M* r5 C6 L5 @' y: t' T! E
  78.     {
    9 r. W3 F( x  g% B9 R6 D3 L
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
    * T/ ]# x2 M* w" \3 B$ V
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;0 {4 Y/ g' h+ I7 i6 m4 e) k+ z4 X6 H
  81.       /* Input capture event */7 A8 A  z3 P( ]& O$ S, e
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
    ( S8 Q3 Q' G8 N2 ~" B6 ?- `- C! p2 ^
  83.       {4 }& n8 j9 D2 c7 N+ p
  84.         HAL_TIM_IC_CaptureCallback(htim);
    # B, ^; [# |2 S7 G$ I
  85.       }, T& @* o: E) J, p6 v/ W7 F& K
  86.       /* Output compare event */7 S, ~5 C. I9 F4 t7 E! [
  87.       else' J  L. N. F; V
  88.       {* N2 \3 l5 _/ j8 U. K( F
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);
    / q; w/ {/ A3 q: o' ^
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);" q. `8 o3 {5 y! p/ `
  91.       }
      u! C& {3 L3 M1 A/ _4 H% z! A5 o' I
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    + {- |' L/ y; M  @/ P4 N0 |% o
  93.     }1 z9 H! v  N# e' _3 Z: h
  94.   }
    / [' P8 k# Q% F" i8 ]" X
  95.   /* TIM Update event */" M/ h3 p: d3 N' M2 [. K
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)5 r! a* ]8 @* x- x
  97.   {0 ]5 j% W% L& A9 {+ R6 A
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)8 j- v+ Y9 k- x7 B& x
  99.     {+ D5 \! ?; h9 W  |
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);% [8 m7 q9 J) K1 F
  101.       HAL_TIM_PeriodElapsedCallback(htim);
    $ u' ^7 u: ^2 v) v2 h  L! L  W, X
  102.     }
    8 {+ m! v* f0 I5 ~' M6 A/ D
  103.   }
    # A' q5 ]' s: B  q
  104.   /* TIM Break input event */
    9 S3 `7 U- ^  p0 d& S
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
    , x4 J7 x1 a0 x2 m( x
  106.   {
    0 G1 \1 b" V* ?& r3 A
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
    % b; U4 ^/ [4 Q" X. D
  108.     {4 g1 g4 S  T6 n( k
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);5 |. U1 `: a! Y8 t2 I9 J3 }
  110.       HAL_TIMEx_BreakCallback(htim);7 a6 o5 X, B' r# T3 h
  111.     }
    / d3 F4 ^! x8 E
  112.   }
    % Y) F9 V6 F2 [$ k  a
  113.   /* TIM Trigger detection event */! k$ |4 S: H& ]8 ^. f, X
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)) _8 H0 [% l2 w* Z4 q
  115.   {+ h6 z0 P- ]) Z% i2 j7 V7 E. l
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
    ) [  _* T5 l' m0 r- v
  117.     {
    ' H4 Z! b) x0 |7 ~( b$ j
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);4 C" c' \# S, _# Q
  119.       HAL_TIM_TriggerCallback(htim);
      t8 G( A8 _# k' j
  120.     }
    / n3 ]+ D/ ?7 d7 d/ n
  121.   }
    6 I5 c" F3 N. t; b
  122.   /* TIM commutation event */
    / L6 z" F3 X( }0 X7 s
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)# \. e8 F. K) T: @1 N# c+ N9 R
  124.   {
      ?) b4 g# |( k5 G
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)
    * B& R7 F- g4 Q8 m' l
  126.     {
    4 |7 P) x4 _+ m' t2 \, N/ v: E9 w
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
    ) Y( g. c- p# Q$ w3 J2 L, i
  128.       HAL_TIMEx_CommutationCallback(htim);
      P3 V3 k- c- I/ S  U/ X6 [
  129.     }8 R0 \9 \6 n& k3 M. S/ g
  130.   }4 {( H. X& N8 @( {4 Z
  131. }
复制代码
' t3 R. E, r& W, f2 R) {
4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);/ r  S6 V. s' a/ o$ [
8 b: F+ z. M* n3 r- z9 I' Z
5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码! n) W9 p0 d5 e& F+ W) D; {9 O
  2.   U1 a' h3 y, y
  3. void TIM14_IRQHandler(void)
    ! B4 l: p1 R6 r& S8 w8 [, c- N! B! D! d
  4. { ( i, y+ ]" c- U, ]8 X+ ]
  5.   HAL_TIM_IRQHandler(&Input_Handle);
    / @! l' E7 G* J

  6. " P' ]6 Z( W# J" |# U
  7. //其他处理代码/ a. ]+ @7 m7 u2 V7 L0 `: M
  8. }
复制代码
8 C% V: D4 S0 J: W* X5 F
6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。' l& Z' V+ K4 w. ?
8 f: \; @7 R2 }; m
7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。. s9 E: l; B- J% R/ P6 |! @
  O" K5 [, R2 J- Z' t8 |# s
8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。8 o2 e' ]4 d1 y  }2 b3 v- Z

6 ~, t9 I8 E: B2 [在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。
/ V! m" i3 P) E, T2 t! e) I8 D3 l' a& N1 k
9)ken坑啊,都怪对库的执行sh顺序不了解。6 u% E) v# E7 X* \: D$ t

* ~6 A: c5 A1 t9 z* o  X# e- z) n3 i; f, q, Z$ p) k
收藏 评论0 发布时间:2021-11-25 16:00

举报

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