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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn6 E7 V* n# g: S1 j$ ^
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */
    ' `) m- c. |, ^( w
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */
    7 x4 z2 N. U  T
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */
    . r! s5 H. N$ n6 b5 d
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */
    0 C6 w( W9 s9 a/ g( f
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */
    . R; [0 h, {* ]' H8 J
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
    7 T4 d$ f$ ]9 e) V
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */
    ) {* N1 {# }0 P9 K" T: S- d
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码

( [, [- [6 N0 S* y. t; a4 y2)通常每个IRQn对应一个zho中断函数
. u! A7 z, V- w( k8 I
  1. /**
    % e; e8 d; O9 ~& ]* l2 ?
  2.   * @brief  This function handles TIM14 global interrupt request.' g* i" c( x2 z. J3 r
  3.   * @param  None
    # I/ L/ f6 }7 J3 Q
  4.   * @retval None
    9 F3 y! D3 v; Y) l5 Y
  5.   */
    ' H& i/ T5 Q$ f* U, ?% H7 z
  6. void TIM14_IRQHandler(void)
    $ v1 M' @: V+ I& t6 W$ Q
  7. {
      S4 `* q; ?% R0 z) d: i
  8.   HAL_TIM_IRQHandler(&Input_Handle);
    9 u# H- w1 K6 ~2 f* j' H4 ^
  9. }
复制代码
2 h: }0 O. ]0 z' Y# d8 p* Z
3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断* m3 c+ ]0 F% i8 |9 R2 p

: @  C* p( v; m# R
  1. /**9 q( G. F8 Z0 e4 K% m
  2.   * @brief  This function handles TIM interrupts requests.
    $ q5 v. r9 X, s4 m
  3.   * @param  htim TIM  handle% k; p& N4 E  @' x, m5 R; ^! P
  4.   * @retval None0 n- Z3 x0 a. q8 X, O
  5.   */) H0 }# ?1 T8 V$ {% A
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
    9 e( A) U+ o% S3 ?% S
  7. {" R2 l4 D$ Q! D& [) Y1 w2 W
  8.   /* Capture compare 1 event */
    - f* h+ R$ |* g( T" C
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
    ; F+ J" ^: P, G
  10.   {+ V! G; n! ~* N" `" b9 M
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
    + R% a0 u! J( ?( Y
  12.     {9 U0 h; R4 l9 M, w3 g* @( q5 [  s# d
  13.       {
    ) j" O, r0 @& j& ^( o* \4 z2 t
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
    $ w7 P4 m% W5 e0 r8 {' X" s+ d1 |  `
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;$ p' B' m) H0 E" H
  16. . Z' y3 S# H5 k
  17.         /* Input capture event */
    2 f# s& ?& ^3 u4 u
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
    9 W. m6 g* L8 V6 K4 i
  19.         {- X9 D% R' F# y( l
  20.           HAL_TIM_IC_CaptureCallback(htim);
    8 p& I5 Q, ?" e- p/ s
  21.         }/ z7 l1 @1 z- c- v! v' Q) ^) s
  22.         /* Output compare event */
    5 r- L% u5 ^9 u% p
  23.         else
    ( x+ `6 \/ F* ^; ^6 m
  24.         {
    , n4 R/ F" c7 b) h" d, p+ D& W
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);
    7 F! u' G: K+ ?& d& c* Y: g0 S
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);
    . z$ G  K5 }) L" Y
  27.         }
    9 \* E, D; ]# Z9 I- {0 V
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;( q4 C- }) ?/ p1 J
  29.       }
    ( n! j9 z% y! A& M. U2 D- E
  30.     }
    * u; N3 B! U0 N
  31.   }2 o3 h  E- N/ a
  32.   /* Capture compare 2 event */
    ! u/ W2 F8 M5 F
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
    & q0 s4 e6 n$ E1 R4 \3 G4 H# a! b# e8 J
  34.   {6 ?: `/ q, l$ M/ M( M
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
    " V/ E9 Y! `5 `2 N1 V: {8 T9 L
  36.     {
    9 K2 @  ~& e% ]( q
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
    3 [  |2 a8 o) Q. o# e+ r( {
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
    . F$ b1 A2 H1 i3 d/ R  @3 s/ }' _& _
  39.       /* Input capture event */
    - F: C- u/ A. g/ j3 L0 J& C
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
    0 O) N) V8 Y' u3 f9 C, W
  41.       {( T' z, R$ P9 w5 |
  42.         HAL_TIM_IC_CaptureCallback(htim);
    # ?% O+ D9 \8 c/ Y9 i
  43.       }
    5 y& ^* c0 u; \( \+ _& y6 P
  44.       /* Output compare event */
    # C: c& g( I. L+ |
  45.       else
    : l+ _9 {7 q! J5 z$ e/ v6 n
  46.       {
    2 Y8 A; T8 D( p* I, R: E$ D1 M
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);
    * g) H9 F  k( U; D, Q* ^1 L
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);: F+ T7 p; q, ^: p9 ?) e
  49.       }
    ( E% z. j- f2 b# w7 L" E
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;7 a+ j" P* t: E" l
  51.     }8 c( v+ P7 G7 C4 g. ^2 ^8 |5 Q% A+ T8 D
  52.   }
    9 R) Q7 Y: {  h$ q% ]
  53.   /* Capture compare 3 event */# e0 P: F+ G, R. w8 c8 q/ o
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
    ' c& u7 _5 p* s- a- l9 D
  55.   {  {% L7 n/ F+ m
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)% ]" M7 m! ?$ \+ c; d+ Q' }; x
  57.     {, F% h6 m; ^# ^( d
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
    , @& v4 |4 n4 a: k/ [
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
    2 r: W4 [6 `1 G" X8 X) t
  60.       /* Input capture event */4 G$ E" ?* z" W: ^  ]+ x
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
    7 \* s% _! ^1 I2 P7 @
  62.       {, w$ E: }( F4 S: x/ i$ o
  63.         HAL_TIM_IC_CaptureCallback(htim);
    & z4 d2 M; f) }- ~3 T4 U
  64.       }: E) j# [; m5 P$ Q: ?3 M
  65.       /* Output compare event */0 ?5 n3 M# d0 U! y% h  N
  66.       else
    ( P  H/ n& a7 l" I3 B
  67.       {/ H) x- i" o2 m
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);
    $ G( S: T/ ^+ v9 x1 w
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);, l9 x% A/ g! }3 d( D# n! `
  70.       }
    ) ?9 H0 B  m) N; Z# J' A1 R
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;# A7 Y" r5 v, p2 ~4 L2 V
  72.     }
    6 ^% l; C/ K- q6 Y
  73.   }: l: j+ L7 f' ~9 V
  74.   /* Capture compare 4 event */! L: z+ u  o+ q/ y6 ?& w1 X& {+ X' g! w
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)  P: `: q* S7 P2 A/ Q; f8 {
  76.   {
    $ F: O; z8 w  Z" \  L
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)# j$ q5 {, A' Y) D
  78.     {
    . k) Q' }3 V1 F' R7 z" ^
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);; ~2 H3 ?0 K  c% r3 p  Z7 c
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
    7 I0 B! G1 B' y. v+ F3 Y3 C% n
  81.       /* Input capture event */
    1 O0 a* G6 p4 N. H/ o
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
    2 b0 r" S; H  c/ Y
  83.       {
    / L9 s. U6 j% {( G( t  P2 }* R
  84.         HAL_TIM_IC_CaptureCallback(htim);8 S) W, t; a2 ^0 N2 C$ h2 k( [4 q
  85.       }
    $ w- T, j/ T; R
  86.       /* Output compare event */% v7 d  ?* x# N3 B! @8 t7 L8 w4 f
  87.       else8 h3 ~  w) C# e3 N
  88.       {
    / t3 \! X% p7 ?1 e: s& g
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);' g- o" ~7 T/ M8 [
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);- l6 r& @, O; [6 ^* c
  91.       }$ S3 R9 F$ K) m8 ?$ @, r9 M
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;  t$ z; U6 W& ]3 v) F" ?
  93.     }
    * K9 O+ O7 D+ ]: I
  94.   }' |9 M7 g  b( w0 H. N7 Q
  95.   /* TIM Update event */6 b- ]2 ^: b* A2 F
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
    " z3 L% W- _" K4 {
  97.   {  L2 G( x' ?) n/ D. l0 b
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
    + [1 T/ R+ q8 x& q' i! M% X
  99.     {
    0 Z+ V" h: u; B( V
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);) F. Q& L+ M# q. T: Z
  101.       HAL_TIM_PeriodElapsedCallback(htim);
    ! Q7 W: {7 l% t& Y
  102.     }! Z) m, U% M( l9 ?
  103.   }
    ' B# d! a8 j) s6 l" K. K4 M
  104.   /* TIM Break input event */! h  n5 Y% n" z
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
    ! u+ V7 z/ t( q$ B+ M1 X
  106.   {6 @, `/ d2 R/ ]  z4 y
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
    2 p8 ^; U' ~- C9 k: T+ `, }
  108.     {( r& U* c+ [) `0 l! z. T
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);# E; f+ M  q, j) f( _7 K4 H3 A
  110.       HAL_TIMEx_BreakCallback(htim);
    1 I! w' F: \3 Y3 |4 J! \1 ?  K
  111.     }
    3 W1 |3 M- O2 W' @- l
  112.   }
    & ]" ^* p( `/ v  l7 O  j8 o* _0 @
  113.   /* TIM Trigger detection event */
    % \. ]5 y2 ~; c  S- H& m- N
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)+ {4 k4 n/ Y  ~6 K
  115.   {5 u) Y6 D, w* o% j4 L8 u1 V7 o% B+ @
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)9 M- B+ s1 D# E( O' h
  117.     {" k5 ], Q# {$ G- b) |1 v
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);. K( K, }- z. S) u
  119.       HAL_TIM_TriggerCallback(htim);) y* w$ T. ~6 h; E) l/ i* @% M
  120.     }
    1 ^2 B0 \8 _2 |  N9 ]6 D% ^
  121.   }. v+ C. j( p5 m7 i+ R9 K* V
  122.   /* TIM commutation event */
      a! F7 ~+ }! A! Q% T
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)" D6 X. b+ Q# o3 J
  124.   {
    1 w7 `' M4 h2 N+ x2 R3 V
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)( F0 L2 W0 ?: w/ N: e+ ?  \5 E2 E
  126.     {
    ' ~8 ]+ e% Q5 y
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
    " n3 O9 k1 z  B4 y/ k
  128.       HAL_TIMEx_CommutationCallback(htim);
    ) I8 t/ l4 ?  o; u& w9 w% _. \5 T5 a
  129.     }1 |" E0 `; _* o1 P* e
  130.   }/ p. ]4 n5 k" w2 [! J. b2 D# m
  131. }
