ARM - cortex-A7核/M4核按键中断实验

 一、分析电路图

分析三个按键对应的GPIO接口:

KEY1----->PF9

KEY2----->PF7

KEY3----->PF8

2eadc6e6cb414dafbd30bab11d179570.png

 f17974797ce14e1fa5b866984ebe935f.png

 dff5fc1c28824aca9efda57d58eda6a5.png

二、分析框图

5dc7b4ecc5794bfd8fff8b60c012a52f.png

总结框图:

1.通过框图分析可知:RCC章节/GPIOF章节/EXTI章节/GIC章节

2.需要分析GPIOF章节:设置引脚为输入模式

3.需要分析EXTI章节:检测中断的触发方式

3.需要分析GIC章节:设置GPIOF引脚对应的中断号

三、分析RCC章节 

3.1 寄存器总线

ba864b9328d541d3b337429f3c4fd039.png

c82ba2b87a974ef5b4c40e403a3a9867.png

3.2 分析RCC_MP_AHB4ENSETR寄存器

8b6abb704b0644748d97c943fe2e5bc6.png

1.如何确定RCC基地址?

    通过2.5.2章节

2.RCC_MP_AHB4ENSETR地址是多少呢?

    RCC_MP_AHB4ENSETR地址=基地址+偏移地址 = 0x50000000 + 0xA28 = 0x50000A28    

3.如何设置GPIOF控制器使能?

    0x50000A28地址的第5位置1,设置GPIOF控制器使能

    RCC_MP_AHB4ENSETR[5] = 1 -------->设置GPIOF控制器使能工作

四、分析GPIO章节

4.1 分析GPIOx_MODER寄存器

9aee32d179e54b3292fe03831cbb43e0.png

KEY1------>PF9引脚

KEY2------>PF7引脚

KEY3------>PF8引脚

1.如何确定GPIOF_MODER寄存器的地址?

    地址=基地址+偏移地址=0x50007000+0x00=0x50007000    

2.通过GPIOF_MODER设置PF9/PF7/PF8引脚设置为输入模式?

    GPIOF_MODER[19:18]=00------>KEY1输入模式

    GPIOF_MODER[15:14]=00------>KEY2输入模式

    GPIOF_MODER[17:16]=00------>KEY3输入模式

五、分析EXTI章节

5.1 EXTI章节分析

efe5b07514784b09b924cbbcf5c7ce82.png

 46571ae736a64d7da1a48d3582cbb895.png

 7997501e809341feb425c609cdc60ca0.png

 229d69337ad548f98bf6ff04d3d9a533.png

eb45df724fbc402d92a6aeb4a0574302.png

3b4e0bc04d02416fb92f0d706165fdaa.png

5.1 分析EXTI_EXTICR3寄存器

f80d78023b8c434ba71ed44fce5c1647.png

1b7488e03a4f4005941a2a129c36105e.png

EXTI_EXTICR3:EXTI external interrupt selection registe

EXTI:外部中断选择寄存器 功能:GPIO控制器和EXTI控制器进行连接

思考:1.EXTI_EXTICRn(n:1~4),为什么有4个EXTI_EXTICRn这样控制器?

1)通过EXTI框图分析可知,一共有16个EXTI(EXTI0~EXIT15)

2)EXTI_EXTICRn寄存器每8位管理一个EXTI,一个寄存器32位,最多管理4个EXTI

3)要想管理16个EXTI,需要4个这样EXTI_EXTICRn控制器

key1------>PF9------>EXTI9-------->EXTI_EXTICR3[15:8] = 0x05

key2------>PF7------>EXTI7-------->EXTI_EXTICR2[31:24] = 0x05

key3------>PF8------>EXTI8-------->EXTI_EXTICR3[7:0] = 0x05

思考2:有没有什么公式可以直接推出哪一个寄存器的哪几位

    EXTI编号 / 4 = 商 ...... 余数

    商+1 :对应的哪一个寄存器

    余数*8:对应寄存器8位中的最低位

key1------>PF9------>EXTI9--->9 / 4 = 2.....1--->EXTI_EXTICR3[15:8] = 0x05

key2------>PF7------>EXTI7--->7 / 4 = 1.....3--->EXTI_EXTICR2[31:24] = 0x05

