Skip to content
On this page

按键中断实验(Cortex-A7)


标签:FSMP1A/🧪实验  

🔍分析电路图

file/img/202306121713.png

  • 丝印 KEY1 --> 网络标号 KEY1 (扩展板原理图)
  • 引脚 (连接板原理图):
    • KEY1 --> PF9
    • KEY2 --> PF7
    • KEY3 --> PF8

file/img/202306121809.png

  • 按键按下的时候触发“下降沿”事件,调用中断

🎚️分析框图

excalidraw/ARM开发板按键中断分析框图.png

1️⃣分析RCC章节

确定总线连接

  • RCCGPIOs 的总线均为 AHB4 (Ref 2.5.2 Figure 4.)

确定基地址

  • RCC 使能寄存器首地址:0x50000000 (Ref 2.5.2 Tabel 9.)
  • GPIOF 组控制器寄存器首地址:0x50007000 (Ref 2.5.2 Tabel 9.)
  • GICC 组控制寄存器首地址:0xA0022000 (Ref 2.5.2 Tabel 9.)
  • EXTI 组控制器寄存器首地址:0x5000D000 (Ref 2.5.2 Table 9.)

RCC_MP_AHB4ENSETR寄存器

  • Ref 10.7.155
  • 地址:0x5000_0000 + 0xA28 = 0x5000_0A28
  • 需要使能 GPIOFEN 位,设置为 1
  • 0x5000_0A28[5] = 1

2️⃣分析GPIO章节

分析GPIOx_MODER寄存器

  • Ref 2.5.2
  • GPIOx_MODER 设置为“输入”模式 (Ref 13.4.1)
  • GPIOF_MODER[17:16]= 0x5000_7000 = 00

3️⃣分析EXTI章节

EXTI寄存器介绍

  • Extended interrupt and event controller (外部中断和事件控制器)
  • 外部中断是由外部设备或信号触发的中断事件,例如按键输入、外部传感器信号等。EXTI 寄存器允许处理器对这些中断事件进行配置和响应
  • 该寄存器通常包含如下字段:
    1. EXTI Line:用于选择要配置的外部中断线,每个外部中断线对应一个或多个外部中断输入
    2. Trigger Selection:用于选择中断触发方式,可以配置为上升沿触发、下降沿触发、边沿触发或电平触发等
    3. Interrupt Enable:用于使能或禁用外部中断线的中断
    4. Pending Interrupt:用于检测是否有未处理的中断请求
    5. Software Interrupt Event:用于通过软件产生一个中断事件,用于测试或模拟中断
    6. Clear Pending Interrupt:用于清除中断挂起状态,确认中断请求已被处理

内部框图分析

file/img/202306121839.png

  1. 中断选择寄存器(interrupt selection register, ICR),选择从对应的 GPIO 引脚中读取
  2. 事件触发的寄存器有许多,我们需要使用的是下降沿触发选择寄存器(falling trigger selection register, FTSR)
  3. 中断屏蔽寄存器(interrupt mask register, IMR),可以设置和消除对中断的屏蔽,确保按键中断的响应的处理的完整性

EXTI_EXTICRx寄存器

  • EXTI_EXTICRx 寄存器,外部中断选择寄存器
    • KEY1 --> PG9 --> EXTI_EXTICR3[15:8] = 0x05
    • KEY2 --> PF7 --> EXTI_EXTICR2[31:24] = 0x05
    • KEY3 --> PF8 --> EXTI_EXTICR3[7:0] = 0x05
    • 🤔为什么有 4 个 EXTI_EXTICR 寄存器?
      • EXTI 组一共有 16 个 EXTI(EXTI0 ~ EXTI15)
      • 每 8 位管理一个 EXTI,一个寄存器 32 位,所以一个寄存器罪过管理 32/8 = 4 个 EXTI
      • 想要管理 16 个 EXTI,所以 16 / 4 = 4 个 EXTI 中断选择寄存器
    • 🤔有没有公式可以直接计算出操作的寄存器和对应的位数?
      • EXTI 编号 / 4 = 商 ...... 余数
      • 商 + 1 = 需要操作的寄存器
      • 余数 * 8:要操作的寄存器 8 位中的最低位
      • 例如,PG99/4=2...1 ,那么对应的寄存器是 ICR2 ,最低位是 8,总共需要写入 8 位,那么就是 ICR[15:8]