复制代码

/ h3 H; t  ]$ X$ e. }4 H! }4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);
: _8 I( E* y3 S. M$ A1 |3 ~" N& u! S* |; ?6 o" s& y% H
5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码+ u, B) t% V+ M4 W0 R
  2. $ p8 G  @, v1 n- `
  3. void TIM14_IRQHandler(void)
    . u1 w% l! g# C; v: }0 b
  4. {
    8 g1 j* L. H8 [% K: P
  5.   HAL_TIM_IRQHandler(&Input_Handle);
    5 Z  y) D( ^  c5 Q! C
  6. ) `* ^/ T. ?8 Z* {- r
  7. //其他处理代码
    * r$ s6 w) U) _
  8. }
复制代码

. t- |5 X3 U5 s( W& g2 V6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。4 ~( a( o9 L7 t+ `9 B; l4 A

, c' s2 L' M9 m2 Q- [7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。
! Z. R) [9 h# t, ]5 j: z3 X* _5 o3 v# p
8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。
, J8 g7 i/ o+ |! A" w3 D# L! z$ I7 s+ C; w
在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。+ d4 D* b) O! e* _# V

& m2 o/ W/ N# D! q% ]- K9)ken坑啊,都怪对库的执行sh顺序不了解。
- @3 e, J# O& Z' L8 A; k- `/ W
% M8 n/ V+ d2 G) X& L& |! J5 q0 D& g7 p) X# [# L
收藏 评论0 发布时间:2021-11-25 16:00

举报

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