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

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

[复制链接]
STMCU小助手 发布时间:2021-11-25 16:00
1)STM32F0有多个定时器,对应多个IRQn0 e) Y0 j$ g* t
  1. TIM1_BRK_UP_TRG_COM_IRQn    = 13,     /*!< TIM1 Break, Update, Trigger and Commutation Interrupt           */
    + F% q; G9 p2 x4 V
  2.   TIM1_CC_IRQn                = 14,     /*!< TIM1 Capture Compare Interrupt                                  */% i5 t# a( t0 n" |( |! W
  3.   TIM3_IRQn                   = 16,     /*!< TIM3 global Interrupt                                           */5 e# \. N8 b% U( B3 C
  4.   TIM6_IRQn                   = 17,     /*!< TIM6 global Interrupt                                           */7 Y0 j5 P6 ^5 t3 ^
  5.   TIM14_IRQn                  = 19,     /*!< TIM14 global Interrupt                                          */
    / y: G, {$ x& m0 ^" _& G' f4 F
  6.   TIM15_IRQn                  = 20,     /*!< TIM15 global Interrupt                                          */
    1 l9 x& V/ ^" C8 p1 F* {' C
  7.   TIM16_IRQn                  = 21,     /*!< TIM16 global Interrupt                                          */0 {7 u) `& A# V
  8.   TIM17_IRQn                  = 22,     /*!< TIM17 global Interrupt                                          */
复制代码

' S3 p, {0 E4 g! x: d$ {$ h) |/ U2)通常每个IRQn对应一个zho中断函数
" t( N4 P4 J( F+ v
  1. /**( c& Q% F- k4 e. {, h+ B1 w
  2.   * @brief  This function handles TIM14 global interrupt request.+ X# N4 u( Y" S& M7 j- s6 i) Q: ^; A
  3.   * @param  None
    . Y3 y7 F( z- ?! y
  4.   * @retval None8 }. [- Q" ^4 I9 b  g$ X' r
  5.   */" \" v3 G* o9 x; @9 w( d
  6. void TIM14_IRQHandler(void)) b4 b- H( e: }# R, Z+ Z' Q
  7. { . q9 F+ Q3 T! M) P# h/ n8 B+ l2 @* }+ F
  8.   HAL_TIM_IRQHandler(&Input_Handle);
    * r3 t! Y% X& [: J# Y. s
  9. }
复制代码
. o/ F6 E' I$ q; Z5 P4 J9 D
3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断8 t/ s) M' ]( W+ o

& {0 r/ i! ?3 G9 P, [
  1. /**# K% u4 A3 p% P: D
  2.   * @brief  This function handles TIM interrupts requests.' v$ k0 \5 f; I3 D
  3.   * @param  htim TIM  handle9 e1 }: d) w, T& B
  4.   * @retval None
    ; L0 F: l, n, L
  5.   */+ ^* z  ^9 \$ m6 c1 E3 J
  6. void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
    9 f7 x) U; A! z! R3 A) t
  7. {( C2 O8 C" o* ^# _8 N& T
  8.   /* Capture compare 1 event */# t0 J( \5 G4 u& U2 V% z5 c
  9.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)$ o  C0 N0 y" g$ f+ C0 F
  10.   {
    $ o6 _1 D6 H3 c7 K1 P/ z) i0 m! S
  11.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)
    & B& R4 x$ P: {  ~! {, f; x" B, E
  12.     {
    5 u0 ]1 W% h9 K
  13.       {- ^' q7 S5 s! x  k: P* e$ V
  14.         __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);2 L% B3 q" S; i/ ?% z
  15.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;# O* N7 j5 `- K: m* O6 [
  16. : j8 u2 T+ Y5 A: E
  17.         /* Input capture event */! B9 K! O# I# N$ M. ]' P
  18.         if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)+ F9 R) H; Q+ _: P# c# V
  19.         {% p" i1 b+ C' [0 E% J
  20.           HAL_TIM_IC_CaptureCallback(htim);0 G+ b$ \- v7 e/ g+ y( `
  21.         }# ^/ H4 t% t5 L& I2 [: p4 Q$ q
  22.         /* Output compare event */
    8 t$ H4 Q! H3 x8 U
  23.         else9 t8 f& d! b' j; R+ n. n
  24.         {
    * W6 i! ]3 c- h# f- ^% t. P
  25.           HAL_TIM_OC_DelayElapsedCallback(htim);
    * m. d  p2 W/ ?
  26.           HAL_TIM_PWM_PulseFinishedCallback(htim);) D7 K5 S7 H6 r2 }3 I0 i, Q
  27.         }
    9 `) J2 \0 W1 t% _- }3 j3 H5 M
  28.         htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    ' T8 Y& M) s# x8 K( a
  29.       }
    $ E6 E8 S3 V& r% `9 }* \$ r
  30.     }
    2 M/ G; B5 a; Z1 {1 g- B2 Y/ V
  31.   }5 \& L* Z7 p" ?. m
  32.   /* Capture compare 2 event */0 W3 e/ ~4 s& m( D
  33.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
    - r- p' w- K0 K7 t. W9 {4 v
  34.   {
    ! i/ W) i# X$ w5 s4 A$ P
  35.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
    & Y% m4 n; l/ @7 D+ r% {6 w- O8 p
  36.     {
    ) A% ?* {' C$ c' A
  37.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
    * v( F6 n- g7 ~+ T5 u
  38.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
    3 W3 f& _' t% _( t, L3 [2 {1 U  T5 ~
  39.       /* Input capture event */. x& n- c- b, A# z- b
  40.       if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
    & i4 [/ W! x3 V6 c+ g+ i
  41.       {! j! U9 c  f, \* z# k
  42.         HAL_TIM_IC_CaptureCallback(htim);2 t/ @: c% W" d$ s$ x" j
  43.       }. x4 g5 A5 y8 P0 Y7 U9 D) {
  44.       /* Output compare event */; N3 ?8 ~6 B* u+ Q. a
  45.       else
    ) h4 Z5 j; R- \' Z( h$ o- {
  46.       {* ^+ I9 M5 L& a: g' m* o4 _% r
  47.         HAL_TIM_OC_DelayElapsedCallback(htim);0 p# e9 N6 l/ ]
  48.         HAL_TIM_PWM_PulseFinishedCallback(htim);
    $ @# T$ T: `  N( B
  49.       }
    9 z" C0 ?* d( I4 ]
  50.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    3 h( |; s& d. i: U
  51.     }; a  U: c9 Z- e( E8 |
  52.   }
    3 y; @& L* g  L; [, k- f% M
  53.   /* Capture compare 3 event */) E. F2 M( a' y# F
  54.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)+ E" ~) ?, v- ]- w( ^
  55.   {& B$ b8 @1 y) O8 L! B) w: ]4 C
  56.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
    3 N" q5 J; p" J* O' Q
  57.     {% X$ b5 c6 a% P  J% K
  58.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
    ! F% p: f7 \' S6 N
  59.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
    & t$ U& [6 `/ t0 [2 |0 o1 H
  60.       /* Input capture event */
    0 p; ]) ?6 l7 i# X
  61.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)" }/ L. i7 I* m) z& ]9 a4 `2 M
  62.       {
    7 R' s* p/ q5 ]& r9 U
  63.         HAL_TIM_IC_CaptureCallback(htim);
    % E. l$ c8 o( x0 r
  64.       }
    9 G. a: ~! u" x1 ]
  65.       /* Output compare event */8 w% a. m: s" v" |' ~
  66.       else& |( w; h4 t" O% S5 f, T
  67.       {7 m5 S/ m2 g$ O9 q
  68.         HAL_TIM_OC_DelayElapsedCallback(htim);
    ! h, K, S* Z" k" W) w
  69.         HAL_TIM_PWM_PulseFinishedCallback(htim);5 ^: A1 {+ e# S* E8 }- d
  70.       }
    2 u' Z: j" C. M: g
  71.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    8 e; k) n( P2 t/ g! h/ S! t
  72.     }
    9 r9 t" [$ w8 a- v1 i5 u; M% G1 z
  73.   }
    + u& S  `# S% @' U4 P* f' {
  74.   /* Capture compare 4 event */0 _6 J' i2 K" H
  75.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
    # s2 U( B% y5 S7 ?4 Q( w
  76.   {- k9 c* h$ q, W/ l* i2 P
  77.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET)' G7 v" e& w# E$ n0 B6 g
  78.     {
    $ N  k; ?4 Y2 p& H& T8 q
  79.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);2 P! J% m  a5 _
  80.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;9 T" [0 z4 W$ f: ?7 [% M
  81.       /* Input capture event */, w1 t/ z% @: \
  82.       if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U); e( j! B- q4 @$ s* H" j
  83.       {6 w' Z- }' U3 j
  84.         HAL_TIM_IC_CaptureCallback(htim);& U$ x% y( m1 Q9 J# W" o
  85.       }6 W2 y% P. s0 ^" \6 U& z/ d
  86.       /* Output compare event */
    ; T" M8 |( o( J! l6 m. E9 ~7 f/ X
  87.       else
    7 b. i  q% ]9 K7 M; ]; ~
  88.       {
    3 Q5 Q8 E2 {* R# K7 {5 _  j
  89.         HAL_TIM_OC_DelayElapsedCallback(htim);1 G# D) K. {& Z+ D: F. W; e5 \
  90.         HAL_TIM_PWM_PulseFinishedCallback(htim);) C/ ]2 `% J* }+ _  ~9 a$ o/ m
  91.       }, M$ w2 C$ F( U5 u3 I
  92.       htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
    1 c6 f+ F, p3 V2 }4 `2 o
  93.     }
    * {6 D* A( W$ k* N; [3 O7 T% }
  94.   }/ Z, A1 ?( b; p3 L* ]7 ^
  95.   /* TIM Update event */
    ; k" Z* N/ |# G0 \$ c
  96.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
    8 t" }- d( A2 l9 v% d
  97.   {
    0 ]& n$ N: p  p: y+ y- ?
  98.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
    2 r$ J5 s1 ~$ [5 P
  99.     {8 m& l0 I+ d' d) e, A4 c
  100.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);7 }# U+ |. b8 d# u4 ?1 w
  101.       HAL_TIM_PeriodElapsedCallback(htim);( P# Q! l& J$ e5 j+ m0 {
  102.     }
    ' L! D7 M/ q. Z
  103.   }
    1 \7 D" K- a3 c. J
  104.   /* TIM Break input event */
    7 N3 O, V* |) A# J- G
  105.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
    , V; n( `) u4 v$ j7 J
  106.   {  Z0 @% h6 R" j7 l9 |2 @
  107.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)) [% B: v1 v: k# H5 C
  108.     {- _; w4 F% z+ O5 ^0 e, z. h
  109.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);! W/ k/ B8 ]: d- c  k
  110.       HAL_TIMEx_BreakCallback(htim);
    ; y8 j3 F0 V- @9 I% F  ?
  111.     }
    ! X. g7 f- e) o4 ?3 u
  112.   }: B$ @2 t% c3 m! ~% g
  113.   /* TIM Trigger detection event */
    - p" _1 f0 U$ g
  114.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
    ( q. N3 V, m6 a: x- R
  115.   {
    6 p% J; M" e9 P% E  T5 c; n: Z3 R
  116.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET); _2 J! w( @+ C/ r/ V( t: W
  117.     {
    6 y6 P/ h& ^4 [6 _( l3 o9 _
  118.       __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
    7 q& z' ]- w7 x4 Y& B  W- v5 Q
  119.       HAL_TIM_TriggerCallback(htim);
    - W" Q) m3 D3 \# u
  120.     }# p! X" B1 B" x8 T- H
  121.   }
    $ ]& T; y1 Q2 f7 I3 L8 r
  122.   /* TIM commutation event */' X( O9 b0 f# n+ B
  123.   if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET), X, z7 W1 o; ]
  124.   {6 L( H. T9 C" q9 A2 O+ z
  125.     if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET), o) j0 z* a* ~" T. G$ @3 o* g0 z
  126.     {
    ; q% p8 m1 `$ l; O$ m
  127.       __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
    4 i! O+ B( U) s! F& r
  128.       HAL_TIMEx_CommutationCallback(htim);" t( M; P) _8 t1 o4 o
  129.     }* w9 b: Y, a0 j6 h2 N4 `8 y, q: S8 ]
  130.   }
    ' X1 P8 p% @$ }1 {" g; k2 {6 o3 A
  131. }