key3------>PF8------>EXTI8--->8 / 4 = 2.....0--->EXTI_EXTICR3[7:0] = 0x05

5.2 分析EXTI_FTSR1寄存器

b5bef39906b3433eb7158b6249dd77a5.png

 bd9681e98a0041c0b248ef362d5c4c83.png

1.需要知道EXTI7/EXTI8/EXTI9对应输入事件编号是多少呢?

    通过芯片手册21.3章节进行查看

2.EXTI7/EXTI8/EXTI9对应设置EXTI_FTSR1位数:

key1------>PF9------>EXTI9--->对应事件9--->EXTI_FTSR1[9] = 0x1

key2------>PF7------>EXTI7--->对应事件7--->EXTI_FTSR1[7] = 0x1

key3------>PF8------>EXTI8--->对应事件8--->EXTI_FTSR1[8] = 0x1

3.地址

    地址 = 基地址 + 偏移地址 = 0x5000D000 + 0x004  =  0x5000D004

5.3 分析EXTI_IMR1寄存器

b35f90fca3724c5f80ff26bb1d47a724.png

1.需要知道EXTI7/EXTI8/EXTI9对应输入事件编号是多少呢?

    通过芯片手册21.3章节进行查看

2.EXTI7/EXTI8/EXTI9对应设置EXTI_IMR1位数:

key1------>PF9------>EXTI9--->对应事件9--->EXTI_IMR1[9] = 0x1--->中断不屏蔽

key2------>PF7------>EXTI7--->对应事件7--->EXTI_IMR1[7] = 0x1--->中断不屏蔽

key3------>PF8------>EXTI8--->对应事件8--->EXTI_IMR1[8] = 0x1--->中断不屏蔽

3.地址

    地址 = 基地址 + 偏移地址 = 0x5000D000 + 0x080  =  0x5000D080

5.4 分析EXTI_FPR1寄存器

46f5a599bcb648099bb92dc377004b0e.png

1.rc_w1: rc--->可读  w1--->写1清除中断挂起标志位

读0:中断没有发生

读1:中断发生

写0:表示没有清除中断挂起标志位

写1:表示清除中断挂起标志位

2.EXTI7/EXTI8/EXTI9对应设置EXTI_FPR1位数:

key1------>PF9------>EXTI9--->对应事件9--->EXTI_FPR1[9] = 0x1--->清除中断挂起标志位

key2------>PF7------>EXTI7--->对应事件7--->EXTI_FPR1[7] = 0x1--->清除中断挂起标志位

key3------>PF8------>EXTI8--->对应事件8--->EXTI_FPR1[8] = 0x1--->清除中断挂起标志位

3.地址

    地址 = 基地址 + 偏移地址 = 0x5000D000 + 0x010  =  0x5000D010

六、分析GICD章节

f2c529136aab4c9c8ca1d591fb7b8a1e.png

6.1 介绍

3eb88ecb816c45aba5af59446ec73230.png

Software generated interrupts (SGI):软件中断号(ID:0~15)

Private peripheral interrupts (PPI):私有的外设中断号(ID:16~31)

Shared peripheral interrupts (SPI):共享外设中断号(ID:32~287)

6.2 分析GICD_CTLR寄存器

d04f7c0857f5460aa45b17df67078f32.png

设置GICD层CPU0组使能

GICD_CTLR[0] = 1

6.3 分析GICD_ISENABLERx寄存器

3d4e08b19456479b95ea8054685f688b.png

04697d303ee6464d8a9061d88cd5bd19.png  

1.思考:GICD_ISENABLERx:中断设置使能寄存器,这个寄存器为什么有9个?

    1)GIC层一共管理288个中断号(16个SGI,16个PPI,256个SPI)

    2)GICD_ISENABLERx每一位管理一个中断号,所以一个寄存器最多管理32个中断号

    3)要想管理288个中断号,需要 288 / 32 = 9个这样的寄存器    

2.思考:key1/key2/key3按键对应的中断号是多少?(通过21.2章节查找)

key1------>PF9------>EXTI9--->对应事件9--->中断号99

key2------>PF7------>EXTI7--->对应事件7--->中断号97

