|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
Questions:为实现任务的快速响应,应用通常会设计外设中断,在中断函数内响应事件标志对应的回调任务。但大多外设均具备多个可引起中断的事件标志,如何实现回调任务的精确响应将变得尤其重要,本文档旨在介绍一种保障回调任务可被精确响应的方法。5 u2 ^4 @" t+ z- k* p
$ p3 d) V( S7 b! B8 Z' O8 J9 _
Answer:! W! z+ P+ Q. W/ v% @" l6 ?
以下将以USART2为例进行阐述。9 L! Y: K- _1 Z( l$ r7 p
8 ]# j( `7 |' b% L" j/ p. X# o" P- V" ]
3 q. B8 C1 X; Z/ ]* P中断响应过程及注意事项( @1 P- K; X: g8 E( [5 ?: K
1) 事件标志置位 7 o# r) D7 m. d. c5 q/ w! T
当事件标志产生条件成立后,硬件会置位对应的事件标志。
- v( T! v4 D+ l) Y! U示例:当USART2接收数据缓冲器满时,会立即置位对应的RDBF标志。
/ J" f* G' [( E* d3 E注意:事件标志的置位发生在其对应的事件产生条件成立时,不受对应的中断使能状态影响。
$ m K$ u7 B3 I x$ G2) 中断服务响应2 W9 d s$ Y0 B9 C: A$ a
当事件标志,且对应的外设中断处于使能状态时,硬件会通过外设中断通道向内核申请中断服务。
4 V' P3 S, ]1 {9 |示例:当USART2的RDBF标志置位,且RDBFIEN处于开启状态时,硬件会自动通过USART2中断通道向内核申请中断服务,同步置位USART2的NVIC pending位来指示有中断申请出现,以指示代码需要跳转到中断服务函数执行。
6 x( d* I! d6 P( [注意:外设中断处于失能状态时,对应的事件标志置位并不会申请中断服务。# g' y# V, P4 [( l, n
3) 中断函数执行 q! b" M* W* ^: p" `* T( Y# n
在符合中断响应优先级规则条件时,代码就会自动跳转执行中断函数内的回调任务。
# y* a" a7 y- T0 c; h由于同一个中断通道具备多个引起中断的事件标志,对应共用同一个NVIC pending位,且该pending位在代码跳转到中断函数后会被硬件自动清零。
; b2 ?: u) K& B# s9 B, q4 o注意:该NVIC pending位会跟随该中断通道内的任意被使能中断的事件标志置位而置位,其只记录有无,不会累加。并在响应中断函数时被硬件自动清除。
: z& E& A4 C, L为避免事件标志的回调任务被漏执行或误执行,软件必须要在中断函数内做好事件标志的区分处理。如下建议方法:
4 N. p& @5 Q$ e' f$ a4 V* D& d2 b回调任务漏执行的避免方法
5 ~$ b: a5 C; m' F当同时使用同一外设的多个事件中断时,中断到底是由什么事件标志产生的须由软件按照如下区分:
# P, W$ N' _5 D- K# Z- n# o6 w在中断函数内,查询每一个事件标志的状态来决定是否响应对应的回调任务。
" `8 q% K" A# B( Q) _! e; d示例1:当同时使用USART2的RDBF中断和TDBE中断时,中断函数需如下设计
2 M( K! S T9 G; F! f& ] void USART2_IRQHandler(void)
0 {" l- k7 m! D; E2 b{0 D$ ~' X, k9 R* h) x
if(usart_flag_get(USART2, USART_RDBF_FLAG) != RESET)5 @. q- g* h' ]; D8 F
{9 |5 n+ w( f+ N* `
/* user code */
( T. Y# e! z. y5 f }3 I, U# E2 F2 @6 h, l! C0 j0 @( L
4 l. K0 V5 t1 P7 P& N4 O if(usart_flag_get(USART2, USART_TDBE_FLAG) != RESET), t( S" c. w! j. t' E0 Z, W* B" z% f
0 R. k* T' q3 Q, \( Z {
1 W% q) K0 N' m# w/ ?" S /* user code */
' }* T2 {$ {2 G" ~* b/ P }
0 D% f4 v3 E( r2 h8 z' |- Y+ d}6 r3 t: w' c: i5 W! l9 _
* ~ G1 ~7 L0 K$ I" Z8 z' e
可同步参考如下路径demo示例用法AT32Fxxx_Firmware_Library_v2.x.x\project\at_start_fxxx\examples\spi\halfduplex_interrupt0 N1 O7 f- A, ?
回调任务误执行的避免方法& Q) x4 D. ^) l0 C
当分时使用同一外设的多个事件中断时,中断到底是由什么事件标志产生的须由软件按照如下区分:
' m/ D' U& _+ {" w& r7 g; p( `: ]) c5 u在中断函数内,查询每事件的中断状态及标志状态来决定是否响应对应的回调任务。* H6 X1 x1 h1 o w2 y( Y
示例1:当使用USART2的RDBF中断、并分时的使用TDBE中断时,中断函数需如下设计
9 ?7 \" p/ T: L S8 o( |$ ^ void USART2_IRQHandler(void)! ]8 [ d+ X' R/ o S! a
{" U4 {: p. B' p% _
if(usart_flag_get(USART2, USART_RDBF_FLAG) != RESET)1 f3 ?& m5 a! w: g p% k; ]
{, p! `4 g9 j# ?
/* user code */
7 C, v' O$ a$ D6 k. c }
1 \2 C! {1 u/ E& m) Y/ M& p% v if(USART2->ctrl1_bit.tdbeien != RESET)
/ K- w& ~2 g- \3 Y {$ e3 }$ w, \ e' r# K
if(usart_flag_get(USART2, USART_TDBE_FLAG) != RESET)
/ u2 p% S: t& \# ]( Z( N; _; d {; o# F; e5 j; J5 ?' A* {
/* user code */1 y) s! [- i) j/ f- U2 l/ M; R
}! ^8 i2 }/ |) S z- y# V1 a. j
}& N9 K; u' K; ^9 A) S& \8 b
}
0 t! y- l. o/ M& A8 r
3 G) b9 A: C+ K* `! X& w8 V可同步参考如下路径demo示例用法AT32Fxxx_Firmware_Library_V2.x.x\project\at_start_fxxx\examples\spi\halfduplex_transceiver_switch1 d6 h9 \: X" a$ [+ [
4) 中断结束返回! n$ m4 ?4 o, U% {3 K" {; h, _
当中断回调任务执行完毕时,软件应该及时清除事件状态标志,随后代码会自动跳转回主函数。5 M* `# N) Y/ P! m/ R3 y, z" B) E4 S3 u
|
|