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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn$ |( m+ u! }. j/ T7 _1 X
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */
    8 A: x0 p- V( Z# z8 D% [
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */0 T# C% R& o8 e( D  |+ P
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */8 M8 N8 F' C9 d& H' F" C
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */
    " R: R3 R8 r/ x8 z0 X3 E, N
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */
    . [! |5 e, T% f
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
    & U1 C# \0 ^6 y# K# @/ w
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */) j7 d  G+ b; _" l9 t
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码
6 w# s/ t7 y! W: v/ H
2)通常每个IRQn对应一个zho中断函数
/ g4 C* r) X' m# u. U1 [
  1. /**8 H. s! h( x4 R
  2.   * @brief  This function handles TIM14 global interrupt request.
    ' g6 ^) p% k' R
  3.   * @param  None
    2 d: v& _4 S, d# @* \
  4.   * @retval None1 Z, W' X9 H' d9 S, K6 w
  5.   */
    + A  H( }( l0 _- p' T
  6. void TIM14_IRQHandler(void)
    - v- O5 t9 _" Z( a& T' X4 X
  7. {
    , u) l2 J$ s5 h
  8.   HAL_TIM_IRQHandler(&Input_Handle);
    & M1 a9 h9 E" L7 L
  9. }
复制代码

9 @' b6 [/ J& c3 }" a3 [: V3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断/ `0 Y7 U( ^' H

