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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn
1 ]( W+ l5 a. O1 L  A- c' @8 y0 t
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */% P* u( H: b& e# V$ Z! t1 C
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */
    0 j4 q9 q( V9 ~) N- o2 ~
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */
    0 [. z1 \! @- G1 X4 N
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */8 m( ?: N8 c- q
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */: v" ~, I0 }  g  e
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
    & v  s0 p$ \7 O5 k; ?  y3 f) Z
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */
    , c" n- N1 h) N' j/ a
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码
) W6 E( M# C0 B% _: c% k  a
2)通常每个IRQn对应一个zho中断函数9 q  M% V! g. |/ ^8 V" C% L2 a
  1. /**- ~, Y/ q$ ~0 V7 q7 f( E
  2.   * @brief  This function handles TIM14 global interrupt request.
    3 h' y* [2 n8 f$ Y! F4 [- m
  3.   * @param  None
    8 a  d' j$ m6 W, N3 p, E& _9 g$ r& |0 z
  4.   * @retval None0 R/ v: L& z" M( O: x; N6 B
  5.   */( V9 W+ @8 E) `" z! [8 x" s* Y- R
  6. void TIM14_IRQHandler(void)
    4 R  U8 L+ G: B4 \+ h. I* o9 x
  7. {
    + v9 ^' J# q1 n4 o: h
  8.   HAL_TIM_IRQHandler(&Input_Handle);
    ' C( g; J2 n+ p( S- ]
  9. }
复制代码

, ]7 D2 f( K* n1 C3 z3 r5 g3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断
; `# W( @, x! L+ [1 x8 K
4 O. N" ^+ X/ E9 A# |& ?1 {. v; D
  1. /**
    2 W. D9 p& T: \% k' t
  2.   * @brief  This function handles TIM interrupts requests.5 q7 B6 T/ [- c5 e
  3.   * @param  htim TIM  handle
    4 c. Y2 o8 N( W9 \. t6 l3 j' y
  4.   * @retval None1 n$ r1 I- w% u2 I1 ~  r& N' c
  5.   */6 T# K/ i0 s3 r
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)5 j% ]1 Z' a  N( f, q0 d( H' r
  7. {1 q5 t, U% ]% A/ s1 Z4 W1 P$ S
  8.   /* Capture compare 1 event */! a/ d; U; ?* H. |* @, n7 D2 F- I! i3 U) n
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)) g: \) ]" H9 Y: @+ L' z) I( B6 o# m/ u
  10.   {
    3 b0 h$ w' e- j4 ]0 |
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)/ u+ A0 e% i) |# i
  12.     {( k, I/ i, L- {
  13.       {5 \) y' y8 J) F" n% x3 X+ o
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);; H  P9 [, H6 w, O
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;0 ~4 Y/ N8 \6 ^+ U2 ^
  16. & S8 Y+ t$ ~( @
  17.         /* Input capture event */
    5 \6 z2 x3 j& o) S* E, W
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)3 ]& V$ A6 }' V$ c8 ]) l" J
  19.         {
    / f6 M% w2 {. d# {) `2 K2 F
  20.           HAL_TIM_IC_CaptureCallback(htim);7 X+ y& l: K# O- \  K; z
  21.         }4 Q: J, J8 u4 l+ o
  22.         /* Output compare event */
    2 U5 N9 _& ]& x3 \$ f  ]  {
  23.         else, c$ K7 a$ j+ {5 l
  24.         {* H  P3 f  [, l& S2 A1 c
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);
    1 c% a) S# Y0 N' M6 Q
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);
    : w& d4 x! M: N& _8 X
  27.         }/ V4 k7 i4 \& e5 |7 N; ^2 g
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;+ `9 [  y* [, `0 o) }! D7 C" r
  29.       }
    + J0 g% x: K0 L$ a
  30.     }
    ! r7 H7 z5 S2 ]$ a1 |4 g. B* y
  31.   }5 ?4 A$ C# G* I- Y7 _5 b) }
  32.   /* Capture compare 2 event */
    3 b) L: ~; t7 [. ?; v  x% q" ]
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
    9 d+ d: j' {- E; S. p  @1 g! r
  34.   {/ U+ [9 a: x# F9 u" F+ r: \9 A
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)" f% W# Q7 z  i0 B) T3 d
  36.     {! {  F  D* z. t$ F: D1 o8 B
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
    6 S: @9 Z2 ]* C4 C
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
    " U/ m: J% a; g$ W. i9 r. o
  39.       /* Input capture event */: u# V/ u+ [$ K) N7 f
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)5 J) V, y5 g3 O6 v$ h4 {: U
  41.       {
    ; \0 R. N+ b& I$ P; X/ Q( m
  42.         HAL_TIM_IC_CaptureCallback(htim);. n! t  K9 w  P# S/ f" d
  43.       }6 Z+ C+ ^! C- E2 c, u6 o. n/ o
  44.       /* Output compare event */' x! W& ]& a& j" U
  45.       else
    0 N, R* w6 w% `1 t) r! p4 n
  46.       {) u5 N+ s- Y, W; Q' z6 A" w
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);! S$ d, L: A+ k( T" H' U
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);$ P# T( w3 d2 t0 v
  49.       }5 G- ]# a4 c9 X$ v, o6 U
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    ( v! z, R1 S. p( t& Q, p5 f
  51.     }, Y& F/ P8 X  P$ w9 x( n
  52.   }# ^1 P+ q7 {7 e, ^5 e
  53.   /* Capture compare 3 event */
    - K: c* T& _0 g& H+ P" V
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
    4 W% q% \9 V/ M3 y
  55.   {
    7 }' @% Q& O" h' b2 r
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)8 ^  k8 \+ X+ ?! `9 B: i, q* e6 \
  57.     {  f3 |  ]- o, X& ]+ Z( O
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
    ) s" D4 l" L3 D0 H" q/ ]
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
    / F9 t6 q$ D7 J! B' n8 R0 {
  60.       /* Input capture event */6 [; C6 ~" o  g5 C* Y8 A8 o/ c. v3 @' P4 i
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
    8 \/ q1 K+ P& ^" Y* S6 S
  62.       {
    5 J0 j) J/ V) D
  63.         HAL_TIM_IC_CaptureCallback(htim);9 q  L, t. E4 M& ^( b4 W' h" _( M
  64.       }1 c  |2 ^: f" I. n  Y+ H
  65.       /* Output compare event */
    6 G0 ?5 o  z; n/ D3 T; ]
  66.       else
    * l  N) ^) w, t3 H! M
  67.       {! |+ u2 w+ W* F5 ^' B; h# P, D% c
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);
    " _5 }& J8 `+ c0 n$ V6 L( c
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);' a8 N% Q' E# e: d: m
  70.       }
    ; E- y1 y, `/ G, w" k
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;1 j% n2 U# O" {) K
  72.     }) e/ ?9 h9 T$ }8 A$ c4 \+ V7 C8 P
  73.   }
    ' K  v3 g; b, `6 I
  74.   /* Capture compare 4 event */% T1 w, O( _! t% c. H( w. Y
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
    + f2 o; D: @  ~% V' n
  76.   {
    ( D1 J. w1 T! ]- b! E" C+ n8 {
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)4 ^; k. i4 G8 G  O# r% R2 v8 A
  78.     {/ _8 Y2 ^5 U# a# [) U
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
    3 E& r* }  p3 A& \2 `/ O
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;  k+ O8 O; q/ E. z! O7 D
  81.       /* Input capture event */
    . Q& {8 \* _/ U5 |/ j5 _
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
    & M$ @. l5 l2 |/ Q- O3 @
  83.       {" e& b8 E& z1 i0 }0 E4 n
  84.         HAL_TIM_IC_CaptureCallback(htim);1 ?. O( _6 \5 I) v- Q
  85.       }' c: U- i" g- f- {3 m; \
  86.       /* Output compare event */
    " z% @' q. E; ?
  87.       else8 P0 ~% y6 c/ x
  88.       {
    ! ]) ?+ u6 u  a. `
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);% H$ k6 D/ `3 L8 w7 U
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);; R7 _; S9 c- Y, w$ h) z, L8 ^
  91.       }
    # ]: p3 L0 N! R! ^8 ^
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    , W: ]$ c6 G6 m; X( \
  93.     }6 i0 v  s4 m$ q2 e
  94.   }" e2 ^/ l( I( S1 O4 \$ n) R  \
  95.   /* TIM Update event */* z1 d. v& J4 S& E. Y3 I, H
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)3 d" L0 E" f9 k5 t6 W' b
  97.   {. A9 P; p$ G$ ^9 W( E; e4 j$ Q
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET). [1 U0 O% y0 h& I& _$ @
  99.     {  W$ t6 X# H$ K2 Q
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
    " N6 w, h! [% G/ m7 t/ P
  101.       HAL_TIM_PeriodElapsedCallback(htim);
    * q/ Q& T) K* j: i( G8 h9 G5 b+ j
  102.     }: S6 q# a- ~( z) ]6 }0 @* d0 ?- A
  103.   }
    % C+ a5 ~8 I$ y  L: o0 f
  104.   /* TIM Break input event */
    ! w( Z# p$ U/ [# W  Q
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)4 k: C7 r+ W, l# k7 k* y2 c; z
  106.   {2 B0 j7 ]8 Z% G: b: v3 E5 V
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
    ' R* U' A( q3 f7 Y+ }3 V
  108.     {- e: M4 @2 d1 i, J
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);2 r5 b  \3 E  D9 {# \$ m& r: c
  110.       HAL_TIMEx_BreakCallback(htim);
    2 n$ k# a" v0 h8 b6 h; P) d
  111.     }6 g6 `7 b+ G) P: t3 q9 d
  112.   }4 t" Z/ W$ h, M, H
  113.   /* TIM Trigger detection event */
    3 P" Y! D( ], F" a2 S: X5 F
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)( \3 G+ p  W! _0 X; ^8 l
  115.   {
    , @# z' I: d7 }5 u! [1 _1 r
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
    ' F6 o$ d8 y: J: Y3 k: ]0 {1 e
  117.     {( m  m: S/ C) W$ ?  P8 a
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
    2 R; ]& t4 T% O+ n% ]0 o
  119.       HAL_TIM_TriggerCallback(htim);
    5 G( \+ v% P/ \1 k5 o6 _4 M
  120.     }
    & i) E& j3 {! u5 q) R2 K0 a
  121.   }
    $ G1 Q% Z' D( f
  122.   /* TIM commutation event */
    ( g: |& c. d' k. h
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)( X' |( c+ L4 r% A3 D% ^8 i/ {
  124.   {# t! J% a# }  k
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)6 x9 ]4 a2 w5 d! I
  126.     {( K8 t" z4 L. k" q7 J# o& b+ H* m
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
      ?4 t( P5 z: m8 D  g* H$ ?
  128.       HAL_TIMEx_CommutationCallback(htim);! i5 l: r  G7 E  T3 U( n
  129.     }; O' R6 y9 R. \* O# s7 ?
  130.   }
    . ~; u* U& x+ A0 s8 w2 c
  131. }
复制代码
9 Y0 z1 J; H# }5 z, |: V6 d' `  [, P: D
4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);3 |8 ^  ~7 X. _' ]( p5 J

