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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn5 x2 T5 i/ J, D; p* m4 A& m2 F# y  |
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */. n1 }: f( k, @8 B- y" d$ P
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */& d3 k9 Q, L; Q6 b# I  O
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */
    8 z7 U1 \# T2 X# W3 ]. o4 o
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */
    $ {% q- y# `" [/ s/ |
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */
    8 G' V; u* c- a6 _& {, D/ J
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
      X! L/ j0 S" p4 v1 p
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */  e' v4 z8 f  T) f$ N7 [
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码

3 B. L; J( E: w' d2)通常每个IRQn对应一个zho中断函数; p! {4 i; h0 m1 a: W% F; Q
  1. /**
    0 k) r# T) l% t( w; a& E
  2.   * @brief  This function handles TIM14 global interrupt request.
    & b/ z. n$ G( ^; [
  3.   * @param  None
    ' e- d# n( E; b+ }, n
  4.   * @retval None% Q3 Z& K0 ?- S! Q. t9 [
  5.   */
    : Y4 _& p! |! i! |7 E0 _) ?
  6. void TIM14_IRQHandler(void)
    7 [- H! e$ y5 Z1 n5 R& H" h
  7. { & {* ~' b' _) H; t- t2 k6 w( y/ t1 J
  8.   HAL_TIM_IRQHandler(&Input_Handle);! F) i7 S5 x5 k; ?/ z9 Z
  9. }
复制代码

1 A2 x3 H' z7 ~, N; G, f0 L3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断+ y+ }/ i! E! M" v- L& d$ i, ]
$ `% c2 G- E% u: l, p: G& l: a
  1. /**  j  }0 k' c+ {# J2 D9 X4 D# r4 z
  2.   * @brief  This function handles TIM interrupts requests.
    4 y# s% r, [6 {1 P1 W' {
  3.   * @param  htim TIM  handle8 e' e) o: P- A; W" `- r9 V, Z
  4.   * @retval None% |: ]9 |2 E/ C& {5 r3 k5 @
  5.   */
    ' d" S8 l0 ?0 O9 r$ x7 O' r3 A$ a
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)' c! s0 Y" n; L; ?) R* t( L9 ~3 z
  7. {  g& s& o1 W, J9 P" K
  8.   /* Capture compare 1 event */* Q$ m; `, J* e. d: x9 e
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)0 i" j2 A& d* N  K" p4 [
  10.   {
    % K, U- [) p: ]
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
    / M, a. v% [6 k0 B+ _7 M; y* ?# w8 I
  12.     {
    ' X/ G, L2 [1 }' N; g8 l" X
  13.       {
    ' G- V4 `: J) _0 G( E8 D
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
    ) x1 @# X; W: y! ?
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;: J6 \( K7 H& \6 F5 C1 N
  16.   n' V4 K' {0 p% J
  17.         /* Input capture event */5 `, T. X1 Z/ Z; k
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
    # l6 ?2 J2 F% i+ |3 _  T
  19.         {
    2 B& z/ @. H7 P0 G5 d8 b! X  O
  20.           HAL_TIM_IC_CaptureCallback(htim);
    ( }% B$ u& l& j0 a2 y4 U
  21.         }+ G3 ^" N' R7 _  h. V
  22.         /* Output compare event */
    0 \6 h8 d/ |0 M5 j
  23.         else) a" l2 ?+ b5 ]3 d' n  R* q  |+ U
  24.         {
    , o# ?, F7 G* W! w* A1 G% I
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);& `% s3 V& M/ u- [
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);
    ; m( w3 g2 l5 }
  27.         }9 a3 _  S3 t2 n! }
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;" o& A; u$ l2 {8 _1 J' {' `
  29.       }9 a) \: {! H  i
  30.     }) P+ V: D. J, ^  a5 `) H- H
  31.   }, C! }+ A8 ]. S/ B( V4 X5 l' u* _
  32.   /* Capture compare 2 event */
    9 t0 u- E5 I$ A1 L* C! ~8 i# {
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
    , U9 t6 \( A, d7 I- U8 ?' n( p. ]" R
  34.   {
    9 B1 E8 L; b( y# ~* a. G# z
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET): G8 T6 U& a/ c) |* U4 P7 D/ G
  36.     {; }  |5 e5 {4 O5 Y0 A/ \6 B0 a' {# Z
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
    9 g1 A! ~) ]1 {
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;( K) C' n' m# l" X4 J( C2 }
  39.       /* Input capture event */
    8 Q, q: P- W/ ~) c9 I/ @
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
    7 Z  o2 |  F6 p) |8 o8 A
  41.       {  p, [& X9 i* `* }+ U- S
  42.         HAL_TIM_IC_CaptureCallback(htim);
    $ X+ D/ x7 F, |% p
  43.       }
    ) X. W6 |$ ?6 C' G8 G, z
  44.       /* Output compare event */
    4 E) L; P2 a0 s2 |- Q: P1 }  z+ ?1 F. n
  45.       else- R; y$ }# e2 h1 P5 G8 a
  46.       {
    ) ], i1 h4 u) E, G- `( J# X
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);$ P6 [5 \/ v# v. L* Y) \
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);5 C8 z% x3 s) @  Z3 b" Z5 z
  49.       }6 r7 p2 {% v, H) Z+ i# R+ \" `$ O
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    4 i# ~& y; p2 h  C" q/ \5 O
  51.     }) Z- i1 k5 U! j
  52.   }
    2 x2 [9 S9 v4 W# q6 {
  53.   /* Capture compare 3 event */
    ' H6 _% b  Q- [' W0 E4 E- p
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)5 [2 P$ j; ]+ m4 N0 P
  55.   {6 ^) R) ?+ y' V7 i- Q; m5 \7 {
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET); V0 W, ~+ o( G4 E8 p! Q
  57.     {
      V3 [. F3 D) r
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
    & [. A! K8 C( {& C" b" w/ X$ s/ }
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
    ! N3 M& q: b$ v! X, L; x
  60.       /* Input capture event */2 k# j2 M- i. `" x& r2 i
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)" r* i" q9 R; j. e9 N+ E8 S1 _
  62.       {" w" [7 ?; `; q" {
  63.         HAL_TIM_IC_CaptureCallback(htim);3 F% `6 k$ E, i" D3 o# G9 R
  64.       }
    2 P7 g$ j* j; \- t; h4 s+ s
  65.       /* Output compare event */
    ; U* s/ Y) |' F2 M2 F- w
  66.       else  d4 @; S: g+ x2 R/ a9 [
  67.       {% e3 X. c" H3 V# g
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);
    ' C+ {4 [7 ?  t. l. @( P
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);* W2 @) ^0 ~9 @* }+ Q# B# ^; a% K
  70.       }5 L; ]0 `6 I1 b/ d6 \, e
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;4 g3 Z9 }" W- J3 L
  72.     }
    * J7 S6 _( M9 T. H6 i% a$ E$ D0 ?
  73.   }  \0 [( h( ~% C" V% t' y
  74.   /* Capture compare 4 event *// {+ X. g6 Y$ i: t% v, i
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)  y% L% i4 L: g
  76.   {
    : d9 O% t( u( V7 _& N7 D1 C/ ]& ]
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET), P, J) D  h* K: y- j0 u! Y9 g
  78.     {* ^! U- Y  \6 k+ j% p3 G$ \+ y
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
    : K8 E# x' W, Z" Y1 C" d3 _3 e
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
    8 `* \" G1 |+ n: c( q
  81.       /* Input capture event */. X7 \" i/ T3 _4 T9 J1 Z
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
    2 ]$ @! |8 W4 K' X" E
  83.       {/ o: @& m8 t& w: o) r/ b$ n$ P4 @
  84.         HAL_TIM_IC_CaptureCallback(htim);
    9 I& [* l2 c; c9 c, y2 B
  85.       }
    + Y1 C% n* z: ]4 R) Z- o7 @
  86.       /* Output compare event */7 u' p3 a4 }' C$ |) q" ]
  87.       else# S0 j( k3 U1 K. M5 C
  88.       {
    ! g1 z: }2 N) X, |9 J# I% J, b, ^
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);! H/ v5 L, [$ Q1 P9 |5 H8 t5 m
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    8 W# I( \+ d2 x( L; g
  91.       }- Y2 ^" u  j4 {3 F6 @" v8 F
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;& Q3 o4 b- r. u! N) W8 U3 N1 D! W
  93.     }7 Q. u" Z* S/ m( }, V1 k
  94.   }
    * [& f5 J: o% I' R2 ]) u; T
  95.   /* TIM Update event */& L" k" \" \) A- _3 k
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
    2 I6 c! P& x# ^0 a# Q
  97.   {4 `- p3 z+ Q3 c& N: [
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
    ; r! z0 _% ?) W  v3 \
  99.     {
    ! y3 x9 ]& F4 f1 x3 i( _+ y: I
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
    ; r4 N& Z. {: t6 s9 e; j/ [1 F
  101.       HAL_TIM_PeriodElapsedCallback(htim);, z8 A7 C/ d/ S1 T! v
  102.     }; L5 N/ G! k0 L
  103.   }
    2 [1 F9 _7 M( ~0 f9 M9 M1 ]
  104.   /* TIM Break input event */
    . P# E8 W( O( \
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
    . x+ j- Z! R: z3 z
  106.   {
    & K* i$ e# a) H! P
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)
    7 f# L" y- }+ }( @3 J1 O6 X( F1 ~
  108.     {' h+ W1 f- D: ~  G- S4 `
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);) v7 \7 c! C' ]
  110.       HAL_TIMEx_BreakCallback(htim);
    5 z( S1 G& J1 [2 k3 ]: C4 t' a
  111.     }# \# @9 |4 }- \! m, c8 |" }/ x3 k
  112.   }
    0 P9 n( V! v# z$ k; M8 S
  113.   /* TIM Trigger detection event */
    ( D4 v0 w' l! o. H. l% e+ m* N0 o
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
    ! z0 D9 H3 ^3 i8 W+ E: [; W
  115.   {
    & T0 e3 `( k. `- n: T" h9 b
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)
    ' q; ?- Y9 w: W+ V. a% G1 q' d3 q% W
  117.     {" @0 X; v+ j" h* J
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
    2 ~% h; i' U  ]  s
  119.       HAL_TIM_TriggerCallback(htim);" ~) D; F/ M3 t
  120.     }6 K5 v: f  h; r# X
  121.   }
    6 _  |; m+ A, @, I; `
  122.   /* TIM commutation event */& I% j% I8 F$ p# z2 j
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
    % P7 K( L( `( S: i/ ^
  124.   {
    ! h5 O" K% g! F# h: X
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)& H; ]; F0 g% F2 I
  126.     {8 K) L# |0 \8 l9 d
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);' f" L/ f: f3 F1 q) w- j% \
  128.       HAL_TIMEx_CommutationCallback(htim);
    7 B6 T6 J2 ]+ s# y
  129.     }& U% [) h% e* R
  130.   }  A0 v  n0 B, q0 e* y% o
  131. }
