1)STM32F0有多个定时器,对应多个IRQn
+ S7 v( w t! G0 y+ D: Y1 c- TIM1_BRK_UP_TRG_COM_IRQn = 13, /*!< TIM1 Break, Update, Trigger and Commutation Interrupt */
2 P5 U9 g, U( F$ T1 ? i - TIM1_CC_IRQn = 14, /*!< TIM1 Capture Compare Interrupt */
2 s+ o) A6 \. {% e: }) d# @5 @ - TIM3_IRQn = 16, /*!< TIM3 global Interrupt */
1 Q9 e7 m/ b& j# s K. z& L2 M3 w4 G1 w - TIM6_IRQn = 17, /*!< TIM6 global Interrupt */5 Z6 O" Q: G3 F' P& _7 T( C
- TIM14_IRQn = 19, /*!< TIM14 global Interrupt */
/ y" P- Y8 s# q* N* \. [1 ]( B6 @ - TIM15_IRQn = 20, /*!< TIM15 global Interrupt */
4 @6 t$ e1 g9 b, C - TIM16_IRQn = 21, /*!< TIM16 global Interrupt */9 ?8 v c3 z7 y* ^9 q5 ?
- TIM17_IRQn = 22, /*!< TIM17 global Interrupt */
复制代码
9 X. c6 `; Y* }+ x* C+ F2)通常每个IRQn对应一个zho中断函数) Z9 X" H& x; \" I( J6 L
- /**5 g6 y: k; ?& V" B( M, {# k! M) z
- * @brief This function handles TIM14 global interrupt request.
/ Z/ M5 z3 f9 i% A3 N& v3 @- L - * @param None& ]5 D$ B% n9 k9 u e* S, r4 q
- * @retval None( p3 P. J' ~# n H' a
- */, {- I& j3 A# i. c) u; {* E
- void TIM14_IRQHandler(void)5 Y) m" j5 o' z
- { ( r$ E9 ?5 j( t& D$ y: x
- HAL_TIM_IRQHandler(&Input_Handle);
1 D8 f5 ~ z* j# I4 m% d - }
复制代码 1 ]6 T6 m! {$ `+ C
3)中断函数里通常会调用HAL_TIM_IRQHandler(&Input_Handle);这个函数来区分是哪一种中断
1 W# `" m" o: O; v8 o
$ |* t8 M, D( D- /**
[% ~8 M4 ~3 H - * @brief This function handles TIM interrupts requests.
1 k8 {' e* D ?" j, _# x6 B - * @param htim TIM handle
* G9 v9 c# p! }9 g$ Y - * @retval None3 P U: k( h, T/ F+ a6 |; K0 g2 Q' N
- */
; n3 H$ T/ V8 S9 w' \ - void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)& o4 K6 S+ R& g$ t( ]$ j
- {, Z" J( a- m/ J1 U6 ]6 _ m, Z
- /* Capture compare 1 event */; A; {3 U6 [4 y9 }, G2 p
- if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET), C B v$ m, W% _
- {
, U' t) l- z8 p4 l$ Y - if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)( v- s5 m# k1 ^3 |+ |
- {
3 o( ~0 n3 S. q m, x& \ - {; l6 Q2 N; `2 {) Q
- __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
& ?" z: {+ c4 d" d+ J7 U - htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
! q1 J/ v3 o0 b% n/ D. A k
: R: X0 K7 s, t- /* Input capture event */
$ \( C' C. x$ q: i( ?! A0 k - if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
- {1 ]- u' {/ ^/ A7 g - {
, p: W" U% f% }% N - HAL_TIM_IC_CaptureCallback(htim);
! N$ R& w! r8 G% p& S( K5 e& x - }9 k: d* c: l y, r; V; M
- /* Output compare event */
+ S, Q, S8 z; a; A - else: o+ Q+ O* S- f4 e# C+ ^
- {
8 R( I+ d) P. u2 ?& \1 \+ j - HAL_TIM_OC_DelayElapsedCallback(htim);
' I6 T C, i4 x$ `0 h3 ` - HAL_TIM_PWM_PulseFinishedCallback(htim);
0 S% s' J0 j0 d- ]) g# B - }
8 q# P. }# E5 l& J6 U5 r5 O# _ - htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
, I8 m' c; R& M$ i; x - }
4 |& H. J0 I+ ] - }
2 C; E3 e- f! N6 I+ a, p - }
. S6 j& T% } \( v V& r - /* Capture compare 2 event */: _' j: N7 N# f( m. T
- if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
$ c1 X y2 ?0 W% t3 O! a - { N" {, @9 z9 K$ t# o, Q
- if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
# l# M7 U3 n3 y. b& h - {
U2 G4 T+ d) u2 F8 A- ^5 t - __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
% V3 L! ^) J) @) q5 ]7 Y1 ?% C - htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;5 H0 h. ~9 a) I0 k* K6 W4 I: \& K2 v) c
- /* Input capture event */# ]4 M1 M, G1 y! h
- if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
+ ^0 V H$ c. U @( l. e - {: v2 W) [; A/ p+ G
- HAL_TIM_IC_CaptureCallback(htim);
& ]$ l/ k: j' `9 Y- P$ y1 L0 q& h - }$ }# X& A+ F/ B' O" d) @( g8 |
- /* Output compare event */
R( R+ o( u) s7 ]6 _ - else
' b9 D0 W; `4 {% V$ v8 V$ i( C - {" z) e f8 {9 F8 z1 h/ z# S
- HAL_TIM_OC_DelayElapsedCallback(htim);
# Z/ V& U) G' \( s - HAL_TIM_PWM_PulseFinishedCallback(htim);- z4 z" I% h/ A2 I, [) O% u8 u
- }
% Z5 H- t$ t& d; v( Z7 h+ I - htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;; q3 y7 U B& D" ?- R0 D; u/ q
- }
- s: ~9 B! a, `0 m. P; C6 ~ - }$ h0 {, j @% @5 y# g5 [. w( S
- /* Capture compare 3 event */
* @0 b- ?; j& H& v; e7 M/ Z$ b - if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)$ J! K( m7 t- p; q! r* Q j
- {
4 ?! s+ D; o0 F% y - if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET)
( b+ \# r8 a+ e3 H - {% c/ V9 e9 B8 H" Q5 G( y
- __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
8 p7 X' M% [# q9 C7 G) S - htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
1 \( S$ C. K" A4 I - /* Input capture event */, M' w& Q# q1 L+ n
- if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
9 P2 v1 t1 ^; N& M; d" Q' C$ _. u - {1 }9 x1 d q& l+ \- o
- HAL_TIM_IC_CaptureCallback(htim);
- y A9 O; `: j& n* ?: C - }
# Y$ ~' i0 [1 Q1 u - /* Output compare event */1 @' d( C: g0 {: V
- else
# ^, z8 _1 a. ^$ t, p. k1 J5 o - {
9 I4 V$ R; p1 C1 O4 l& L - HAL_TIM_OC_DelayElapsedCallback(htim);/ i- D7 [. Q, ^4 w V+ V$ P
- HAL_TIM_PWM_PulseFinishedCallback(htim);5 u6 {7 p1 v# S* x. E& H
- }; l5 f6 ^; G7 @- |3 h o* B
- htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
; U5 P: E# Q) p( |5 \& B& q - }6 k# t; N/ A( u8 z
- }
# [- K1 D h1 z2 g - /* Capture compare 4 event */
) h; E7 t4 \ r' `2 a ` - if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
* h; W7 e6 q# O2 N# w - {
+ m: r* X' D7 {8 a0 y$ z6 A# _4 K - if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET): x2 I5 U! o; w' Y5 t$ |- [
- {
: Q7 @! C8 ^4 P9 |2 r$ a5 k( R - __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
! U3 z8 N* J9 ]2 ] - htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;6 g! A V \( T. w/ l- u
- /* Input capture event */
4 j2 c7 C4 n# X - if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
* B4 C: s& l D$ ~ - {* f2 r' z: B& `# A0 k
- HAL_TIM_IC_CaptureCallback(htim);
) `, |0 }/ o! C/ H - }
, U$ }$ y7 K) H' O- o9 V - /* Output compare event */
4 k- z6 l/ H4 o - else' U( J% H: q0 S8 f& [. L
- {
1 |! H, x. ]# u/ f - HAL_TIM_OC_DelayElapsedCallback(htim);+ a5 W$ l6 t, {# M+ g4 \
- HAL_TIM_PWM_PulseFinishedCallback(htim);
- z2 l( j) A; g) ]( P - }
8 ]3 e3 t0 f" j' B: {* a - htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
. s% J1 N: [+ R4 W" }" l - }. A" B0 t% R$ k+ D) o
- }
+ v1 e+ f' M% |6 X0 q$ v( M% m - /* TIM Update event */
$ P g# p% z7 Z) ~ - if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)0 I* H' f x5 y* P0 m
- {3 {5 q6 i3 M$ a$ S9 x6 v2 l7 f7 w
- if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)* v! D' z9 M2 I/ h0 q7 \2 w6 @
- {- V2 R* h/ e0 p0 T9 b5 [
- __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);: k6 F! s+ K$ i' r: s: Z; _ x# H" W
- HAL_TIM_PeriodElapsedCallback(htim);
1 j7 Y' Z+ J p! W( H1 L - }
- y! u. ?) x2 K2 e - } |: x' p) K( W9 n; G
- /* TIM Break input event */
/ |3 [1 X+ ^6 s( o9 _ - if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
" o: h4 c% b) P ]3 ?2 B - {, h8 ^: ]' I6 T: r# t
- if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET)1 z# T9 j3 f- T; y" L7 ~" k
- {
, [3 m. {/ Y X7 i1 z - __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
2 [! D+ u7 x4 t3 R - HAL_TIMEx_BreakCallback(htim);
' N) Y- i4 i. K: W - }. H9 Y& Z* U7 I& p5 f
- }
( c; ~/ ]2 v4 x& ~9 W- w, [ - /* TIM Trigger detection event */2 W/ ?8 D- w8 h5 L$ S) ^' d" o J
- if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)1 J7 X3 U! h( _5 z) f6 B" V* W
- {
- E3 R- H' R' L2 L5 m; i - if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET)6 Z2 b9 W+ L5 C' C4 {! b
- {
% M$ K/ S. }! s2 \4 t - __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
* \8 {& f6 t1 \8 [2 w j - HAL_TIM_TriggerCallback(htim);
! I E5 U6 V# [+ a* V; U" H - }
0 |/ z2 p' l# B* k, _) q - }
( z6 ?- l' |$ q6 M) v - /* TIM commutation event */
! ?5 M! u6 K# Q4 z+ E' n - if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)6 g6 ~: ]/ F! d+ ?$ }" t
- {) A2 p4 w6 a9 r! R
- if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET)1 P; A: D& v. H' {8 V; u
- {
$ J# N5 S. l9 O6 J R' u - __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
* ^8 Q( i: ?* B) `* t! j - HAL_TIMEx_CommutationCallback(htim);) l+ i/ {- |! M7 H, W
- }
: w/ B" ]8 Y8 d# U& J - }" Q# ?; l4 V, n; L& K, s
- }
复制代码
! F$ e. T: u$ U4)在这个函数里根据不同的中断,调用不同的回调函数,像最基本的计时中断,调用HAL_TIM_PeriodElapsedCallback(htim);
' } ^! }; w% l/ C {4 s
- J$ n) |4 J- Q6 {5)问题来了:当我的程序需要用多个di开始定时器时,而且有相同的中断。开始我以为可以在- HAL_TIM_IRQHandler(&Input_Handle);后面写自己的处理代码
4 K4 z" E' `4 S- m1 a+ z, k1 `( {
( h+ S5 `1 o& r2 g) B' ]4 k+ r- void TIM14_IRQHandler(void)5 r f6 }# i5 q, E6 I
- {
, ~% l, `" A& Q - HAL_TIM_IRQHandler(&Input_Handle);
. @4 d7 v/ A" H* ? l( ~
3 w c+ g, {; d0 e- //其他处理代码4 z. R) h0 D$ B
- }
复制代码 2 b* Y$ T. F9 Y* Z) Y8 n' e. X
6)但是,在使用Freemodbus的时候FreeModbus用到的定时器在HAL_TIM_PeriodElapsedCallback(htim)中执行了TIMERExpiredISR();这个函数。
1 L. [! o9 g _. y# ~ J: G7 k% Y+ d' B
7)当我用到另一个别的定时器的的时候,因为我在HAL_TIM_PeriodElapsedCallback(htim)这个函数里没有区分是哪个定时器产生的中断,所以当其他定时器产生中断时也顺便执行了属于FreeModbus的这个TIMERExpiredISR();处理函数。
' J3 h5 L: d, [& Q: I; ], K
3 e4 B2 u3 T! n: b& d8)这样就导致了一个奇怪的xian现象:只有我一启动别的定时器。主机Modbus Poll的时候就会出现Timeout的情况。
/ T$ W6 {1 N# C' A: M n7 u
" F' D# U/ {% G6 y' y) G在HAL_TIM_PeriodElapsedCallback(htim)中区分zh中断来源之后,问题就解决了。
. R) x) u6 U+ |3 Z
0 P! V+ _$ T& g3 }9)ken坑啊,都怪对库的执行sh顺序不了解。3 ~2 Z; d2 u8 p& O
& L% P" ]& Z# y& ]; y% `9 D& B
# `1 |( _1 C) z- ^2 }; |8 C
|