key3------>PF8------>EXTI8--->对应事件8--->中断号98

3.key1/key2/key3对应的中断号需要设置哪一个GICD_ISENABLERx寄存器的哪几位

key1------>PF9------>EXTI9--->对应事件9--->中断号99--->GICD_ISENABLER3[3] = 1

key2------>PF7------>EXTI7--->对应事件7--->中断号97--->GICD_ISENABLER3[1] = 1

key3------>PF8------>EXTI8--->对应事件8--->中断号98--->GICD_ISENABLER3[2] = 1

4.有没有什么公式,直接可以计算出哪一个GICD_ISENABLERx寄存器的哪几位

    公式: 中断号 / 32 = 商 ...... 余数

    商:中断号对应要操作的寄存器

    余数:中断号对应操作寄存器的位数

key1------>PF9------>EXTI9--->对应事件9--->中断号99---> 99 / 32 = 3 .... 3--->GICD_ISENABLER3[3] = 1

key2------>PF7------>EXTI7--->对应事件7--->中断号97---> 97 / 32 = 3 .... 1--->GICD_ISENABLER3[1] = 1

key3------>PF8------>EXTI8--->对应事件8--->中断号98---> 98 / 32 = 3 .... 2--->GICD_ISENABLER3[2] = 1

6.4 分析GICD_IPRIORITYRx寄存器

50b4c6a48ea04de6bc164c5ccb0284ea.png

1.思考:GICD_IPRIORITYRx:中断优先级设置寄存器,这个寄存器为什么有72个?

    1)GIC层一共管理288个中断号(16个SGI,16个PPI,256个SPI)

    2)GICD_ISENABLERx每八位管理一个中断号,所以一个寄存器最多管理4个中断号

    3)要想管理288个中断号,需要 288 / 4 = 72个这样的寄存器    

    

2.思考:key1/key2/key3按键对应的中断号是多少?(通过21.2章节查找)

key1------>PF9------>EXTI9--->对应事件9--->中断号99

key2------>PF7------>EXTI7--->对应事件7--->中断号97

key3------>PF8------>EXTI8--->对应事件8--->中断号98

3.有没有什么公式,直接可以计算出哪一个GICD_ISENABLERx寄存器的哪几位

    公式: 中断号 / 4 = 商 ...... 余数

    商:中断号对应要操作的寄存器

    余数*8+3:中断号对应操作寄存器的位数

key1------>PF9------>EXTI9--->对应事件9--->中断号99---> 99 / 4 = 24 .... 3--->GICD_IPRIORITYR24[31:27]

key2------>PF7------>EXTI7--->对应事件7--->中断号97---> 97 / 4 = 24 .... 1--->GICD_IPRIORITYR24[15:11]

key3------>PF8------>EXTI8--->对应事件8--->中断号98---> 98 / 4 = 24 .... 2--->GICD_IPRIORITYR24[23:19]

4.注意点:中断优先级设置时,数字越小代表优先级越高

6.5 分析GICD_ITARGETSRx寄存器

07db337f9b144b2fa8ef1642c4d579c2.png

1.思考:GICD_ITARGETSRx:中断优先级设置寄存器,这个寄存器为什么有72个?

    1)GIC层一共管理288个中断号(16个SGI,16个PPI,256个SPI)

    2)GICD_ITARGETSRx每八位管理一个中断号,所以一个寄存器最多管理4个中断号

    3)要想管理288个中断号,需要 288 / 4 = 72个这样的寄存器    

    

2.思考:key1/key2/key3按键对应的中断号是多少?(通过21.2章节查找)

key1------>PF9------>EXTI9--->对应事件9--->中断号99

key2------>PF7------>EXTI7--->对应事件7--->中断号97

key3------>PF8------>EXTI8--->对应事件8--->中断号98

3.有没有什么公式,直接可以计算出哪一个GICD_ITARGETSRx寄存器的哪几位

    公式: 中断号 / 4 = 商 ...... 余数

    商:中断号对应要操作的寄存器

    余数*8:中断号对应操作寄存器的位数

key1------>PF9------>EXTI9--->对应事件9--->中断号99---> 99 / 4 = 24 .... 3--->GGICD_ITARGETSR24[25:24] = 0bx1