# ~$ B4 n* x1 k2 d* m5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码
    # @! B( m3 z0 {) o) N; D" c; X
  2. ! E8 |1 W& j% P  |$ l) `
  3. void TIM14_IRQHandler(void)
    * M; G; t8 ]9 f' r+ H' k
  4. { & f5 q! E2 G9 n6 ?
  5.   HAL_TIM_IRQHandler(&Input_Handle);
    4 q4 `1 ~# r# R; f/ z/ a4 p$ q

  6. ; ^2 P* T. L; C& X3 k- i: I
  7. //其他处理代码& d+ u. C1 o( K. a9 T. V3 `
  8. }
复制代码
. d  V* |5 J0 o5 f; M2 O% W
6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。" c3 _: s# p( @6 Y. b

8 f. [4 N7 F: D' c$ W7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。) P( J1 Q+ }" F: H9 T# r& i
; f; t5 c( I$ ?2 n' Y, T3 x2 [
8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。3 S3 |' A( g# b" o4 f& q

2 v' X/ r3 W: }; J0 ~在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。
( [- c+ r; ^/ }4 b# y* X' C, _) w8 q# X4 y2 h( ^: M$ q" w) K
9)ken坑啊,都怪对库的执行sh顺序不了解。7 b0 d+ n1 O2 {, \+ R. d

$ A2 j: i. V% ^$ o
  o( N! S3 i, K  m# `
赞 收藏 评论0 发布时间:2021-11-25 16:00

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版