ARM按键中断实验

cortex-A7按键中断实验

1.按键相关电路图分析

 

        可得知3个按键对应的引脚为PF7(key2)/PF8(key3)/PF9(key1)。

 2.框图分析

         通过框图分析可得知,需要分析GPIOF章节设置按键引脚为输入模式,分析EXTI章节这是检测中断的触发方式,分析GIC章节,设置GPIOF引脚为对应的中断号。

3.RCC章节分析

        a.RCC_MP_AHB4ENSETR寄存器分析

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

        使能GPIOF控制器需要设置RCC_MP_AHB4ENSETR寄存器地址的第五位为0x1。

4.GPIO章节分析

        a.GPIOx _MODER寄存器分析

        

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

         GPIOF_MODER寄存器的第19位到第14位全部设置为0,即可将三个按键都设置为输入模式。

5.EXTI章节分析

        

        a.EXTI_EXTICR3寄存器分析

        

          地址=基地址+偏移地址=0x5000D000+0x068=0x5000D068。

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

          EXTI_EXTICRn(n:1~4),有四个这样的控制器是因为通过EXTI框图分析可得知一共有16个EXTI,而EXTI_EXTICRn寄存器每8位管理一个EXTI,一个寄存器32位,最多管理四个。

        EXTI编号/4=商 ... 余数,商+1:对应的哪一个寄存器,余数*8:对应的寄存器八位中的最低位。

        b.EXTI_FTSR1寄存器分析

        

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

        key1--->PF9--->EXTI9--->对应事件9--->EXTI_FTSR1寄存器第9位设置为0x1。

        key2--->PF7--->EXTI7--->对应事件7--->EXTI_FTSR1寄存器第7位设置为0x1。

        key3--->PF8--->EXTI8--->对应事件8--->EXTI_FTSR1寄存器第8位设置为0x1。

        c.EXTI_IMR1寄存器分析

        

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

        key1--->PF9--->EXTI9--->对应事件9--->EXTI_IMR1寄存器第9位设置为0x1--->中断不屏蔽。

        key2--->PF7--->EXTI7--->对应事件7--->EXTI_IMR1寄存器第7位设置为0x1--->中断不屏蔽。

        key3--->PF8--->EXTI8--->对应事件8--->EXTI_IMR1寄存器第8位设置为0x1--->中断不屏蔽。

        d.EXTI_FPR1寄存器分析

        

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

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

        读0:中断没有发生,读1:中断发生。

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

        key1--->PF9--->EXTI9--->对应事件9--->EXTI_FPR1寄存器第9位设置为0x1--->清除中断挂起标志位。

        key2--->PF7--->EXTI7--->对应事件7--->EXTI_FPR1寄存器第7位设置为0x1--->清除中断挂起标志位。

        key3--->PF8--->EXTI8--->对应事件8--->EXTI_FPR1寄存器第8位设置为0x1--->清除中断挂起标志位。

6.GICD章节分析

                               

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

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

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

        a.GICD_CTLR寄存器分析

        

         设置GICD层CPU0组使能,即设置第0位为0x1。

        b.GICD_ISENABLERx寄存器分析

        

         GICD_ISENABLERx:终端设置使能寄存器,有9个该寄存器是因为GIC层一共管理288个中断号(16个SGI,16个PPI,256个SPI),GICD_ISENABLERx每1位管理一个中断号,所以一个寄存器最多管理32个中断号。  

        key1--->PF9--->EXTI9--->对应事件9--->GICD_ISENABLER3寄存器第3位设置为0x1--->中断号99。

        key2--->PF7--->EXTI7--->对应事件7--->GICD_ISENABLER3寄存器第1位设置为0x1--->中断号97。

        key3--->PF8--->EXTI8--->对应事件8--->GICD_ISENABLER3寄存器第2位设置为0x1--->中断号98。

        中断号/32=商 ... 余数,商:中断号对应要操作的寄存器,余数:中断号对应操作寄存器的位数。

        d.GICD_IPRIORITYRx寄存器分析

        

         GICD_IPRIORITYRx:中断优先级设置寄存器,有72个该寄存器的是因为GIC层一共管理288个中断号(16个SGI,16个PPI,256个SPI),GICD_IPRIORITYRx每8位管理 一个中断号,所以一个寄存器最多管理4个中断号。

        中断优先级设置时,数字越小代表优先级越高。

        key1--->PF9--->EXTI9--->对应事件9--->设置GICD_IPRIORITYR24寄存器第31位到第27位--->中断号99。

        key2--->PF7--->EXTI7--->对应事件7--->设置GICD_IPRIORITYR24寄存器第15位到第11位--->中断号97。

        key3--->PF8--->EXTI8--->对应事件8--->设置GICD_IPRIORITYR24寄存器第23位到第19位--->中断号98。

        中断号/4=商 ... 余数,商:中断号对应要操作的寄存器,余数*8+3:中断号对应操作寄存器的位数。

        e.GICD_ITARGETSRx寄存器分析

        

         GICD_ITARGETSRx:中断优先级设置寄存器,有72个该寄存器的是因为GIC层一共管理288个中断号(16个SGI,16个PPI,256个SPI),GICD_ITARGETSRx每8位管理 一个中断号,所以一个寄存器最多管理4个中断号。

        key1--->PF9--->EXTI9--->对应事件9--->设置GICD_ITARGETSR24寄存器第25位到第24位为0bx1--->中断号99。

        key2--->PF7--->EXTI7--->对应事件7--->设置GICD_ITARGETSR24寄存器第9位到第8位为0bx1--->中断号97。

        key3--->PF8--->EXTI8--->对应事件8--->设置GICD_ITARGETSR24寄存器第17位到第16位为0bx1--->中断号98。

        中断号/4=商 ... 余数,商:中断号对应要操作的寄存器,余数*8:中断号对应操作寄存器的位数。

        0bx1---> 分配给CPU0,0b1x--->分配给CPU1,0b11--->分配给CPU0和CPU1。

        f.GICD_ICPENDRx寄存器分析

        

        GICD_ICPENDRx:中断清除GICD层挂起标志位寄存器,有9个该寄存器是因为GIC层一共管理288个中断号(16个SGI,16个PPI,256个SPI),GICD_ISENABLERx每1位管理一个中断号,所以一个寄存器最多管理32个中断号。  

        key1--->PF9--->EXTI9--->对应事件9--->GICD_ICPENDR3寄存器第3位设置为0x1--->中断号99。

        key2--->PF7--->EXTI7--->对应事件7--->GICD_ICPENDR3寄存器第1位设置为0x1--->中断号97。

        key3--->PF8--->EXTI8--->对应事件8--->GICD_ICPENDR3寄存器第2位设置为0x1--->中断号98。

        中断号/32=商 ... 余数,商:中断号对应要操作的寄存器,余数:中断号对应操作寄存器的位数。