EXTI_FTSR1寄存器

  • 下降沿触发使能,设置为 1
  • 查看 Ref 21.3 Table 119,EXTI[7]EXTI[8]EXTI[9] 对应的事件编号是 FT7FT8FT9
  • KEY1 --> PG9 --> EXTI_FTSR1[9] = 1
  • KEY2 --> PF7 --> EXTI_FTSR1[7] = 1
  • KEY3 --> PF8 --> EXTI_FTSR1[8] = 1

EXTI_IMR1寄存器

  • Ref 24.6.23
  • 中断屏蔽寄存器
  • 设置中断不屏蔽,设置为 1
  • KEY1 --> PG9 --> EXTI_IMR1[9] = 1
  • KEY2 --> PF7 --> EXTI_IMR1[7] = 1
  • KEY3 --> PF8 --> EXTI_IMR1[8] = 1

EXTI_FPR1寄存器

  • EXTI 下降沿挂起寄存器,该寄存器可读可写
  • 0 :中断没有触发
  • 1 :中断触发
  • 0 :不清除 EXTI 层中断挂起标志位
  • 1:清除 EXTI 层中断挂起标志位
  • 设置中断挂起:
    • KEY1 --> PG9 --> EXTI_FPR1[9] = 1
    • KEY2 --> PF7 --> EXTI_FPR1[7] = 1
    • KEY3 --> PF8 --> EXTI_FPR1[8] = 1

🌕总体框图

file/img/202306121920.png

  • GIC 层中,分成了两个寄存器,GICD 和 GICC,分别对应了外部和 CPU 内部的中断管理的寄存器

4️⃣分析GICD层章节

中断号管理

img/202306132106_1.png

  • SPI 中断通过 CPU 触发 IRQ 中断

中断号:

  • Software generated interrupts (SGI): 软件产生中断 (ID: 0~15)
  • Private peripheral interrupts (PPI): 私有外部中断 (ID: 16 ~ 31)
  • Shared peripheral interrupts (SPI): 共享外设中断 (ID: 32 ~ 287)

事件号:

img/202306131002.png

事件号对应的中断号:

img/202306132050.png

  • #中断号的划分来说,是属于 SPI 共享外设中断

GICD_ISENABLERx寄存器

  • GICD_ISENABLERx:Ref 23.5.6 中断设置使能,设置数值 1 为使能
    • KEY1 -> EXTI9 -> PG9 -> 事件9 -> 中断号99 -> GICD_ISENABLER3[3] = 1
    • KEY2 -> EXTI7 -> PF7 -> 事件7 -> 中断号97 -> GICD_ISENABLER3[1] = 1
    • KEY3 -> EXTI8 -> PF8 -> 事件8 -> 中断号98 -> GICD_ISENABLER3[2] = 1
  • 🤔为什么有 9 个 ISENABLER 寄存器?
    • 每个寄存器有 32 位,可以管理 32 个中断号
    • 一个 288 个中断号,288/32=9

🧮计算公式

  • 中断号 / 32 = 商 ...... 余数
    • 商:操作的寄存器
    • 余数:操作为位
  • 例如,99 / 32 = 3 ... 3,所以设置 ISENABLER3[3]

GICD_IPRIORITYRx寄存器

img/202306132116.png

  • GICD_IPRIORITYRx:23.5.14 优先级设置
  • 有 72 个寄存器(0~71),因为每个寄存器需要使用 8 位(保留3位)管理一个中断的优先级,一个寄存器只能管理 4 个中断号,所以 288/4=72