复制代码

) B6 l) V- y0 q/ a, W. r: m& o4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);/ D6 C  O8 U3 F, Y# R
: N6 p. r* ^5 Y2 i4 ]7 y: t
5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码
    $ i3 K+ D3 q& u1 m( \# A) D
  2. ! C* D! Z" v7 _4 r: r
  3. void TIM14_IRQHandler(void)
    2 Q4 ~! C5 x3 k) j
  4. { + ~$ s5 V# i3 s; p, S
  5.   HAL_TIM_IRQHandler(&Input_Handle);* W! v8 T5 h1 i0 e
  6. % S2 \; l* J  T* l6 Z& _
  7. //其他处理代码4 {" U! \! c8 M! _3 ]
  8. }
复制代码
8 \! K8 d" t9 P
6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。
* _6 n0 g& S  C6 q; k* Z" z- n! i/ w9 @4 @1 R3 [( E" f$ J
7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。
2 `8 L! i) A# X$ a" v) O. a( [2 r5 s6 [+ ~9 O
8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。
+ `5 O5 ~6 v  i7 [( _
: {1 m! j0 X3 V3 w; W在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。) d4 P, c( J) _" C+ O/ |7 O

4 _% _! `' k$ w) |9)ken坑啊,都怪对库的执行sh顺序不了解。
4 B9 t7 W1 K- f9 ]) A; @. Z# D: v' t! K
  g3 M- _0 H" w% S" y" H
赞 收藏 评论0 发布时间:2021-11-25 16:00

举报

0个回答

所属标签

相似技术帖

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