key2------>PF7------>EXTI7--->对应事件7--->中断号97---> 97 / 4 = 24 .... 1--->GICD_ITARGETSR24[9:8]  = 0bx1

key3------>PF8------>EXTI8--->对应事件8--->中断号98---> 98 / 4 = 24 .... 2--->GICD_ITARGETSR24[17:16]  = 0bx1

4.如何确定GICD_ITARGETSRx中这两位设置的值?

    0bx1----->分配给CPU0

    0b1x----->分配给CPU1

    0b11----->分配给CPU0和CPU1

6.6 分析GICD_ICPENDRx寄存器

d2bc709e8ba84fb09f61509ca0af2b38.png

1.思考:GICD_ICPENDRx:中断清除GICD层挂起标志位寄存器,这个寄存器为什么有9个?

    1)GIC层一共管理288个中断号(16个SGI,16个PPI,256个SPI)

    2)GICD_ICPENDRx每一位管理一个中断号,所以一个寄存器最多管理32个中断号

    3)要想管理288个中断号,需要 288 / 32 = 9个这样的寄存器    

    

2.思考:key1/key2/key3按键对应的中断号是多少?(通过21.2章节查找)

key1------>PF9------>EXTI9--->对应事件9--->中断号99

key2------>PF7------>EXTI7--->对应事件7--->中断号97

key3------>PF8------>EXTI8--->对应事件8--->中断号98

3.key1/key2/key3对应的中断号需要设置哪一个GICD_ICPENDRx寄存器的哪几位

key1------>PF9------>EXTI9--->对应事件9--->中断号99--->GICD_ICPENDR3[3] = 1

key2------>PF7------>EXTI7--->对应事件7--->中断号97--->GICD_ICPENDR3[1] = 1

key3------>PF8------>EXTI8--->对应事件8--->中断号98--->GICD_ICPENDR3[2] = 1

4.有没有什么公式,直接可以计算出哪一个GICD_ISENABLERx寄存器的哪几位

    公式: 中断号 / 32 = 商 ...... 余数

    商:中断号对应要操作的寄存器

    余数:中断号对应操作寄存器的位数

key1------>PF9------>EXTI9--->对应事件9--->中断号99---> 99 / 32 = 3 .... 3--->GICD_ICPENDR3[3] = 1

key2------>PF7------>EXTI7--->对应事件7--->中断号97---> 97 / 32 = 3 .... 1--->GICD_ICPENDR3[1] = 1

key3------>PF8------>EXTI8--->对应事件8--->中断号98---> 98 / 32 = 3 .... 2--->GICD_ICPENDR3[2] = 1

七、分析GICC章节

7.1 分析GICC_CTLR寄存器

8f79351000c447edb6277440092417c7.png

CTRL[0] = 1 cpu组0使能

7.2 分析GICC_PMR寄存器

c2ae025933874bf6abeb331e622f4d32.png

GICC_PMR:中断优先级寄存器

这个寄存器设置的值,需要比GICD层设计的中断优先级的值要大

7.3 分析GICC_IAR寄存器

1b826bf0983b42c18e3a64c4914ef5f5.png  

GICC_IAR作用:获取中断号

GICC_IAR[9:0]:获取按键的中断号

7.4 分析GICC_EOIR寄存器

b440e2845fdb4a6e8e4c02913b2c3d0d.png

GICC_EOIR作用:清除中断号

GICC_EOIR[9:0]:清除按键的中断号

cortex - A7 核代码 

#ifndef __KEY_H__
#define __KEY_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"


/*****KEY1---->PF9**********/
//初始化EXTI层
void pf9_exti_init();
//初始化GICD层
void pf9_gicd_init();
//初始化GICC层
void pf9_gicc_init();


#endif
#include "key.h"

