Appearance
🔍分析电路图

- 丝印
KEY1--> 网络标号KEY1(扩展板原理图) - 引脚 (连接板原理图):
KEY1 --> PF9KEY2 --> PF7KEY3 --> PF8

- 按键按下的时候触发“下降沿”事件,调用中断
🎚️分析框图

1️⃣分析RCC章节
- 备注
- RM0436-stm32mp157-Reference-manual.pdf ---> Ref
- RCC 为使能控制器使能寄存器,参考:
确定总线连接
RCC和GPIOs的总线均为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 寄存器允许处理器对这些中断事件进行配置和响应
- 该寄存器通常包含如下字段:
- EXTI Line:用于选择要配置的外部中断线,每个外部中断线对应一个或多个外部中断输入
- Trigger Selection:用于选择中断触发方式,可以配置为上升沿触发、下降沿触发、边沿触发或电平触发等
- Interrupt Enable:用于使能或禁用外部中断线的中断
- Pending Interrupt:用于检测是否有未处理的中断请求
- Software Interrupt Event:用于通过软件产生一个中断事件,用于测试或模拟中断
- Clear Pending Interrupt:用于清除中断挂起状态,确认中断请求已被处理
内部框图分析

- 中断选择寄存器(interrupt selection register, ICR),选择从对应的 GPIO 引脚中读取
- 事件触发的寄存器有许多,我们需要使用的是下降沿触发选择寄存器(falling trigger selection register, FTSR)
- 中断屏蔽寄存器(interrupt mask register, IMR),可以设置和消除对中断的屏蔽,确保按键中断的响应的处理的完整性
EXTI_EXTICRx寄存器
EXTI_EXTICRx寄存器,外部中断选择寄存器KEY1 --> PG9 --> EXTI_EXTICR3[15:8] = 0x05KEY2 --> PF7 --> EXTI_EXTICR2[31:24] = 0x05KEY3 --> 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 位中的最低位
- 例如,
PG9,9/4=2...1,那么对应的寄存器是ICR2,最低位是8,总共需要写入 8 位,那么就是ICR[15:8]
EXTI_FTSR1寄存器
- 下降沿触发使能,设置为
1 - 查看 Ref 21.3 Table 119,
EXTI[7],EXTI[8],EXTI[9]对应的事件编号是FT7,FT8,FT9 KEY1 --> PG9 --> EXTI_FTSR1[9] = 1KEY2 --> PF7 --> EXTI_FTSR1[7] = 1KEY3 --> PF8 --> EXTI_FTSR1[8] = 1
EXTI_IMR1寄存器
- Ref 24.6.23
- 中断屏蔽寄存器
- 设置中断不屏蔽,设置为
1 KEY1 --> PG9 --> EXTI_IMR1[9] = 1KEY2 --> PF7 --> EXTI_IMR1[7] = 1KEY3 --> PF8 --> EXTI_IMR1[8] = 1
EXTI_FPR1寄存器
- EXTI 下降沿挂起寄存器,该寄存器可读可写
- 读
0:中断没有触发 - 读
1:中断触发 - 写
0:不清除 EXTI 层中断挂起标志位 - 写
1:清除 EXTI 层中断挂起标志位 - 设置中断挂起:
KEY1 --> PG9 --> EXTI_FPR1[9] = 1KEY2 --> PF7 --> EXTI_FPR1[7] = 1KEY3 --> PF8 --> EXTI_FPR1[8] = 1
🌕总体框图

- 在 GIC 层中,分成了两个寄存器,GICD 和 GICC,分别对应了外部和 CPU 内部的中断管理的寄存器
4️⃣分析GICD层章节
中断号管理

- SPI 中断通过 CPU 触发 IRQ 中断
中断号:
- Software generated interrupts (SGI): 软件产生中断 (ID: 0~15)
- Private peripheral interrupts (PPI): 私有外部中断 (ID: 16 ~ 31)
- Shared peripheral interrupts (SPI): 共享外设中断 (ID: 32 ~ 287)
事件号:

事件号对应的中断号:

- 从#中断号的划分来说,是属于 SPI 共享外设中断
GICD_ISENABLERx寄存器
- GICD_ISENABLERx:Ref 23.5.6 中断设置使能,设置数值
1为使能KEY1 -> EXTI9 -> PG9 -> 事件9 -> 中断号99 -> GICD_ISENABLER3[3] = 1KEY2 -> EXTI7 -> PF7 -> 事件7 -> 中断号97 -> GICD_ISENABLER3[1] = 1KEY3 -> 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寄存器

- 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] = 0bx1key2 -> PF7 -> EXTI7 -> 中断号97 -> 97/4=24...1 -> GICD_ITARGETSR24[9:8] = 0bx1key3 -> PF8 -> EXTI8 -> 中断号98 -> 98/4=24...2 -> GICD_ITARGETSR24[17:16] = 0bx1- 设置的值,分配的 CPU:
0b00:不分配0bx1:CPU0Ob1x:CPU1Ob11:同时分配给 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灯的状态进行取反