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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn
+ W4 e% {8 O& i" f+ J
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */
    % _# ^1 n" a+ A) n# h- {0 U
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */
    / v  K2 {5 L* E" L0 s
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */' z% i9 S  N0 S! F8 K  q7 A
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */
    , k) v' }7 P6 p6 x/ d$ ]# C
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */+ }, G+ t8 `. n, ]
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
    : o) M  f3 E' D  l4 Q# q$ A
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */0 z& G$ x# {- Q& S" n
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码

# n% k5 z! j/ S3 V% k5 B$ {2)通常每个IRQn对应一个zho中断函数
0 |9 [4 G+ w# l4 t) x1 j
  1. /**. ]7 @% E0 Q; z9 ?+ w
  2.   * @brief  This function handles TIM14 global interrupt request.% Z+ N  @# O4 V- [5 U) }
  3.   * @param  None
    " v# l3 e$ Z6 A; J9 [- ^
  4.   * @retval None4 `6 J; m! d" b9 w& K4 D" C
  5.   */, L, [/ N* s- F
  6. void TIM14_IRQHandler(void)8 Y7 L5 C/ _7 @0 N0 A9 S$ S
  7. {
    / `4 c- N7 O# q$ x: b: ]
  8.   HAL_TIM_IRQHandler(&Input_Handle);/ t) R" L3 N% r  V
  9. }
复制代码

5 G6 ~* H8 |) e* o( h+ P; d3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断
: r, y' q5 j1 ]+ s2 i1 p6 P" p' L; E
  1. /**# l( G+ @+ Q$ q* S% r6 e. C0 @
  2.   * @brief  This function handles TIM interrupts requests.6 d; W$ [4 o# @8 A  T* ]
  3.   * @param  htim TIM  handle
    / g8 x* A3 u5 l0 X6 V, Y, \
  4.   * @retval None: B! C/ S* j8 E) o
  5.   */# n0 [) W- Q; q9 r2 v& E! r0 r
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
    9 h) O/ L- E. P  W, B3 Z
  7. {
    6 h: R# j5 E8 R0 m: f- F( |
  8.   /* Capture compare 1 event */+ P( G. _. n1 ]% ^* ]9 C
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)2 n/ N. {& |: H) X0 o8 V* \/ j
  10.   {* b  j* s/ Y0 k& i2 h% s, L% m5 s
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
    2 _6 |& v9 }4 V! e+ p5 X5 d0 [1 H' `. O
  12.     {% b" i9 H+ w0 _' P* E; e$ s
  13.       {, P4 N: |1 n4 v" T! t! B
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);; T& g4 z9 C3 p" u
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
    3 Z* }# o' }) r) Q' J

  16. 5 d! L9 P  i. k4 t  Q: u
  17.         /* Input capture event */
    * }4 S" a7 b( I& Y
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)3 g& A3 ^# i. J! _6 w. u
  19.         {
    # n7 W2 v$ L* S" l: y2 e
  20.           HAL_TIM_IC_CaptureCallback(htim);
    / J0 d, ^5 i# h# W9 e
  21.         }
    & Q8 K5 a% X. ?3 M5 f4 `" \" R* k
  22.         /* Output compare event */( l8 H4 W& X$ S1 x) M- Q
  23.         else3 Q1 V+ f# P6 [! {2 ~
  24.         {+ Y8 s  o: }0 q3 G9 |5 ~
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);
    0 A  ]5 R8 R$ z' [. z4 g
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);
    ' o  p# {8 X6 y
  27.         }
    & `7 d9 [8 z3 O( a& F# X  m
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    , O- c4 D  S% T
  29.       }
    : b. O7 d# Y8 W+ `' y! x2 |
  30.     }
    8 b, I2 Z  o# P" d7 W
  31.   }
    ; [5 x, C7 r" p* T
  32.   /* Capture compare 2 event */
    / K2 s" v( m9 k9 C+ _
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)+ A" t, i: T( K
  34.   {
    ) {' T$ ?% B; A0 P8 |( B
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
    3 Y$ O, k) B9 y5 F- t9 ^4 d
  36.     {
    3 e$ D: k+ W% b3 r
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);9 h7 b2 J: T. z
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;" p7 O- }( j! n
  39.       /* Input capture event */+ ~- l. {9 \9 p1 T6 {* v
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
    6 P7 X# g! [$ t
  41.       {
    3 S- t! t! ^- C" M  b0 v
  42.         HAL_TIM_IC_CaptureCallback(htim);9 F/ f- k) p0 Q# s; s
  43.       }
    : {; J0 v# B8 B& x
  44.       /* Output compare event */
    0 N( @( U  ~7 D4 o2 s* v- P1 Y" s
  45.       else9 H# S8 r$ ^# P9 z2 V2 M
  46.       {; U6 K0 F( ^  n% R+ `. z7 _( @( K
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);
    ) z7 ]* t) N) p0 h! n7 v
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    : [) {7 D, h) v% P# g
  49.       }
    # }+ ]2 w8 b: O6 e
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    3 R# Y! D: |8 I! w
  51.     }
    5 R- ?5 c/ }! b. S  t& \
  52.   }
    0 U" N  t- t; H) f, @
  53.   /* Capture compare 3 event */
    $ S1 P( Z9 w9 a" h2 ?
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)4 h$ H. F7 H( I8 R
  55.   {
    & |# \2 S- N/ [0 U0 I0 r$ B% Q
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
    ; |  s# [7 U, `, p
  57.     {
    , ~% ^3 S2 N$ o% Q' @
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);% }& Y) D* {% a6 `6 x- C8 y& N
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;7 a" K. m8 L3 K; }) L
  60.       /* Input capture event */0 O5 b6 N" j# O+ {0 s/ z* r
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
    , @  Q' M: }+ r" b6 }) T6 S% `3 P7 g
  62.       {
    ! s: _9 u0 }" \* `* q
  63.         HAL_TIM_IC_CaptureCallback(htim);
    " `3 d) X5 Y8 h+ v
  64.       }
    , S5 ]: N6 v4 x+ B  n8 Y
  65.       /* Output compare event */
    ! E3 e  o& U, x$ C% [% S) |# a
  66.       else
    ; L( l0 s9 d4 o+ k6 D, l
  67.       {
    , O3 p7 G7 F5 [$ M
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);5 }. n# z: [1 b/ d
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    4 _$ J! k3 y( J; `! S* \. a
  70.       }4 ~8 b8 W9 V5 q
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;* b4 s; [; F& r. t5 p+ d
  72.     }
    ' X: g8 m3 ]6 [1 L3 e
  73.   }
    ' V1 s' X4 r" u. [  f- t
  74.   /* Capture compare 4 event */: u2 n5 }" n4 y7 Q5 U9 b; W! @
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
    1 C; u; M7 i6 O( x5 E
  76.   {" _  e. Z2 F8 E0 Q& h6 r% ]# o
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)/ }$ Z& C" P- I0 w$ ]$ U. x
  78.     {
    / ~% J/ [. z9 Q. ?, R! v
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);" f& W; L% s. w- @& @9 y! d, W- S
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
    : b  x. {# Y( T4 a! G+ P( B2 [3 r; [, Q
  81.       /* Input capture event */
    3 I' A- v2 ~) y
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
    ' [& c! G, Y6 n
  83.       {* B* V, z! H2 u' p% Q! R* L) ?7 m
  84.         HAL_TIM_IC_CaptureCallback(htim);" H. w, O* e! R, j1 r$ x
  85.       }# f; u2 g5 P) s5 Y# v- D6 v
  86.       /* Output compare event */8 K9 g# Z/ n7 y# g
  87.       else0 n( h- @% D1 ~: j1 x! C
  88.       {
    ( u: Y: |8 U+ ^3 `7 U
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);
    3 J: Z1 Y4 s# T/ P+ [' I
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    7 F9 o3 g8 }: f* j, B# G6 Y9 A
  91.       }- h: @) o$ G2 c$ @- z$ G
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    $ A8 i, P3 H. \4 ~
  93.     }
    1 C. l- m; t) D! L5 b3 n
  94.   }4 R0 e  h' w/ F  _
  95.   /* TIM Update event *// Z* _; t+ O5 ~, e6 _5 d5 _
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
    % P$ l8 e# G# T/ B7 ^4 i) F5 ]
  97.   {
    # A' g/ h9 g) t$ s; |2 b
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
    / |1 w2 R9 _9 h+ q& P3 f. u2 f
  99.     {
    # b& J0 J! e, E1 F+ h  I
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);8 w/ J  v5 t  I2 g6 |# c3 |( H
  101.       HAL_TIM_PeriodElapsedCallback(htim);
    ' j% {" J& H+ o3 E$ D3 u
  102.     }8 e0 f1 h; E5 W* Z$ G* G7 e6 c
  103.   }- T" ~2 n8 W$ H: |6 E- E. W1 @5 O' S2 R/ _
  104.   /* TIM Break input event */9 V/ b1 |; ^9 h  y4 E
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)" o1 {5 k% x" M' \6 V$ I
  106.   {
    & D) p: V9 F9 a- |5 w% a7 {) Z
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET), l- B" x; _& Y3 v+ Y/ f
  108.     {  ~2 _* u# a) p% ?" L6 T# }. s
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);1 g& q% m  o( Y" h
  110.       HAL_TIMEx_BreakCallback(htim);3 t. L3 i) S- }( {$ k, Z6 v( L( C
  111.     }5 }' y8 c# f1 G7 {+ K
  112.   }8 y, V7 }- k! M) L
  113.   /* TIM Trigger detection event */, U; x2 p$ W3 j5 l
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)1 X: V. V, ~) O5 q# ?0 \
  115.   {
    ) }3 ?4 P3 V( g& U2 O  a& f$ q
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
    3 r- k8 }% k) A
  117.     {
    ' i- L; Y: d, |1 Y0 o
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
    6 Y9 j" j' F! T9 L5 \
  119.       HAL_TIM_TriggerCallback(htim);: f# Z+ f, h2 U. ^9 |6 @! g
  120.     }
      z2 f/ ?/ C7 B6 V. C9 g+ L- b
  121.   }2 h9 V8 ^- R3 s! `( b/ o$ z! g
  122.   /* TIM commutation event */
    , ]1 e7 q" Q0 i
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
    + p# S$ B3 k/ }: y$ ~0 l% ~6 @5 l
  124.   {, k  q+ V. |0 ?0 S8 p
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)
    ' C4 @1 w' C% y( x6 f
  126.     {# b& W& X+ a5 d- q4 B0 I
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
    ( z2 t! D- z* Q" a
  128.       HAL_TIMEx_CommutationCallback(htim);
    1 C+ p3 r1 R- [6 E  a% f+ r" A
  129.     }  b: ~6 C& \/ ], ]7 o/ |: O" V) ~
  130.   }' l0 y/ B2 ~  C5 T; {  \9 e& N/ k
  131. }
复制代码
, V! y8 h* [+ J1 `  z" G- @" D
4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);, p% Y% [9 B* k5 ~+ ~! B* j

! F* u# s2 O3 W4 p/ u* h( B5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码) p! x: r0 P. t

  2. - f2 m1 ~  N' e8 U3 A. ?; T
  3. void TIM14_IRQHandler(void)
    6 z' d: {4 \4 I' Q- e. |
  4. {
    - D4 n, a7 |- v" f1 |2 h5 w) Y' @
  5.   HAL_TIM_IRQHandler(&Input_Handle);
      B7 q8 j; q- @1 I7 r

  6. 3 E9 @% S% C  n6 _6 a
  7. //其他处理代码
    - J7 q$ h$ A7 F* M
  8. }
复制代码

2 n; d8 q# L: ]' r6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。1 F+ n* B' M1 E, a/ t
- z7 z! ]5 p1 O4 M9 k4 K- p  P
7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。. A: H+ q% M# k: N$ `0 C$ J

5 Q& b) k  D" _; @1 ~6 s  P8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。% B) ~2 V+ J2 {" v# o7 R

6 H/ K% w4 A& M/ L" K在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。. [$ c$ E& b, S
& O+ m- r: T- Z( r9 m8 e. ~! ^: ~
9)ken坑啊,都怪对库的执行sh顺序不了解。1 j# p* i3 m; s, o" r. R4 }8 |+ X
6 N. w; F# u+ M* g9 w9 w/ s

. z9 \( R# {3 C4 ?
收藏 评论0 发布时间:2021-11-25 16:00

举报

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