/*****KEY1---->PF9**********/
//初始化EXTI层
void pf9_exti_init()
{
	/*****RCC章节初始化******/
	//1.设置GPIOF组时钟使能 MP_AHB4ENSETR[5] = 1
    RCC->MP_AHB4ENSETR |= 0x1<<5;

	/*****GPIO章节初始化******/
	//1.设置PF9引脚为输入模式 MODER[19:18] = 00
	GPIOF->MODER &=(~(0x3<<18));

	/*****EXTI章节初始化******/
	//1.设置PF9引脚和EXIT9控制器进行连接 EXTICR3[15:8] = 0x05
	EXTI->EXTICR3 &=(~(0xff<<8));
	EXTI->EXTICR3 |= (0x05<<8);
	//2.设置PF9引脚检测方式下降沿 FTSR1[9] = 1
	EXTI->FTSR1 |= 0x1<<9;
	//3.设置PF9引脚中断不屏蔽 C1IMR1[9] = 1
    EXTI->C1IMR1 |= 0x1<<9;
}

//初始化GICD层
void pf9_gicd_init()
{
	//1.设置GICD层全局中断使能寄存器 CTRL[0] = 1
	GICD->CTRL |=0x1<<0;
	//2.设置GICD层中断使能寄存器 ISENABLER[3] 第三位 1
	GICD->ISENABLER[3] |= 0x1<<3;
	//3.设置GICD层中断优先级寄存器IPRIORITYR[24] [31:27]
	GICD->IPRIORITYR[24] &=(~(0x1f<<27));
	//4.设置GICD层中断目标分配寄存器 ITARGETSR[24] [25:24] = 01
	GICD->ITARGETSR[24] &=(~(0x3<<24));
	GICD->ITARGETSR[24] |=0x1<<24;
}

//初始化GICC层
void pf9_gicc_init()
{
	//1.设置GICC层全局中断使能寄存器 CTRL[0] = 1
     GICC->CTRL |=0x1<<0;
	//2.设置GICC层中断优先级寄存器 PMR[7:3]
	GICC->PMR &=(~(0x1f<<3));
	GICC->PMR |=0x1f<<3;
}

cortex - M4核

一、中断实验接口

key1------>PF9------>检测方式:下降沿

key2------>PF7------>检测方式:下降沿

key3------>PF8------>检测方式:下降沿

光电开关------>PE15------>检测方式:上升沿(通过调节滑动变阻器R55,让LD5灯点亮)

火焰传感器------>PF5------>检测方式:上升沿(通过调节滑动变阻器R67,让LD6灯点亮)

人体红外------>PF12------>检测方式:上升沿

二、电路图分析

2.1 光电开光分析

4e198d944ba5438da69059f813eb2f8e.png  

2.2 火焰传感器

 0e3524e1e68b427e966238199763e6b7.png

火焰传感器(即红外接收二极管)是机器人专门用来搜寻火焰的传感器,火焰传感器对火焰特别灵敏

它的原理是利用火焰产生的红外线对它非常敏感的特点

当火焰亮度变大时,发出的红外线越多,火焰传感器管教间的阻抗变小

当火焰亮度变小时,发出的红外线越少,火焰传感器管教间的阻抗变大

2.3 人体红外

9466f299719141f4badb921926a08232.png

 612bc08913c8449d866099360dad593d.png

三、实验目的

需要检测中断之后,让灯状态取反

四、工程配置

1.配置LED1/LED2/LED3为输出模式:PE10/PF10/PE8------>配置工程师注意:配置为输出模式,给到M4核

2.配置PF9/PF7/PF8/PE15/PF5/PF12为GPIO_EXTI模式:配置工程师注意:配置为GPIO_EXTI模式,给到M4核

a34af71769294d7dbfd3cb0e784f18e0.png

 e65f83f6c855444b9335cccb84120828.png

 d63ea343794c4049949db676ffb6c473.png

 73eee0d02f8d40a893edc210c8bdefac.png

五、导出工程

17cd35b1eb5646ccad9fedd9aefef385.png

f708dd64dc9b4b6896ad16535374f865.png

b3787764a78b4e53ac08918328af9778.png

六、代码编写 

void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
    switch(GPIO_Pin)
    {
        //KEY2 --- PF10
        case GPIO_PIN_7:
            HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
        break;
        
        //KEY3 --- PE10
        case GPIO_PIN_8:
            HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_10);
        break;

        //KEY1 --- PE8
        case GPIO_PIN_9:
            HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_8);
        break;
    }
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coding Peasant

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值