! q9 \# C2 O, \1 @
  1. /**3 p! d1 Z: X% m  D. _* P; j
  2.   * @brief  This function handles TIM interrupts requests.
    1 t3 Z* c1 ]; q8 ^9 X) R
  3.   * @param  htim TIM  handle
    & d- @+ L/ A8 ?7 G+ I# B. H% Y
  4.   * @retval None
    " {6 M" m7 ?8 L' }- x& \
  5.   */( q7 j' @" A! h" V6 a3 S
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)" K$ `* l# m$ ^- Z9 x7 f
  7. {- g3 N; [% S" y% e
  8.   /* Capture compare 1 event */
    . T( E! k% L. \' n) F. Y
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)3 B: q$ S; O$ k' W* W
  10.   {( r& ]6 U  v3 _
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
    3 I  N3 I* P; ~
  12.     {
    3 C+ G6 k% v7 t' T3 z2 I
  13.       {9 X2 z: i% F$ W/ }2 J: Q
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
    9 ~0 J# F' ~' `; I# m
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
    ' Q, e8 W' g7 }! s) j4 |: K

  16. ' o5 R( d% R+ u- a, Y5 ~
  17.         /* Input capture event */4 z* g3 p3 d6 P$ c, h$ R. \  e. G
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
    3 g* B+ A6 C- |- c* I0 o4 h" }3 }
  19.         {* h+ t$ G, Z0 |6 u, N
  20.           HAL_TIM_IC_CaptureCallback(htim);+ F1 d. q9 I+ D9 v' t' ^/ G+ o4 i
  21.         }
    * N5 {# G3 n* ^
  22.         /* Output compare event */; q1 a1 a( |2 D' ~: a/ |
  23.         else
    : O; s8 z/ L0 K
  24.         {3 g- z3 ~: o1 C$ A, \8 Q$ \
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);$ m; F; A4 U% z  U0 |
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);& _" w' U, E5 T4 ], Y. c6 O! J
  27.         }  m/ S4 ]; i1 g( W9 e) n: z
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    2 |9 z! j; ?) S! [$ O. t$ d8 n0 Q/ l
  29.       }) d4 k3 B/ ~0 {; h3 O( T
  30.     }
    ; _( K0 {, G/ x4 c* m# \2 ^0 B
  31.   }% F. N1 n6 M. v1 B; N9 e% L
  32.   /* Capture compare 2 event */
    4 l2 X2 o' _$ Y6 Y9 E
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)4 r- V% T6 ?8 W. N
  34.   {
      l& ]3 i3 o, a( i; G
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
      Z; L9 N0 q. P2 |( M
  36.     {
      E( B5 k+ D  K6 d
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
    7 o1 z# J: F+ d+ P( P
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
    9 Z; ]3 l& Y& a6 T5 i) j
  39.       /* Input capture event */
    . y- @1 D4 W' S) @/ K
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)( d: j  l4 k  _( y$ Q. W* E
  41.       {- M7 k, [3 g/ f* f) r
  42.         HAL_TIM_IC_CaptureCallback(htim);. Z7 @$ D) \8 D5 }6 {, M
  43.       }
    6 e7 U  @6 a$ e$ i; g: {  K7 [
  44.       /* Output compare event */
    . n8 g  p( f. M$ F; s& N
  45.       else
    ; c3 p/ _" W1 I
  46.       {
    # ]4 I$ j0 t. y" A3 `$ ], r
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);0 e5 I' h( C3 q" B3 s7 m, z/ b, Q
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);9 X4 E. v9 ?+ ~
  49.       }
    . n; r9 |) }  G' e$ Q2 U
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    ; |+ t( }, t) Z2 T, {) ~% q
  51.     }6 r( g* t4 I' D! L. S  \
  52.   }% k" S' [4 M' ~3 [' J, K4 P/ Y
  53.   /* Capture compare 3 event */$ l; ~; |& Q$ |( h. @4 a
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
    1 q8 V7 k2 m9 N  M- P( ~
  55.   {' p9 }4 y. Q/ F, d+ ^; x
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)8 c* N5 f9 Z- F+ X  E) D
  57.     {0 i- j$ [- B2 r
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);, [7 S6 k5 X& U8 r6 u2 M: ^# `
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;* F7 C, E6 i& s- t: q: ?  L4 h5 T
  60.       /* Input capture event */
    % _) t0 u9 U; v
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)) Z7 d- |6 K* M$ s: s
  62.       {7 U1 r- L' i3 }5 }
  63.         HAL_TIM_IC_CaptureCallback(htim);
    - r+ M! @8 A3 \: E
  64.       }' S- X8 }$ g% p* r& g
  65.       /* Output compare event */
    9 q0 B- R$ @& H$ t
  66.       else- h4 {$ N% E9 Q6 Y
  67.       {
    : l- I9 E' J  l: t
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);
    % E. f. f& ^3 _2 a
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);& T) s6 W. g& l, [. ?2 A
  70.       }0 p+ i0 {% t7 y
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    1 ^* ?2 Z8 T/ |* M
  72.     }5 S" x4 x+ T. i7 C% T" J5 x! e: G
  73.   }
    - z3 t# |# _& E$ i( {
  74.   /* Capture compare 4 event */0 N6 k  ~& t; F) j
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
    # Z% i- Z% V/ r8 o0 v! ~$ H- v: m# d
  76.   {! ~3 r- o7 t9 ~$ |
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)- X) d2 q3 d+ `* s3 m
  78.     {* g. M0 z4 _  ?9 p% E/ `) H1 k  p
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);8 x/ u1 e- Z/ o, l  {. N
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;" |9 I+ h- `* h
  81.       /* Input capture event */
    : L; O& P" S3 e3 j" N  P
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
    8 R6 O- F, v" ]' G& }/ G3 u
  83.       {
    , u# Y% k3 d3 q" j% \  Q2 }) b% K
  84.         HAL_TIM_IC_CaptureCallback(htim);5 U  Q5 d$ `2 e& p% h" c/ z' d
  85.       }( k  R* ?6 t2 N, Q/ a
  86.       /* Output compare event */
    - m8 @5 d& A# e# Y) R/ I
  87.       else. ~( n- W' A0 K1 |9 S' g: S
  88.       {
    3 l1 F8 T% }/ Q
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);' d" l& Q+ Q1 @4 p
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    ' p5 \) @, |# e  u
  91.       }
    ! G2 {( U6 D$ O% d0 ]+ [
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    ' {8 s3 E. i* O8 f3 ?1 p
  93.     }
    . e1 g( O; h3 V7 w" T
  94.   }% g3 G' J7 {) ~. J
  95.   /* TIM Update event */
    # i1 D) X7 n) O
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)0 y  t7 Y) O  F2 i) R/ ^% h: \& Q
  97.   {! h# D. [- `% L: ^0 X* O
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
    3 d$ K4 A/ K( Y# |. c9 }
  99.     {' m5 d: n8 |& ]
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);, F& z4 N& ]" q* u5 J
  101.       HAL_TIM_PeriodElapsedCallback(htim);
    + Y2 [- U, L3 A7 m: b+ \
  102.     }
    , Q: m% J# n: d/ m
  103.   }, q) d/ t2 L7 o( d3 e5 n" d7 k
  104.   /* TIM Break input event */0 d% Q' F# P( _3 \$ Y3 @
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
    . A6 L3 W1 v1 Y3 Y- S$ [3 q1 ?: [
  106.   {6 c/ ]- g' W$ ~, z, r# C
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET), p: {6 R) t; z' p& ^! r/ x
  108.     {  s2 ^& i! i+ c2 j. T- I) x
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
    ! t" ^' k1 x9 E
  110.       HAL_TIMEx_BreakCallback(htim);
    . }& q0 z! u3 s) @4 t$ a' }
  111.     }
    ) u: e) Y, P6 l  t4 G& ^: a" H
  112.   }2 x! \# D, u! o% S0 V
  113.   /* TIM Trigger detection event */
    8 \; q; ?: O( D
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
    $ x, ]) i8 a& r+ B; W
  115.   {( |, x9 Q& @, _* _2 Z! L
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
    5 w' E0 }3 @5 W$ k  M4 d0 [
  117.     {
    , r1 y: e# a3 }" x" R. R
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);" O6 d5 `: t5 t2 ^5 E5 ?# e3 X
  119.       HAL_TIM_TriggerCallback(htim);: q7 D* p  x( e( T9 m
  120.     }
    ( a# i, A6 s) _" M2 d4 I
  121.   }, M( V) |. Q# R4 U9 x
  122.   /* TIM commutation event */
    1 V! \+ L2 C. S& N' h/ g0 K
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET); R7 w* Z! \. p' z# h: i  n
  124.   {7 v8 G& v) Q2 `# t! U/ [2 P# C5 \
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)# e+ f5 U; W8 v! J
  126.     {/ r% [6 E) z0 H$ ^1 o2 S. t" Y2 Q# m
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
    . V$ t+ g* v! F. |& V
  128.       HAL_TIMEx_CommutationCallback(htim);
    1 t4 t. b4 E- s6 `$ y
  129.     }# B) u8 \* e1 X' W: X$ C! _
  130.   }
    9 N/ h. q2 R3 @4 k- z2 m
  131. }
