|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
Questions:为实现任务的快速响应,应用通常会设计外设中断,在中断函数内响应事件标志对应的回调任务。但大多外设均具备多个可引起中断的事件标志,如何实现回调任务的精确响应将变得尤其重要,本文档旨在介绍一种保障回调任务可被精确响应的方法。* ]- d L Y3 {4 U
i1 U( o# }' `4 ]" R5 {Answer: @) P# ]7 L& K! }7 ~2 _
以下将以USART2为例进行阐述。
$ B! J. v. L6 t/ W5 l+ m8 p0 p6 {8 p8 U8 i7 ~! S8 t6 f
# \3 j0 w( y4 A, b! T中断响应过程及注意事项
8 H. ?7 Q% S0 ?1) 事件标志置位 ; n9 N% m! J4 |* y9 P4 d
当事件标志产生条件成立后,硬件会置位对应的事件标志。
3 {3 B* b- H8 V( p示例:当USART2接收数据缓冲器满时,会立即置位对应的RDBF标志。7 k j" J, Z4 L$ G
注意:事件标志的置位发生在其对应的事件产生条件成立时,不受对应的中断使能状态影响。" O1 U* s$ y: w' X
2) 中断服务响应
9 f$ _7 M5 n/ Q5 U当事件标志,且对应的外设中断处于使能状态时,硬件会通过外设中断通道向内核申请中断服务。0 {" L2 K$ t4 s3 t
示例:当USART2的RDBF标志置位,且RDBFIEN处于开启状态时,硬件会自动通过USART2中断通道向内核申请中断服务,同步置位USART2的NVIC pending位来指示有中断申请出现,以指示代码需要跳转到中断服务函数执行。# C% B2 S* } ]; u
注意:外设中断处于失能状态时,对应的事件标志置位并不会申请中断服务。
% t A: N7 x* v7 O* ^5 m$ J3 W; g+ B3) 中断函数执行
4 @! C0 @9 @2 l# P) N b) l% o在符合中断响应优先级规则条件时,代码就会自动跳转执行中断函数内的回调任务。
/ ]% ^2 G. \% r) L* F由于同一个中断通道具备多个引起中断的事件标志,对应共用同一个NVIC pending位,且该pending位在代码跳转到中断函数后会被硬件自动清零。
) B$ f8 D; B1 d$ m$ Y: q" \" i注意:该NVIC pending位会跟随该中断通道内的任意被使能中断的事件标志置位而置位,其只记录有无,不会累加。并在响应中断函数时被硬件自动清除。
' X# J# H- S x为避免事件标志的回调任务被漏执行或误执行,软件必须要在中断函数内做好事件标志的区分处理。如下建议方法:
+ A# e) Q9 j9 Z: H* Z回调任务漏执行的避免方法
! ] I6 k6 b+ @: N! I当同时使用同一外设的多个事件中断时,中断到底是由什么事件标志产生的须由软件按照如下区分:
8 H# D b$ b3 b6 U6 G3 ^) n: m在中断函数内,查询每一个事件标志的状态来决定是否响应对应的回调任务。
' Z, d9 d- _0 K0 B5 k" _# w示例1:当同时使用USART2的RDBF中断和TDBE中断时,中断函数需如下设计
* g% t: C9 c3 G: e: X4 L void USART2_IRQHandler(void)
# ?2 h: m( j- q+ t{; S9 w2 s; n# l0 U
if(usart_flag_get(USART2, USART_RDBF_FLAG) != RESET)$ {, z1 d2 x; Y
{
$ U) w: b- Y. X$ {7 F3 s /* user code */
0 k. }4 G3 M) d; f3 j& T2 a }+ y v; c3 `" }" w
3 e( Q9 ^9 V; S$ c# |3 u
if(usart_flag_get(USART2, USART_TDBE_FLAG) != RESET)& ]/ V% [% ?3 B' D: _! F+ P
% H, o1 [7 g3 \ {
- b8 D. u( E) I; R /* user code */( H9 h# a! T" T- Q* F' r7 ]5 r
}; o" @) H, a$ b7 G- o
}# }) z0 e! ?3 N1 N- U/ @
- H5 U, B1 d. ]5 h! j
可同步参考如下路径demo示例用法AT32Fxxx_Firmware_Library_v2.x.x\project\at_start_fxxx\examples\spi\halfduplex_interrupt2 B4 F# {6 ?' C6 x- _9 Z
回调任务误执行的避免方法' j# ^4 |% h) N* \3 `0 W2 ~
当分时使用同一外设的多个事件中断时,中断到底是由什么事件标志产生的须由软件按照如下区分:: h% x6 T4 F& c3 ~; W; M1 K
在中断函数内,查询每事件的中断状态及标志状态来决定是否响应对应的回调任务。
* N% z$ l. L# I/ N, g% ~" r. y示例1:当使用USART2的RDBF中断、并分时的使用TDBE中断时,中断函数需如下设计! E+ n( ^& w2 `5 \) p6 \# s: Z" e
void USART2_IRQHandler(void)
& h0 n' I, K% s8 s" ^2 F$ w% u{& c+ ?. {( V3 c0 W
if(usart_flag_get(USART2, USART_RDBF_FLAG) != RESET)/ g1 @! {% s. S" D
{
' G |% U R# \ /* user code */
& l) B A. E4 c R7 e6 a1 |+ h; j: c1 y }
1 P% H) D- v& n% V if(USART2->ctrl1_bit.tdbeien != RESET)/ d$ y0 ~3 e) ~: N g% O
{
7 } p' ~" f* l$ o8 V" H if(usart_flag_get(USART2, USART_TDBE_FLAG) != RESET)
9 [9 m D c; A$ o' T) ]4 T) f {4 [3 ^. r. t8 v3 G2 ~0 e7 k: ?
/* user code */
8 ?! R; d$ E* a! V8 G4 h) x }
( k5 D6 R' Q* K7 T- ] }1 m- M/ z% a2 Z) S. K
}
( ~ ~! x# D; p% ^; O+ T1 }# b6 ?9 k/ x- J5 n
可同步参考如下路径demo示例用法AT32Fxxx_Firmware_Library_V2.x.x\project\at_start_fxxx\examples\spi\halfduplex_transceiver_switch @, B# X* p8 M Y1 t( j" }1 d
4) 中断结束返回
: P/ R+ A4 }( g9 K4 M ?当中断回调任务执行完毕时,软件应该及时清除事件状态标志,随后代码会自动跳转回主函数。; M" M# \# W2 l4 [
|
|