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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn3 [5 r  L  ]% ^) Z
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */
    3 A" y1 L4 F9 b# H- |  ~
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */9 F" Z+ E$ {6 g  d4 M
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */3 Z8 L! _# M. ]( Z' D: Y, J4 ~: c
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */
    5 c9 v7 F8 J# O5 [+ A) i% }2 O8 z
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */; b$ J# K* G9 J+ Z; ?( @3 w
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
      R% i& Q' B$ z2 K9 F
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */
    2 T1 C' m$ D- B7 `
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码

3 q) |3 [2 V- p7 E. v2)通常每个IRQn对应一个zho中断函数/ ^, V: ?- l6 Q6 S& @+ k2 U
  1. /**
    5 D! V9 `7 @" I( ~% ?! b
  2.   * @brief  This function handles TIM14 global interrupt request.
    2 S0 f2 V' [2 h4 {0 y- @+ `: y
  3.   * @param  None
    8 b+ S. u! ]( k  X0 `
  4.   * @retval None' i  c0 Q7 |4 V
  5.   */1 }& L0 [1 Q! z
  6. void TIM14_IRQHandler(void)& c& z2 i; G8 @. n; a4 t' f6 ?# e9 G
  7. {
    & J! |) K, I% I
  8.   HAL_TIM_IRQHandler(&Input_Handle);
    / ?0 V3 Y# N$ r. V" [
  9. }