7.GICC章节分析

        a.GICC_CTLR寄存器分析

        

         设置GICC层CPU0组使能,即设置第0位为0x1。

        b.GICC_PMR寄存器分析

        

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

        c.GICC_IAR寄存器分析

        

         GICC_IAR的作用:获取按键的中断号,存储在第九位到第0位。

        d.GICC_EOIR寄存器分析

        

         GICC_EOIR的作用:清除中断号。

代码编写:

key.h文件

#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();

//初始化EXTI层
void pf8_exti_init();
//初始化GICD层
void pf8_gicd_init();
//初始化GICC层
void pf8_gicc_init();

//初始化EXTI层
void pf7_exti_init();
//初始化GICD层
void pf7_gicd_init();
//初始化GICC层
void pf7_gicc_init();
#endif

key.c文件

#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;
}

/*void pf8_exti_init()
{
	RCC->MP_AHB4ENSETR |= (0x1 << 5);	
	GPIOF->MODER &= (~(0x3 << 16));
	EXTI->EXTICR3 |= (0x05);
	EXTI->FTSR1 |= (0x1 << 8);
	EXTI->C1IMR1 |= (0x1 << 8);
}

void pf7_exti_init()
{
	RCC->MP_AHB4ENSETR |= (0x1 << 5);	
	GPIOF->MODER &= (~(0x3 << 14));
	EXTI->EXTICR2 &= (~(0xff << 24));
	EXTI->EXTICR2 |= (0x05 << 24);
	EXTI->FTSR1 |= (0x1 << 7);
	EXTI->C1IMR1 |= (0x1 << 7);
}*/

//初始化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;
}

/*void pf8_gicd_init()
{
	GICD->CTRL |= 0x1;
	GICD->ISENABLER[3] |= (0x1 << 2);
	GICD->IPRIORITYR[24] |= (0x01 << 19);
	GICD->ITARGETSR[24] |= (0x1 << 16);
}

void pf7_gicd_init()
{
	GICD->CTRL |= 0x1;
	GICD->ISENABLER[3] |= (0x1 << 1);
	GICD->IPRIORITYR[24] |= (0x01 << 11);
	GICD->ITARGETSR[24] |= (0x1 << 8);
}*/

//初始化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;
}

/*void pf8_gicc_init()
{
	GICC->CTRL |= 0x1;
	GICC->PMR |= (0x02 << 3);
}

void pf7_gicc_init()
{
	GICC->CTRL |= 0x1;
	GICC->PMR |= (0x02 << 3);
}*/

main.c文件

#include "key.h"
extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
	int i,j;
	for(i = 0; i < ms;i++)
		for (j = 0; j < 1800; j++);
}

int main()
{
	pf9_exti_init();
//	pf8_exti_init();
//	pf7_exti_init();
	pf9_gicd_init();
//	pf8_gicd_init();
//	pf7_gicd_init();
	pf9_gicc_init();
//	pf8_gicc_init();
//	pf7_gicc_init();
	while(1)
	{

	}
	return 0;
}

测试结果:

        

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值