复制代码
' }- W% {; ]7 n! n% G! p
4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);; e5 C( W( Z+ F6 M4 H. t" c

2 B4 H+ w5 ]+ e8 a& a2 n6 m5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在
  1. HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码2 H8 l0 a& m- ~/ O2 R0 f
  2. 9 U9 j1 S0 E" D" O
  3. void TIM14_IRQHandler(void)" |9 [5 J- x4 o7 B  Q6 K, n  D) P3 d6 d
  4. {
    2 V* f# d/ m; n  H1 P8 x/ o9 ~- I0 J
  5.   HAL_TIM_IRQHandler(&Input_Handle);1 X6 y4 T5 E5 c) ^4 v: U! h
  6. ) W# R8 X# l% i: F: y- f
  7. //其他处理代码
    % h% Y$ X6 j4 v
  8. }
复制代码
' t$ x- a5 s! A
6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。
, [7 ?; \2 U/ a- ?( d6 {' P/ p4 d  O* C
7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。& f9 j  d: ^3 k/ p* T" K* ^( f0 d
& @6 p3 Y( o: v% e' p
8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。5 k# l; C0 J8 w4 U7 }
# f# [. a- [  f4 Z4 Z3 {
在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。
/ @$ S1 V. j" M+ V" r/ g* I  b8 Z( Q8 X
$ `7 W9 ^% \/ w: B4 q- X: V* N9)ken坑啊,都怪对库的执行sh顺序不了解。
) e6 @9 m5 g2 j% j
& }( c7 O8 ?" x
! q1 m' }. B# O0 A4 z2 u4 J
收藏 评论0 发布时间:2021-11-25 16:00

举报

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