复制代码
0 v) W9 \+ X' i+ C9 m5 c
3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断
! E: S* u+ r. v2 Q- h
6 G% b' g* |" O. o2 K2 V* c
  1. /**
    . |% v0 h2 T+ D4 l, @' H) w
  2.   * @brief  This function handles TIM interrupts requests.
    0 q4 ]  q! ]2 l! I0 E4 U
  3.   * @param  htim TIM  handle, F0 {$ s3 o- l# d7 r
  4.   * @retval None
    & M( g; A5 l( h5 r& b
  5.   *// r0 J9 H! t) N
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
    6 o! Y6 _5 k: ~& a; H
  7. {
    2 d: R; P3 I( ]) g4 [% G
  8.   /* Capture compare 1 event */6 _* b: E2 X% ~( p
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)9 v8 m' d) P& `( f1 s2 v4 w
  10.   {9 Z, ^0 z8 Z3 ]9 H" v' i3 a
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)7 N& o2 x: Q8 q" |
  12.     {
    1 `! d2 {9 g$ y* t/ J  y8 Y8 q
  13.       {1 V- j0 s  y/ Y' ~
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);+ r( O& F# o5 H, F% u9 H' O
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
    : c; ?1 |  K6 _7 I
  16. & Y- f: p) k+ i) Z- r$ o
  17.         /* Input capture event */# O, A/ w1 Q% J+ E+ i, u* H
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)3 ^& G1 h/ B: r$ t, Y
  19.         {
    9 h! h1 _1 r0 U% x& u
  20.           HAL_TIM_IC_CaptureCallback(htim);" j& F2 P5 R, @5 i
  21.         }
    3 R2 c: Z9 f& C* w3 ^/ B2 l
  22.         /* Output compare event */
    6 c, f$ E! ?8 S+ v. ]
  23.         else
    ' n. H# ~7 w4 X* V) m+ d% z; N2 r2 {8 n* ?  i
  24.         {% j6 Z; V$ o/ U0 N5 g3 m- T
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);6 H2 j* J3 K  `& e
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);& t( O- p: S1 V& D7 V# l7 T% m1 U' o
  27.         }  u! u0 I+ R$ t" t2 s  w
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    $ \# R& x. I/ P
  29.       }- K* j& b. \' U; {% ]- x# q
  30.     }+ T0 e5 J0 O5 b# e4 [
  31.   }
    ( e& O. k7 `2 Z' u# g3 U% p+ L; J
  32.   /* Capture compare 2 event */) X% _: `6 p  I8 u5 L6 _
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
    & N/ {0 `& \1 T9 @% b# t
  34.   {. Z) s' c" ?# T: i4 K
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)" ?$ n, c% X! Y" v0 t, I
  36.     {
    ; ~- `$ d- X( Q: y2 k# g/ c- c1 V
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);6 O" f* t  r' V4 A
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;7 r3 _* d) w5 y& J1 \1 k0 ?
  39.       /* Input capture event */
    - p; E. I+ w: }, ?
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
    ; l  e5 [/ \8 _- q, R
  41.       {1 Y% C9 c5 f" P! r  m$ R* ^/ q  {3 Q
  42.         HAL_TIM_IC_CaptureCallback(htim);! n1 f: r0 T2 a, P4 g8 B
  43.       }8 j) p- X: k2 N0 ?
  44.       /* Output compare event */
    ; p8 U" q& `1 z0 \" E3 j
  45.       else+ [# B) c0 W* C2 g8 Z( n8 S
  46.       {3 B$ i2 d8 Z# Q( P5 {
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);) W+ b& ~8 \' A* V
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);) k3 \% r- u7 l8 M2 F8 m. v. B
  49.       }, Y, S1 X/ l$ z' t( C( m
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    ! B- q6 _$ T! v" ]$ N; M* {
  51.     }
    ; b) f2 l/ _# [; z
  52.   }- H$ J  C/ o* M( M
  53.   /* Capture compare 3 event */0 ^! y: T5 K" v$ {6 `! T
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
    ) ]% v  V& L1 ~* C: u* J+ p1 [
  55.   {; b7 x5 e; Z& R# T
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET). |1 H- O1 {% m4 T
  57.     {
    " ^/ E5 d3 b; t+ q$ F* w
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
    ! S7 X0 T) c- R
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;4 I: K5 c, x+ }: l
  60.       /* Input capture event */; G! j( d! p( k( e% q7 C
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U), a5 I& n9 j8 d( l- Y0 u% I
  62.       {
    3 F% G4 `! O  u$ R3 j& G6 ]
  63.         HAL_TIM_IC_CaptureCallback(htim);, ?4 L0 `7 D6 y7 v6 L9 F
  64.       }' [2 Z& f% J* p6 g( z8 t# F
  65.       /* Output compare event */
    ' e  A+ {* U' e, I, c) K, {
  66.       else4 K5 y: N/ V7 U) e6 \
  67.       {
    0 w1 t" x# q4 d9 G
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);5 X( ~' z1 R0 r  w2 \
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);+ d2 h5 u# a6 S  U( K
  70.       }
    ! w( {; Z" }% T# q; @
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    8 ^8 O# G7 U6 t# g' Y# V
  72.     }4 H6 {9 X4 h6 }/ D1 J* _1 x$ u
  73.   }
    / k- P6 ~% D. @3 ?9 _
  74.   /* Capture compare 4 event */
    % Y( _+ R' f% R/ V0 H3 J
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
    8 W( }3 Z' W5 u) A& T$ N
  76.   {
    # l$ x/ v! H6 `5 r
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)
    : U/ G1 C* j7 V, I# i* [
  78.     {
    % p$ F( O0 A2 a9 N
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);, a$ ?  @5 R% u/ n8 y( A
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
    4 g) N7 X/ L. @9 B2 t
  81.       /* Input capture event */
    / C" g6 V4 r& l1 _4 s" B$ M8 f
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
    9 M7 E" `1 D. d, T
  83.       {
    1 W* c5 k$ u; m0 B/ y3 p6 f
  84.         HAL_TIM_IC_CaptureCallback(htim);
    % d! j* ]6 K# O
  85.       }" A, P" h! _! p4 P6 S; @; _
  86.       /* Output compare event */+ m  d& U$ z  D& \8 M+ q3 v) w
  87.       else
    7 e: k& Q( B# [% h6 {. A& u
  88.       {, A3 \' ~" s: V: z. O2 ?
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);
    / p1 Y5 P" D6 x5 W# C) d: s
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    6 ]% n5 K. ^5 q+ I/ O8 I3 W4 u% M4 w
  91.       }
    % \0 a0 x0 m+ q; J# D
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;5 L1 `1 Y( ]+ q; D$ r6 p7 l
  93.     }0 K: W3 O: p% D7 c
  94.   }) r. l; [1 C. O
  95.   /* TIM Update event */. X9 @& z( |$ C
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)6 R  G! s; A$ E  X4 ^. Q; N+ z1 L  p- V
  97.   {
    , V, J4 V( P1 H  j( e/ w  N
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
    , y! S, ~+ e" J' D6 z5 h/ a
  99.     {
    . J8 j' O* j' e$ x- h: u0 J
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);: E3 p3 ]' }( m. ~. w) W
  101.       HAL_TIM_PeriodElapsedCallback(htim);& O: R! Z5 e, u$ o5 `* z1 r- g
  102.     }. J5 T, w# J% T% }" |2 y
  103.   }
    ; q& p! X) X& @! o
  104.   /* TIM Break input event */
    ! t+ z$ w+ U) a# q' Q
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
    * X( x/ D. g0 h5 m* F, @
  106.   {
    # M7 a0 w+ ]9 M
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)1 P5 i- \# q0 ?2 h1 T
  108.     {" X3 q3 y2 ^, w- f. p* B+ r3 h  M
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);9 x) g$ z7 I' k; {" y
  110.       HAL_TIMEx_BreakCallback(htim);8 b: W0 O0 r: ^) `+ ?
  111.     }
    0 H* s  c5 D+ B$ {- a
  112.   }) }, c1 i0 P3 z2 q+ J
  113.   /* TIM Trigger detection event */
    : a  ~* F" k- Y) B% ?& F
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)3 V# C0 P# G& q0 N
  115.   {$ S# k! ^) W4 @4 L
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
    2 D' I$ e" \+ n0 t, N! S
  117.     {
    & n# o( \3 S5 O2 s* K9 d
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
    " m9 q  s7 r( W" d" D- z
  119.       HAL_TIM_TriggerCallback(htim);
    $ _1 [) @  ]8 x( M
  120.     }
    5 N/ P; J; Q! s! P) f
  121.   }
    , c) Q4 h4 v/ @% t
  122.   /* TIM commutation event */
    ) s3 i+ `. q9 a
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
    ( R8 @: `2 y+ V; X' ], U( a
  124.   {
    ' |+ G5 R& [' g
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)
    $ s4 B( P# c  w* Q! G$ J% W
  126.     {
    - Q5 Y( U  T  i7 @+ i4 U3 J
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);% K6 v" J, k4 R3 q
  128.       HAL_TIMEx_CommutationCallback(htim);/ S" E$ d0 K# m
  129.     }2 g$ H0 m$ n/ p
  130.   }2 `- _, `" e8 l/ z7 r$ A
  131. }
复制代码

* T# \- [) F# v1 S$ H( u7 X7 W4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);0 j% ~/ `( B. r6 A1 N
& N" F0 t7 S. `* M4 q9 [6 |$ @
5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码
    / c' Q5 f5 x: ]( i8 A

  2. + p3 C/ X& f, F8 r' P+ y! L
  3. void TIM14_IRQHandler(void)9 z6 s. t, k, Q+ h  M3 ~9 g5 u# I
  4. {
    8 x) W7 ]5 g9 n+ y
  5.   HAL_TIM_IRQHandler(&Input_Handle);
    ' S$ R* q+ b! k5 {
  6. 7 H) v9 ?/ B3 t0 c0 I8 V
  7. //其他处理代码
    & z/ ]1 w2 u; Z, i0 S! L
  8. }
复制代码
1 }# R" Y! R: c2 ^% s# K
6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。
! U5 ^& t" f- g8 K2 E4 n) q  f+ @7 K, Y/ [  B5 c. q! U
7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。
6 s$ [- ]5 r6 C; o) ^3 v- r( ?. i. K1 ?8 }& j: i
8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。7 v! Q! e- V1 Y9 k7 c

0 a5 c8 u3 L5 y7 S在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。
/ W" a& R  E& t  F, p2 ]
: v4 [* A+ z; `) a6 x! G9)ken坑啊,都怪对库的执行sh顺序不了解。% I4 n. E4 g9 X% b4 x' p
2 }/ h3 A( c, _7 N) n9 m5 K# Q" `

! X& }" c' ]6 P% U) Y! Y
收藏 评论0 发布时间:2021-11-25 16:00

举报

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