程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)

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 = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
EINT6 [26:24] 设置EINT6 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
EINT5 [22:20] 设置EINT5 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
EINT4 [18:16] 设置EINT4 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
EINT3 [14:12] 设置EINT3 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
EINT2 [10:8] 设置EINT2 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
EINT1 [6:4] 设置EINT1 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
EINT0 [2:0] 设置EINT0 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000

EXTINT1位信息:

EXTINT1 描述 初始状态
FLTEN15 [31]

EINT15 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT15 [30:28]

设置EINT15 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN14 [27]

EINT14 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT14 [26:24] 设置EINT14 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN13 [23]

EINT13 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

 
EINT13 [22:20] 设置EINT13 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN12 [19]

EINT12 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT12 [18:16] 设置EINT12 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN11 [15]

EINT11 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT11 [14:12] 设置EINT11 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN10 [11]

EINT10 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT10 [10:8] 设置EINT10 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN9 [7]

EINT9 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT9 [6:4] 设置EINT9 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN8 [3]

EINT8 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT8 [2:0] 设置EINT8 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000

EXTINT2位信息:

EXTINT2 描述 初始状态
FLTEN23 [31]

EINT15 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT23 [30:28]

设置EINT15 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN22 [27]

EINT14 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT22 [26:24] 设置EINT14 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN21 [23]

EINT13 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

 0
EINT21 [22:20] 设置EINT13 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN20 [19]

EINT12 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT20 [18:16] 设置EINT12 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN19 [15]

EINT11 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT19 [14:12] 设置EINT11 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN18 [11]

EINT10 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT18 [10:8] 设置EINT10 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN17 [7]

EINT9 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT17 [6:4] 设置EINT9 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 000
FLTEN16 [3]

EINT8 的滤波器使能

0 = 滤波器禁止 1 = 滤波器使能

0
EINT16 [2:0] 设置EINT8 的信号触发方式

000 = 低电平 001 = 高电平 01x = 下降沿触发
10x = 上升沿触发  11x = 双边沿触发

 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-30I*B1
2024-01-28*兴20
2024-02-01QYing20
2024-02-11*督6
2024-02-18一*x1
2024-02-20c*l18.88
2024-01-01*I5
2024-04-08*程150
2024-04-18*超20
2024-04-26.*V30
2024-05-08D*W5
2024-05-29*辉20
2024-05-30*雄10
2024-06-08*:10
2024-06-23小狮子666
2024-06-28*s6.66
2024-06-29*炼1
2024-06-30*!1
2024-07-08*方20
2024-07-18A*16.66
2024-07-31*北12
2024-08-13*基1
2024-08-23n*s2
2024-09-02*源50
2024-09-04*J2
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-26B*h10
2024-09-3010
2024-10-02M*i1
2024-10-14*朋10
2024-10-22*海10
2024-10-23*南10
2024-10-26*节6.66
2024-10-27*o5
2024-10-28W*F6.66
2024-10-29R*n6.66
2024-11-02*球6
2024-11-021*鑫6.66
2024-11-25*沙5
2024-11-29C*n2.88
posted @   大奥特曼打小怪兽  阅读(470)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
如果有任何技术小问题,欢迎大家交流沟通,共同进步

公告 & 打赏

>>

欢迎打赏支持我 ^_^

最新公告

程序项目代做,有需求私信(小程序、网站、爬虫、电路板设计、驱动、应用程序开发、毕设疑难问题处理等)。

了解更多

点击右上角即可分享
微信分享提示