🧮计算公式

  • 中断号 / 4 = 商 ...... 余数
    • 商:操作的寄存器
    • 余数 * 8 + 3:操作五位中的最低位
  • 通过公式可以得到:
  • KEY1 -> PF9 -> EXTI9 -> 中断号99 -> 99/4=23...3 -> GICD_IPRIORITYR24[31:27]
  • key2 -> PF7 -> EXTI7 -> 中断号97 -> 97/4=24...1 -> GICD_IPRIORITYR24[15:11]
  • key3 -> PF8 -> EXTI8 -> 中断号98 -> 98/4=24...2 -> GICD_IPRIORITYR24[23:19]
  • 关于优先级的值:
    • 可设置的范围是:0 ~ 2^5-1
    • 中断的优先级设置得越小,代表优先级越高
    • 需要比 GICC 层的优先级高才能生效

GICD_ITARGETSRx寄存器

  • GICD_ITARGETSRx:23.5.15 中断目标分配寄存器(x=0~71)
    • 即分配给哪个 CPU 处理
  • 🤔为什么有 72 个寄存器?同#分析GICD_IPRIORITYRx寄存器

🧮计算公式

  • 中断号 / 4 = 商 ...... 余数
    • 商:操作的寄存器
    • 余数 * 8:操作两位中的最低位
  • 按键的设置:
  • key1 -> PF9 -> EXTI9 -> 中断号99 -> 99/4=24...3 -> GICD_ITARGETSR24[25:24] = 0bx1
  • key2 -> PF7 -> EXTI7 -> 中断号97 -> 97/4=24...1 -> GICD_ITARGETSR24[9:8] = 0bx1
  • key3 -> PF8 -> EXTI8 -> 中断号98 -> 98/4=24...2 -> GICD_ITARGETSR24[17:16] = 0bx1
  • 设置的值,分配的 CPU:
    • 0b00 :不分配
    • 0bx1:CPU0
    • Ob1x:CPU1
    • Ob11:同时分配给 CPU0 和 CPU1
    • x 为任意值(简单来说,最左边一个 0 代表 CPU0,后面一个代表 CPU1)

GICD_CTLR寄存器

  • GICD_CTLR:23.5.1 全局控制 0 位设置 1
  • ARM 中将控制组分成了组 0 和 组 1,两组在优先级和其他地方的特性不一样,这里不展开讲,但我们需要使能的是组 0 的中断组
  • GICD_CTLR[0] = 1

GICD_ICPENDRx寄存器

  • GICD_ICPENDRx:23.5.11 中断清除挂起标志位(x=0~8)
  • 在完成对中断的响应后,需要将中断挂起标志位清除
  • 🤔为什么有 9 个寄存器?
    • 每一位管理一个中断号,一个寄存器可以管理 32 个
    • 288/32 = 9 个

🧮计算公式

  • 中断号 / 4 = 商 ...... 余数
    • 商:操作的寄存器
    • 余数:操作的位数

5️⃣分析GICC层章节

GICC_PMR寄存器

  • 第 23.6.3 章节
  • 设置 GICC 输入中断的优先级
  • 这个没有 GICD 那样需要管理 288 个的优先级,是整体的
  • 设置的位数GICC_PMR[7:3]
  • 设置的值:0~2^5-1
  • 需要比 GICD 层大(即优先级更低),才能使得中断生效

GICC_CTLR寄存器

  • 第 23.6.1 章节,GICC层全局控制
  • 设置 0 使得 GROUP 0 中断组生效
  • GICC_CTLR[0]=1

GICC_IAR寄存器

  • 第 23.6.6 章节,获取中断号,只读
  • 例如,当按键1按下,寄存器中会写入 99
  • 怎么读?GICC_IAR & 0x3ff

GICC_EOIR寄存器

  • 第 23.6.7 章节,清除获取到的中断号
  • 防止一次中断被多次响应,需要在一次获取到后清除掉它
  • GICC_EOIR=GICC_IAR & 03ff

🧪实验1

🧪实验2

实验现象:

  • 当按键1按下之后,1)打印一句话,并且需要打印出中断号 2)LED1灯的状态进行取反
  • 当按键2按下之后,1)打印一句话,并且需要打印出中断号 2)LED2灯的状态进行取反
  • 当按键3按下之后,1)打印一句话,并且需要打印出中断号 2)LED3灯的状态进行取反

Last updated: