Mini2440裸机开发之中断控制器
一、S3C2440上的中断
1.1 中断概述
S3C2440A 中的中断控制器接受来自60 个中断源的请求。提供这些中断源的是内部外设,如DMA 控制器、 UART、IIC 等等。在这些中断源中,UARTn、AC97 和EINTn 中断对于中断控制器而言是“或”关系。
当从内部外设和外部中断请求引脚收到多个中断请求时,中断控制器在仲裁步骤后请求ARM920T 内核的FIQ 或IRQ。
1.2 中断过程
(1) 如果是不带子中断的内部中断
如果是不带子中断的内部中断发生后,中断发生后SRCPND相应位置1,如果没有被INTMSK屏蔽,那么等待进一步处理 。
(2) 如果是带子中断的内部中断
如果是带子中断的内部中断,中断发生后SUBSRCPND相应位置1,如果没有被INTSUBMSK屏蔽,那么SRCPND相应位置1,等待进一步处理。
几个SUBSRCPND可能对应同一个SRCPND,SRCPND和SUBSRCPND对应关系:
SRCPND | SUBSRCPND |
INT_UART0 | INT_RXD0,INT_TXD0,INT_ERR0 |
INT_UART1 | INT_RXD1,INT_TXD1,INT_ERR1 |
INT_UART2 | INT_RXD2,INT_TXD2,INT_ERR2 |
INT_ADC | INT_ADC_S, INT_TC |
INT_CAM | INT_CAM_C, INT_CAM_P |
INT_WDT_AC97 | INT_WDT, INT_AC97 |
(3) 如果是外部中断
EINT0-EINT3发生后SRCPND相应位置1,如果没有被INTMSK屏蔽,那么等待进一步处理。
EINT4-EINT23发生后EINTPEND相应位置1,如果没有被EINTMASK屏蔽,那么SRCPND相应位EINT4-7或EINT8-23置1,如果没有被INTMSK屏蔽,等待进一步处理。
几个EINTPEND对应同一个SRCPND,对应表如下:
SRCPND | EINTPEND |
EINT0 | EINT0 |
EINT1 | EINT1 |
EINT2 | EINT2 |
EINT3 | EINT3 |
EINT4~7 | EINT4-EINT7 |
EINT8~23 | EINT8-EINT23 |
1.3 中断处理逻辑
三种中断都等待进一步处理了。接下来从SRCPND往下看,看INTMSK。如果中断被屏蔽了,就不用说了(注意:快中断也能被屏蔽)。如果没有被屏蔽,那看一下中断模式:
- 如果中断模式是快中断,那么直接 出来进入FIQ;
- 如果是普通中断,那么SRCPND可以有多位置1(FIQ 只能有一个),这时就会经过PRIORITY选出一个优先级高的,然后把根据选 出的中断把INTPND相应位置1(注意:只能选出一个),进入IRQ,让CPU处理。
1.4 中断开启
- 如果是不带子中断的内部中断,只需设置INTMSK,让它不屏蔽中断就可以了;
- 如果是带子中断的内部中断,需设置INTSUBMSK和INTMSK,让它门不屏蔽中断就可以了;
- 如果是外部中断,对于EINT4-23需要设置EINTMASK和INTMSK。对于EINT0-EINT3只需设置INTMSK;
1.5 中断清除
- 如果是不带子中断的内部中断,只需清除SRCPND、INTPND,注意清除需位置1。
- 如果是带子中断的内部中断,需清除SRCPND和SUBSRCPND、INTPND,注意先清除SUBSRCPND,再清除SRCPND。 因为,如果你先清除SRCPND的话,然后在清除SUBSRCPND的过程中,SRCPND会以为又有中断发生, 又会置1,也就是说一次中断会响应两次。所以必须先掐断源头。
- 如果是外部中断,对于EINT4-23需要清除EINTPEND和SRCPND、INTPND(同样注意顺序)。对于EINT0-EINT3只需清除SRCPND、INTPND。
二、中断寄存器
在阅读下面内容之前,你需要了解ARM的寄存器体系,其中主要包括CPSR 和 SPSR 寄存器,如果不了解,可以看我之前的博客介绍,嵌入式Linux之常用ARM汇编。
2.1 程序状态寄存器(PSR)的F位和I位
如果ARM920T CPU 中的PSR 的F位被置位为1,CPU 不会接受来自中断控制器的快中断请求(FIQ)。同 样的如果PSR 的I 位被置位为1,CPU 不会接受来自中断控制器的中断请求(IRQ)。因此,中断控制器可以通过清除PSR 的F位和I位为0,并且设置INTMSK 的相应位为0来接收中断。同理我们关中断也包含两步:
(1) 我们可以开启SVC模式,关闭fiq,irq中断,如下:
set_svcmode:
mrs r0,cpsr /* r0 = cpsr */
bic r0,r0,#0x1f /* M[4:0]清0 */
orr r0,r0,#0xd3 /* 设置为SVC模式,并关闭fiq,irq中断 */
msr cpsr,r0 /* cpsr = r0 */
mov pc,lr /* bl指令将下一条指令地址复制到了lr,子程序返回 */
我们先用bit指令将处理器模式为[4:0]请零,然后采用ORR或指定将模式位设置位10011,即SVC模式,同时将[7:6]位置1,关闭fiq、irq中断。
(2) 设置INTMASK屏蔽中断
disable_interrupt:
mvn r1,#0x00 /* 取反赋值 r1 = 0xffffffff */
ldr r0,=0X4A000008
str r1,[r0] /* INTMASK每一位均写1 屏蔽中断
mov pc,lr
2.2 中断模式(INTMOD)
ARM920T有两种中断模式的类型:FIQ 或IRQ。所有中断源在中断请求时决定使用哪种类型。
INTMOD寄存器由32 位组成,其每一位都都涉及一个中断源。如果某个指定为被设置为1,则在FIQ(快中断)模式 中处理相应中断。否则则在IRQ 模式中处理。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTMOD | 0X4A000004 | R/W |
中断模式寄存器 0:IRQ模式 1:FIQ模式 |
0x00 |
寄存器的每一位和2.5节每一个中断源一一对应,比如[31]:INT_ADC、[30]:INT_RTC。
注意:如果中断模式在INTMOD 寄存器中设置为FIQ 模式,则FIQ 中断将不会影响INTPND 和INTOFFSET 寄存 器。这种情况下,这2 个寄存器只对IRQ 中断源有效。
2.3 中断挂起寄存器(SRCPND、INTPND)
S3C2440A 有两个中断挂起寄存器:源挂起寄存器(SRCPND)和中断挂起寄存器(INTPND)。这些挂起寄存器表明一个中断请求是否为挂起。当中断源请求中断服务,SRCPND 寄存器的相应位被置位为1,并且同时在仲 裁步骤后INTPND 寄存器仅有1 位自动置位为1。如果屏蔽了中断,则SRCPND 寄存器的相应位被置位为1。这 并不会引起INTPND 寄存器的位的改变。当INTPND 寄存器的挂起位为置位,每当I 标志或F 标志被清除为0 中 断服务程序将开始。SRCPND 和INTPND 寄存器可以被读取和写入,因此服务程序必须首先通过写1 到SRCPND寄存器的相应位来清除挂起状态并且通过相同方法来清除INTPND 寄存器中挂起状态。
寄存器 | 地址 | R/W | 描述 | 复位值 |
SRCPND | 0X4A000000 | R/W |
指示中断请求状态 0:中断未被请求 1:中断源声明了中断请求 |
0x00 |
寄存器的每一位和2.5节每一个中断源一一对应,比如[31]:INT_ADC、[30]:INT_RTC。
中断挂起寄存器中32 位的每一位都表明了是否相应未屏蔽并且正在等待中断服务的中断请求具有最高的优先 级。当INTPND 寄存器在优先级逻辑后被定位了,只有1 位可以设置为1 并且产生中断请求IRQ 给CPU。IRQ 的 中断服务程序中可以读取此寄存器来决定服务32 个中断源的哪个源。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTPND | 0X4A000010 | R/W |
指示中断请求状态 0:中断未被请求 1:中断源声明了中断请求 |
0x7F |
寄存器的每一位和2.5节每一个中断源一一对应,比如[31]:INT_ADC、[30]:INT_RTC。
注意:如果FIQ 模式中断发生,则INTPND 的相应位将不会打开因为INTPND 寄存器只对IRQ 模式中断可见。
2.4 中断屏蔽寄存器(INTMASK)
此寄存器表明如果中断相应的屏蔽位被置位为1 则禁止该中断。如果某个INTMSK 的中断屏蔽位为0,将正常 服务中断。如果INTMSK 的中断屏蔽位为1 并且产生了中断,将置位源挂起位。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTMASK | 0X4A000008 | R/W |
决定屏蔽哪个中断源。被屏蔽的中断源将不会服务 0:中断服务可用 1:屏蔽中断服务 |
0xFFFFFFFF |
寄存器的每一位和2.5节每一个中断源一一对应,比如[31]:INT_ADC、[30]:INT_RTC。
2.5 中断源
中断控制器支持60个(EINT4~8、EINT8~23算多个)中断源,并分为6个仲裁组ARB5、ARB4、ARB3、ARB2、ARB1、ARB0。
2.6 中断优先级
每个仲裁器可以处理基于1 位仲裁器模式控制(ARB_MODE)和选择控制信号(ARB_SEL)的2 位的6 个中断请求,如下:
- 如果ARB_SEL 位为00b,优先级顺序为REQ0、REQ1、REQ2、REQ3、REQ4 和REQ5。
- 如果ARB_SEL 位为01b,优先级顺序为REQ0、REQ2、REQ3、REQ4、REQ1 和REQ5。
- 如果ARB_SEL 位为10b,优先级顺序为REQ0、REQ3、REQ4、REQ1、REQ2 和REQ5。
- 如果ARB_SEL 位为11b,优先级顺序为REQ0、REQ4、REQ1、REQ2、REQ3 和REQ5。
请注意仲裁器的REQ0 的优先级总是最高并且REQ5 的优先级总是最低。此外,通过改变ARB_SEL 位,可以轮换REQ1 到REQ4 的顺序。
此处,如果ARB_MODE 位被设置为0,ARB_SEL 位不能自动改变,这使得仲裁器操作在固定优先级模式中 (注意即使在此模式中,也不能通过手动改变ARB_SEL 位来重新配制优先级)。另一方面,如果ARB_MODE 为 1,ARB_SEL 位会被轮换方式而改变,例如如果REQ1 被服务,ARB_SEL 位被自动改为01b 以便REQ1 进入到 最低的优先级。ARB_SEL 改变的详细结果如下:
- 如果REQ0 或REQ5 被服务,ARB_SEL 位不会改变 ;
- 如果REQ1 被服务,ARB_SEL 位被改为01b;
- 如果REQ2 被服务,ARB_SEL 位被改为10b;
- 如果REQ3 被服务,ARB_SEL 位被改为11b;
- 如果REQ4 被服务,ARB_SEL 位被改为00b。
寄存器 | 地址 | R/W | 描述 | 复位值 |
PRIORITY | 0X4A00000C | R/W |
IRQ 优先级控制寄存器 |
0x7F |
寄存器位信息:
PRIORITY | 位 | 描述 | 初始状态 |
ARB_SEL6 | [20:19] |
仲裁器组6 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL5 | [18:17] |
仲裁器组5 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL4 | [16:15] |
仲裁器组4 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL3 | [14:13] |
仲裁器组3 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL2 | [12:11] |
仲裁器组2 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL1 | [10:9] |
仲裁器组1 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_SEL0 | [8:7] |
仲裁器组0 优先级顺序设置 00: REQ 0-1-2-3-4-5 01:REQ 0-2-3-4-1-5 10: REQ 0-3-4-1-2-5 11:REQ 0-4-1-2-3-5 |
00 |
ARB_MODE6 | [6] |
仲裁器组6 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE5 | [5] |
仲裁器组5 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE4 | [4] |
仲裁器组4 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE3 | [3] |
仲裁器组3 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE2 | [2] |
仲裁器组2 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE1 | [1] |
仲裁器组1 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
ARB_MODE0 | [0] |
仲裁器组0 优先级轮换使能 0 :优先级不轮换 1:优先级轮换使能 |
1 |
2.7 中断偏移寄存器(INTOFFSET)
中断偏移寄存器中的值表明了是哪个IRQ 模式的中断请求在INTPND 寄存器中。此位可以通过清除SRCPND 和INTPND 自动清除。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTOFFSET | 0x4A000014 | R |
指示IRQ 中断请求源 |
0x00 |
寄存器值和2.5节每一个中断源偏移量对应,比如31:INT_ADC、30:INT_RTC。
2.8 次级源挂起寄存器(SUBSRCPND)
可以通过写入数据到此寄存器来清除SUBSRCPND 寄存器的指定位。只有数据中那些被设置为1 的相应 SUBSRCPND 寄存器的位的位置才能被清除。数据中那些被设置为0 的相应位的位置则保持不变。
寄存器 | 地址 | R/W | 描述 | 复位值 |
SUBSRCPND | 0X4A000018 | R/W |
指示中断请求状态 0:中断未被请求 1:中断源声明了中断请求 |
0x00 |
寄存器位信息:
SUBSRCPND | 位 | 描述 | 初始状态 |
保留 | [31:15] | 未使用 | 0 |
INT_AC97 | [14] | 0:未请求 1:请求 | 0 |
INT_WDT | [13] | 0:未请求 1:请求 | 0 |
INT_CAM_P | [12] | 0:未请求 1:请求 | 0 |
INT_CAM_C | [11] | 0:未请求 1:请求 | 0 |
INT_ADC_S | [10] | 0:未请求 1:请求 | 0 |
INT_TC | [9] | 0:未请求 1:请求 | 0 |
INT_ERR2 | [8] | 0:未请求 1:请求 | 0 |
INT_TXD2 | [7] | 0:未请求 1:请求 | 0 |
INT_RXD2 | [6] | 0:未请求 1:请求 | 0 |
INT_ERR1 | [5] | 0:未请求 1:请求 | 0 |
INT_TXD1 | [4] | 0:未请求 1:请求 | 0 |
INT_RXD1 | [3] | 0:未请求 1:请求 | 0 |
INT_ERR0 | [2] | 0:未请求 1:请求 | 0 |
INT_TXD0 | [1] | 0:未请求 1:请求 | 0 |
INT_RXD0 | [0] | 0:未请求 1:请求 | 0 |
映射到SRCPND:
SRCPND | SUBSRCPND |
INT_UART0 | INT_RXD0,INT_TXD0,INT_ERR0 |
INT_UART1 | INT_RXD1,INT_TXD1,INT_ERR1 |
INT_UART2 | INT_RXD2,INT_TXD2,INT_ERR2 |
INT_ADC | INT_ADC_S, INT_TC |
INT_CAM | INT_CAM_C, INT_CAM_P |
INT_WDT_AC97 | INT_WDT, INT_AC97 |
2.9 中断次级屏蔽寄存器(INTSUBMSK)
此寄存器有11 位,其每一位都与一个中断源相联系。如果某个指定位被设置为1,则相应中断源的中断请求 不会被CPU 所服务(请注意即使在这种情况中,SRCPND 寄存器的相应位也设置为1)。如果屏蔽位为0,则可以 服务中断请求。
寄存器 | 地址 | R/W | 描述 | 复位值 |
INTSUBMSK | 0X4A00001C | R/W |
决定屏蔽哪个中断源。被屏蔽的中断源将不会服务 0:中断服务可用 1:屏蔽中断服务 |
0xFFFF |
寄存器每一位和2.8节中寄存器位信息一致。
INTSUBMSK | 位 | 描述 | 初始状态 |
保留 | [31:15] | 未使用 | 0 |
INT_AC97 | [14] | 0:可服务 1:屏蔽 | 0 |
INT_WDT | [13] | 0:可服务 1:屏蔽 | 0 |
INT_CAM_P | [12] | 0:可服务 1:屏蔽 | 0 |
INT_CAM_C | [11] | 0:可服务 1:屏蔽 | 0 |
INT_ADC_S | [10] | 0:可服务 1:屏蔽 | 0 |
INT_TC | [9] | 0:可服务 1:屏蔽 | 0 |
INT_ERR2 | [8] | 0:可服务 1:屏蔽 | 0 |
INT_TXD2 | [7] | 0:可服务 1:屏蔽 | 0 |
INT_RXD2 | [6] | 0:可服务 1:屏蔽 | 0 |
INT_ERR1 | [5] | 0:可服务 1:屏蔽 | 0 |
INT_TXD1 | [4] | 0:可服务 1:屏蔽 | 0 |
INT_RXD1 | [3] | 0:可服务 1:屏蔽 | 0 |
INT_ERR0 | [2] | 0:可服务 1:屏蔽 | 0 |
INT_TXD0 | [1] | 0:可服务 1:屏蔽 | 0 |
INT_RXD0 | [0] | 0:可服务 1:屏蔽 | 0 |
三、外部中断
3.1 硬件资源
Mini2440开发板总共有6个用户测试用按键,它们均从CPU中断引脚直接引出,属于低电平触发,这些引脚也可以复用为GPIO和特殊功能口,为了用户把它们引出作为其他用途,这6个引脚也通过CON12引出,6个按键和CON12的定义如下:
K1 | K2 | K3 | K4 | K5 | K6 | |
中断 | EINT8 | EINT11 | EINT13 | EINT14 | EINT15 | EINT19 |
复用GPIO | GPG0 | GPG3 | GPG5 | GPG6 | GPG7 | GPG11 |
特殊功能 | - | nSS1 | SPIMISO1 | SPIMOSI1 | SPICLK1 | TCLK1 |
对应CON12 | 1 | 2 | 3 | 4 | 5 | 6 |
3.2 端口G 控制寄存器(GPGCON,GPGDAT,GPGUP)
寄存器 | 地址 | R/W | 描述 | 复位值 |
GPGCON | 0x56000060 | R/W | 配置端口G的引脚 | 0x00 |
GPGDAT | 0x56000064 | R/W | 配置G的数据寄存器 | - |
GPGUP | 0x56000068 | R/W | 端口G的上拉使能寄存器 | 0x00 |
保留 | 0x5600006C | - | 保留 | - |
GPGCON寄存器位信息
GPGCON | 位 | 描述 | 初始状态 |
GPG15 | [31:30] | 00 = 输入 01 = 输出 10 = EINT[23] 11 = 保留 | 0 |
GPG14 | [29:28] | 00 = 输入 01 = 输出 10 = EINT[22] 11 = 保留 | 0 |
GPG13 | [27:26] | 00 = 输入 01 = 输出 10 = EINT[21] 11 = 保留 | 0 |
GPG12 | [25:24] | 00 = 输入 01 = 输出 10 = EINT[20] 11 = 保留 | 0 |
GPG11 | [23:22] | 00 = 输入 01 = 输出 10 = EINT[19] 11 = 保留 | 0 |
GPG10 | [21:20] | 00 = 输入 01 = 输出 10 = EINT[18] 11 = 保留 | 0 |
GPG9 | [19:18] | 00 = 输入 01 = 输出 10 = EINT[17] 11 = 保留 | 0 |
GPG8 | [17:16] | 00 = 输入 01 = 输出 10 = EINT[16] 11 = 保留 | 0 |
GPG7 | [15:14] | 00 = 输入 01 = 输出 10 =EINT[15] 11 = 保留 | 0 |
GPG6 | [13:12] | 00 = 输入 01 = 输出 10 = EINT[14]11 = 保留 | 0 |
GPG5 | [11:10] | 00 = 输入 01 = 输出 10 = EINT[13] 11 = 保留 | 0 |
GPG4 | [9:8] | 00 = 输入 01 = 输出 10 = EINT[12] 11 = 保留 | 0 |
GPG3 | [7:6] | 00 = 输入 01 = 输出 10 = EINT[11] 11 = 保留 | 0 |
GPG2 | [5:4] | 00 = 输入 01 = 输出 10 = EINT[10]11 = 保留 | 0 |
GPG1 | [3:2] | 00 = 输入 01 = 输出 10 = EINT[9]11 = 保留 | 0 |
GPG0 | [1:0] | 00 = 输入 01 = 输出 10 = EINT[8]11 = 保留 | 0 |
由上表可知,G端口的控制寄存器可以将每个引脚配置为四种模式:
- 00:输入模式
- 01:输出模式
- 10:外部中断
- 11:保留模式
配置端口G、K1~K6引脚功能复用为外部中断:
//K1,K2,K3,K4,K5,K6 对应的6根引脚设为中断功能 GPGCON &= ~((0x03 << 0) | (0x03 << 6) | (0x03 << 10) | (0x03 << 12) | (0x03 << 14) | (0x03 << 22)); /* 清零 */ GPGCON |= (0x02 << 0) | (0x02 << 6) | (0x02 << 10) | (0x02 << 12) | (0x02 << 14) | (0x02 << 22);
3.3 EXINTn(外部中断控制寄存器n)
24 个外部中断可以由多种信号触发方式所请求。EXTINT 寄存器为外部中断配制信号触发方式为电平触发或边沿触发,同时还配制信号触发极性。
为了确认电平中断,由于噪声滤波必须保持EXTINTn 引脚上有效逻辑电平至少40ns。
寄存器 | 地址 | R/W | 描述 | 复位值 |
EXINT0 | 0x56000088 | R/W | 外部中断控制寄存器0 | 0x000000 |
EXINT1 | 0x5600008C | R/W | 外部中断控制寄存器1 | 0x000000 |
EXINT2 | 0x56000090 | R/W | 外部中断控制寄存器2 | 0x000000 |
EXTINT0位信息:
EXTINT0 | 位 | 描述 | 初始状态 |
EINT7 | [30:28] |
设置EINT7 的信号触发方式 000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
EINT6 | [26:24] | 设置EINT6 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
EINT5 | [22:20] | 设置EINT5 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
EINT4 | [18:16] | 设置EINT4 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
EINT3 | [14:12] | 设置EINT3 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
EINT2 | [10:8] | 设置EINT2 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
EINT1 | [6:4] | 设置EINT1 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
EINT0 | [2:0] | 设置EINT0 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
EXTINT1位信息:
EXTINT1 | 位 | 描述 | 初始状态 |
FLTEN15 | [31] |
EINT15 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT15 | [30:28] |
设置EINT15 的信号触发方式 000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN14 | [27] |
EINT14 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT14 | [26:24] | 设置EINT14 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN13 | [23] |
EINT13 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
|
EINT13 | [22:20] | 设置EINT13 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN12 | [19] |
EINT12 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT12 | [18:16] | 设置EINT12 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN11 | [15] |
EINT11 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT11 | [14:12] | 设置EINT11 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN10 | [11] |
EINT10 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT10 | [10:8] | 设置EINT10 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN9 | [7] |
EINT9 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT9 | [6:4] | 设置EINT9 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN8 | [3] |
EINT8 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT8 | [2:0] | 设置EINT8 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
EXTINT2位信息:
EXTINT2 | 位 | 描述 | 初始状态 |
FLTEN23 | [31] |
EINT15 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT23 | [30:28] |
设置EINT15 的信号触发方式 000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN22 | [27] |
EINT14 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT22 | [26:24] | 设置EINT14 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN21 | [23] |
EINT13 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT21 | [22:20] | 设置EINT13 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN20 | [19] |
EINT12 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT20 | [18:16] | 设置EINT12 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN19 | [15] |
EINT11 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT19 | [14:12] | 设置EINT11 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN18 | [11] |
EINT10 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT18 | [10:8] | 设置EINT10 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN17 | [7] |
EINT9 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT17 | [6:4] | 设置EINT9 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
FLTEN16 | [3] |
EINT8 的滤波器使能 0 = 滤波器禁止 1 = 滤波器使能 |
0 |
EINT16 | [2:0] | 设置EINT8 的信号触发方式
000 = 低电平 001 = 高电平 01x = 下降沿触发 |
000 |
我们的按键K1~K6按下去全部是低电平,EINT8、EINT11、EINT13、EINT14、EINT15、EINT19、默认低电平触发方式即可。
3.4 EINTMASK(外部中断屏蔽寄存器)
寄存器信息:
寄存器 | 地址 | R/W | 描述 | 复位值 |
EINTMASK | 0x560000A4 | R/W | 外部中断屏蔽寄存器 | 0x000FFFFF |
寄存器位信息:
EINTMASK | 位 | 描述 | 初始状态 |
EINT23 | [23] | 0 = 使能中断 1 = 禁止中断 | 0 |
EINT22 | [22] | 0 = 使能中断 1 = 禁止中断 | 0 |
EINT21 | [21] | 0 = 使能中断 1 = 禁止中断 | 0 |
EINT20 | [20] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT19 | [19] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT18 | [18] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT17 | [17] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT16 | [16] | 0 = 使能中断 1 = 禁止中断 | 0 |
EINT15 | [15] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT14 | [14] | 0 = 使能中断 1 = 禁止中断 | 0 |
EINT13 | [13] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT12 | [12] | 0 = 使能中断 1 = 禁止中断 | 0 |
EINT11 | [11] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT10 | [10] | 0 = 使能中断 1 = 禁止中断 | 0 |
EINT9 | [9] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT8 | [8] | 0 = 使能中断 1 = 禁止中断 | 0 |
EINT7 | [7] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT6 | [6] | 0 = 使能中断 1 = 禁止中断 | 0 |
EINT5 | [5] |
0 = 使能中断 1 = 禁止中断 |
0 |
EINT4 | [4] | 0 = 使能中断 1 = 禁止中断 | 0 |
Reserved | [3:0] | 保留 |
使能外部中断:
// 对于EINT8,11,13,14,15,19,需要在EINTMASK寄存器中使能它 清零,中断使能 EINTMASK &= ~((1 << 8) | (1 << 11) | (1 << 13) | (1 << 14)) | (1 << 15)) | (1 << 19));
3.5 INTMASK
ENT8、ENT11、ENT13、ENT14、ENT15、ENT19、对应的中断源为EINT8_23,位于INTMASK的第五位:
// EINT8~EINT23中断使能 INTMSK &= ~BIT_EINT8_23;
3.6 外部中断初始化
将之前介绍的步骤总结下来,初始化代码如下:
/************************************************************* * * Function : 初始化GPIO引脚为外部中断 * GPIO引脚用作外部中断时,默认为低电平触发、IRQ方式(不用设置INTMOD) * K1 K2 K3 K4 K5 K6 * 中断 EINT8 EINT11 EINT13 EINT14 EINT15 EINT19 * 复用GPIO GPG0 GPG3 GPG5 GPG6 GPG7 GPG11 * **************************************************************/ void eint8_23_int_init() { //K1,K2,K3,K4,K5,K6 对应的6根引脚设为中断功能 GPGCON &= ~((0x03 << 0) | (0x03 << 6) | (0x03 << 10) | (0x03 << 12) | (0x03 << 14) | (0x03 << 22)); /* 清零 */ GPGCON |= (0x02 << 0) | (0x02 << 6) | (0x02 << 10) | (0x02 << 12) | (0x02 << 14) | (0x02 << 22); /* 设置为中断功能 */ // 对于EINT8,11,13,14,15,19,需要在EINTMASK寄存器中使能它 清零,中断使能 EINTMASK &= ~((1 << 8) | (1 << 11) | (1 << 13) | (1 << 14)) | (1 << 15)) | (1 << 19)); /* * 看2440手册Figure 14-2. Priority Generating Block * EINT8~EINT23的优先级是一样的 * 所以不用设置PRIORITY了 */ // EINT8~EINT23中断使能 INTMSK &= ~BIT_EINT8_23; }
3.7 CPSR开启IRQ中断
将CPSR的bit[7] I位清零,开启IRQ总中断:
void vector_enable() { __asm__( "mrs r0,cpsr\n" /* r0 = cpsr */ "bic r0,r0,#(0x01<<7 )\n" /* cpsr 的I位清零 */ "msr cpsr_c,r0\n" /* cpsr = r0 */ ); }
3.8 EINT8_23_IRQHandler
EINT8~23外部中断触发后,我们需要跳到对应的中断处理程序(至于怎么跳到对应的中断处理程序后面介绍),这里想做以下事情:
- 按下K1,LED1亮;
- 按下K2,LED2亮;
- 按下K3,LED3亮;
- 按下K4,LED4亮,
- 按下K5,所有LED熄灭;
- 按下K6,所有LED点亮;
/************************************************************************* * * Function : 中断源5 外部中断8至23 * 执行之前,必须先始化led * *************************************************************************/ void EINT8_23_IRQHandler() { if (EINTPEND & (1 << 8)) { // K1被按下 GPBDAT &= ~(1 << 5); // LED1点亮 } if (EINTPEND & (1 << 11)) { // K2被按下 GPBDAT &= ~(1 << 6); // LED2点亮 } if (EINTPEND & (1 << 13)) { // K3被按下 GPBDAT &= ~(1 << 7); // LED3点亮 } if (EINTPEND & (1 << 14)) { // K4被按下 GPBDAT &= ~(1 << 8); // LED4点亮 } if (EINTPEND & (1 << 15)) { // K5被按下 GPBDAT |= (0xF << 5); // 所有LED熄灭 } if (EINTPEND & (1 << 19)) { // K6被按下 GPBDAT &= ~(0xF << 5); // 全部点亮 } //清中断 EINTPEND |= (1 << 8) | (1 << 11) | (1 << 13) | (1 << 14); /* 清中断标志位 */ SRCPND |= BIT_EINT8_23; /* 清中断标志位 */ INTPND |= BIT_EINT8_23; /* 清中断标志位 */ }
在中断处理函数的最后,我们进行了中断清除。其实在外部中断初始化函数中我们最好也进行一次中断清除。
四、串口中断
我们这里仍然以UART0为例,UART0中断包括:
亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。
日期 | 姓名 | 金额 |
---|---|---|
2023-09-06 | *源 | 19 |
2023-09-11 | *朝科 | 88 |
2023-09-21 | *号 | 5 |
2023-09-16 | *真 | 60 |
2023-10-26 | *通 | 9.9 |
2023-11-04 | *慎 | 0.66 |
2023-11-24 | *恩 | 0.01 |
2023-12-30 | I*B | 1 |
2024-01-28 | *兴 | 20 |
2024-02-01 | QYing | 20 |
2024-02-11 | *督 | 6 |
2024-02-18 | 一*x | 1 |
2024-02-20 | c*l | 18.88 |
2024-01-01 | *I | 5 |
2024-04-08 | *程 | 150 |
2024-04-18 | *超 | 20 |
2024-04-26 | .*V | 30 |
2024-05-08 | D*W | 5 |
2024-05-29 | *辉 | 20 |
2024-05-30 | *雄 | 10 |
2024-06-08 | *: | 10 |
2024-06-23 | 小狮子 | 666 |
2024-06-28 | *s | 6.66 |
2024-06-29 | *炼 | 1 |
2024-06-30 | *! | 1 |
2024-07-08 | *方 | 20 |
2024-07-18 | A*1 | 6.66 |
2024-07-31 | *北 | 12 |
2024-08-13 | *基 | 1 |
2024-08-23 | n*s | 2 |
2024-09-02 | *源 | 50 |
2024-09-04 | *J | 2 |
2024-09-06 | *强 | 8.8 |
2024-09-09 | *波 | 1 |
2024-09-10 | *口 | 1 |
2024-09-10 | *波 | 1 |
2024-09-12 | *波 | 10 |
2024-09-18 | *明 | 1.68 |
2024-09-26 | B*h | 10 |
2024-09-30 | 岁 | 10 |
2024-10-02 | M*i | 1 |
2024-10-14 | *朋 | 10 |
2024-10-22 | *海 | 10 |
2024-10-23 | *南 | 10 |
2024-10-26 | *节 | 6.66 |
2024-10-27 | *o | 5 |
2024-10-28 | W*F | 6.66 |
2024-10-29 | R*n | 6.66 |
2024-11-02 | *球 | 6 |
2024-11-021 | *鑫 | 6.66 |
2024-11-25 | *沙 | 5 |
2024-11-29 | C*n | 2.88 |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了