外部中断/事件控制器包含多达 23 个用于产生事件/中断请求的边沿检测器。每根输入线都可 单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发)。每根输入线还可单独屏蔽。挂起寄存器用于保持中断请求的状态线。
4 n5 ^3 d8 s2 v
8 k! q* N% `0 V" ~% P# q4 H功能说明
f" R) r. q5 o& D" f+ y$ U要产生中断,必须先配置好并使能中断线。根据需要的边沿检测设置 2 个触发寄存器,同时在 中断屏蔽寄存器的相应位写“1”使能中断请求。当外部中断线上出现选定信号沿时,便会产生中断请求,对应的挂起位也会置 1。在挂起寄存器的对应位写“1”,将清除该中断请求。要产生事件,必须先配置好并使能事件线。" G- o: w- F7 R7 E
根据需要的边沿检测设置 2 个触发寄存器,同时 在事件屏蔽寄存器的相应位写“1”允许事件请求。当事件线上出现选定信号沿时,便会产生事件脉冲,对应的挂起位不会置 1。通过在软件中对软件中断/事件寄存器写“1”,也可以产生中断/事件请求。! U( R/ G) C! Y |; f
9 V: i5 {' O" t9 q& [7 `硬件中断选择; S% f' S0 D' n9 Y! d
要配置 23 根线作为中断源,请执行以下步骤:
, V( D1 M# z, R8 ^: T● 配置 23 根中断线的屏蔽位 (EXTI_IMR)
0 K0 I3 G- `1 i! Z+ ]0 o ~● 配置中断线的触发选择位(EXTI_RTSR 和 EXTI_FTSR)
: b4 R. [ q1 j1 \% Z" a● 配置对应到外部中断控制器 (EXTI) 的 NVIC中断通道的使能和屏蔽位,使得 23 个中断线中的请求可以被正确地响应。) c" ?% y E1 s, O. B
( e$ j3 _7 t9 y2 H i, m
硬件事件选择
/ j3 A& q" n" }" Q要配置 23 根线作为事件源,请执行以下步骤:
" p7 s4 }5 {2 o! z/ x● 配置 23 根事件线的屏蔽位 (EXTI_EMR): W8 R! Q1 b) O! B5 c
● 配置事件线的触发选择位(EXTI_RTSR 和 EXTI_FTSR)
# \3 e2 t! J/ E! c1 M7 Q/ g5 ^$ T: Q. x. M$ n7 X- m& K
软件中断/事件选择
& H$ i# x8 N$ ~% }可将这 23 根线配置为软件中断/事件线。以下为产生软件中断的步骤。
8 ^; ]9 s9 M' s9 g● 配置 23 根中断/事件线的屏蔽位(EXTI_IMR、EXTI_EMR)
/ I& O8 a2 s# q! F' M0 e; L4 Q● 在软件中断寄存器设置相应的请求位 (EXTI_SWIER)) R4 [2 Y8 F* x* o: c2 e1 _$ I
8 m( p8 Q0 d9 i0 M6 j) TGPIO中断线
( w) C; a8 [! [) u% ?* h2 p; EGPIOX0都是共用一根总线的。
5 A. x. D O; N3 _9 E6 ?; e
9 M+ c& A9 Z. F. L5 f4 W
( G. z- I+ z/ R& l
6 O0 S8 B2 R% m X& B1 |
( B! e& ~( g6 l: b/ D
8 h- e( t3 @( ^6 } w
$ P: M' I1 H: C' j) d4 Q
' s9 |6 O- w8 `, c \
; j9 \5 d6 T" j# c+ w
0 y* r9 _: k0 ^ M! K: D; R8 v, B* A5 Z
3 P% @5 i; ^' ]% @7 ?
* C6 n4 ?( q+ O( G X
6 W. f3 ?7 ]! l! N8 C
6 o% @$ s! E% ~$ Q" q6 ^. T* k2 U" n4 X+ V
配置步骤:
7 e# l1 Y I! E: v( n拿硬件中断来说:
) E$ t# g% b6 J- ]9 B● 配置 23 根中断线的屏蔽位 (EXTI_IMR)
8 d1 Y' ]1 I8 R! }● 配置中断线的触发选择位(EXTI_RTSR 和 EXTI_FTSR)
6 a6 m3 q* _( `* _) y. `. X● 配置对应到外部中断控制器 (EXTI) 的 NVIC中断通道的使能和屏蔽位,使得 23 个中断线中的请求可以被正确地响应。
2 @" D8 e( }* _. q) ?
i5 f! B1 [8 X0 G& T+ x: x! d比如我要开GPIO_A0的外部中断,按照上述步骤:
! V1 s7 N3 }& n# j# O: R& h6 C1.配置中断屏蔽位:PA0是挂在EXTI0线上,所以EXTI_IMR bit0 = 1
. E L; l* n3 ^6 r2.配置触发选择位:也是EXTI_RTSR 和 EXTI_FTSR 的bit0 = 1, [- ^" q4 y8 Q2 v6 A5 |
3.调用NVIC控制寄存器开启EXTI0的中断# z% }. k$ v C, t* v1 X
; H" K: _; `) `这里只是讲到了使用中断线,那么一根中断线上挂载了那么多GPIO的中断,我们怎么判断具体是哪个GPIO[0-15]发出的中断呢?
* N9 \# z- Z% L* }" q, _6 K- ^( A这里就要提到SYSCFG外部中断配置寄存器了:
, K# {3 j5 P5 n- J* p ?+ o/ Q& p/ @- P* e' x$ T0 H/ _
% u% z+ c& {$ E1 h$ M3 W5 ~& T1 I# }
" B2 B3 i: x2 M8 ]
设置下面的寄存器值就能把具体的gpio跟中断线连接起来。0 A" G+ p/ C9 p4 Q& \
代码实现:
- m p! X" I/ Y0 Y1 a' Y, T: u- g; I- void KEY_IRQ_NVIC_init()2 m1 Q1 Y# V3 `) O/ b2 G3 i
- {! R" Y) \! J8 c( p/ x
- NVIC_InitTypeDef NVIC_InitStructure;5 F& |" w5 b" t
- NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
) L& |9 o+ b0 |7 Q, B - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0X01;
2 X3 |, V+ P8 y' j( R |" [) V5 y - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0X02;# ]0 B2 i* R6 k2 Z3 d' a8 Q
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ S) T. ~2 s4 M* t - NVIC_Init(&NVIC_InitStructure);
* U7 |1 x1 r0 M+ o - }
/ E. n+ c: a3 P! Q/ g% j2 V
) x( a5 X& W) ]' `, v L- void KEY_IRQ_init()* y2 P. z3 ]' Q$ Y
- {
: D! N% G$ z. d8 c - EXTI_InitTypeDef exit_def;9 S9 [: ` W& d5 Y! p3 n
- EXTI_StructInit(&exit_def);6 t, f# c) p' @( a: i& p
- + i" F3 `5 L5 N
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//ENABLE CLOCK1 j0 h3 c. A8 t: d
- SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);, T1 D+ M3 h1 W" f- l3 J& d
2 _' _% n2 F9 L- exit_def.EXTI_Line = EXTI_Line0;9 s8 K' q6 h1 @( {
- exit_def.EXTI_Mode = EXTI_Mode_Interrupt;# D8 v! V/ P) K0 x# e: p
- exit_def.EXTI_Trigger = EXTI_Trigger_Falling;
' w# T% [/ a% ^# {* F - exit_def.EXTI_LineCmd = ENABLE;
8 l* p6 E7 d' x" _0 R - EXTI_Init(&exit_def);
5 C0 U% Z8 K& j$ R" x4 L' j1 O5 J' L - KEY_IRQ_NVIC_init();
! M! G) ^/ U# w0 K* \ - }
3 D5 t* J' ^- w* `# [4 | - 9 T- ?- O6 j N4 @8 {
- void KEY_Init(){+ w0 Q3 `8 U* A' K' j! T4 t
- GPIO_InitTypeDef GPIO_InitStructure;$ z* C5 ^0 H# O' G
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
1 a9 s" H1 }6 l8 E - GPIO_InitStructure.GPIO_Pin = KEY1_PIN;
, ?, v& j$ S. e! c) F - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;' D, L0 V2 m* Y( A! q- l m
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;8 l! I1 m7 L2 D+ p, w
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
. O& G3 V, ?) Y% `7 w4 _+ n4 F6 w! j - GPIO_Init(GPIOA, &GPIO_InitStructure);
1 d* i/ D. P B5 H - % |% y4 _, i2 F
- KEY_IRQ_init();
- g( Q/ \0 j7 I; j( c" z - }
0 E( n3 f" o1 N+ I/ G, Q
! k3 o% L6 y, ?+ x- void EXTI0_IRQHandler()
# N* y6 [4 n6 n8 s4 U8 a - {% f: M0 P3 c) S7 Z) Q# P! v
- //EXTI_ClearITPendingBit(EXTI_Line0); 跟EXTI_ClearFlag(EXTI_Line0);功能一样的,都是清理挂起寄存器。' ?5 K k2 s$ O: a. [
- EXTI_ClearFlag(EXTI_Line0);
3 ^) h; _9 x1 @. b2 M! o - LED1_ON();) p, r7 I, E& [! s8 X
- printf("you press key\n");3 c$ Q: ]# F& q! |. b' j
- }9 v0 J' Y8 w+ X! q
复制代码
. d. z, p, Z! P! O, h0 }: G————————————————8 A: ^6 a6 c* o. z& [
版权声明:tony++
y0 ]' H0 K" A
3 S! b% o6 G. r/ S( M. c7 d2 A' h" ], T
|