复制代码

) @% P  P' \5 T0 m4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);
, J, ]( {$ @6 ]" k! s8 o$ Q
1 G- A+ H2 F$ z) M$ a8 j5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码$ d. i% X# \" Y6 ~* [7 }2 o6 K

  2. 4 o; m( y6 ]( c; y' @
  3. void TIM14_IRQHandler(void)3 r1 A& ?' N' J# A5 o
  4. {   r8 q' P% d; i
  5.   HAL_TIM_IRQHandler(&Input_Handle);+ w7 X$ y3 ?" Z6 [$ S
  6. - @9 v, F1 D9 P7 x- s) u# p/ `
  7. //其他处理代码
    ; e4 J' C( v! `/ ?
  8. }
复制代码
7 ^5 I: a- G7 i5 c  L0 q
6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。
5 m( V8 O+ q6 b  K/ r- ~) C* t7 g9 e3 b7 f/ O, C
7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。& X* ]! u+ h  ^2 Q) h( T
* L: }2 z% v1 F, k+ ^- O
8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。
; o& r' j! P. T; @% k; W' k* Y
* O0 [4 ^" ?# \' i在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。
7 Z/ I4 `$ u1 h& w6 J0 @& A* c9 P, }( Z
9)ken坑啊,都怪对库的执行sh顺序不了解。
7 h, j2 Q% k5 P* B+ i' H/ s+ d8 p5 X  V6 k
  J3 a0 s5 b! B) D
收藏 评论0 发布时间:2021-11-25 16:00

举报

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