ARM——cortex-A7核 按键中断实验

控制按键key1、2、3,实现,按下按钮时,串口工具内输出对应按键名

本开发板为:stm32mp157

查找芯片手册得:key1、2、3的引脚分别对应PF9、PF7、PF8。

以Key1为例:

PF9对应GPIOF寄存器,用RCC寄存器使能,再设置为输入模式。

以下归属于函数:void pf9_exti_init();

//使能GPIOF
	RCC->MP_AHB4ENSETR = (0x1 << 5);
	
	/*****GPIO章节初始化*****/
	//设置PF9引脚为输入模式
	//GPIOF_MODER[19:18] = 0b00
	GPIOF->MODER &= (~(0x3 << 18));

ARM——cortex-A7核 按键中断实验_第1张图片

 

设置PF9与EXTI9连接,这样才能把信号传递进去

/*******EXTI章节初始化********/
	//1.设置PF9引脚和EXTI9控制器进行链接
	//EXIT_EXTICR3[15:8] = 0x05
	EXTI->EXTICR3 &= (~(0xff << 8));  //清零
	EXTI->EXTICR3 |= (0x05 << 8);   //置1

因为我们采取的是按下按钮响应,所以要监控下降沿

//2.设置PF9引脚检测方式为下降沿
	//EXTI_FTSR1[9] = 0x01
	EXTI->FTSR1 |= (0x1 << 9);
//3.设置PF9引脚中断不屏蔽
	//EXTI_IMR1[9] = 0x01
	EXTI->C1IMR1 |= (0x01 << 9);

设置GIC部分,以下归属于函数:void pf9_gicd_init() ;

ARM——cortex-A7核 按键中断实验_第2张图片

 初始化GICD

先设置全局中断使能寄存器

GICD->CTRL |= (0X01 << 0);

设置GICD层中断使能寄存器

	//EXTI9-->99号-->GICD_ISENABLER[3][3] = 1
	GICD->ISENABLER[3] |= (0x1 << 3);

设置GICD层中断优先级寄存器 

	//99号中断-->GICD_IPRIORITYR24[31:27] = 10 //数字随意
	GICD->IPRIORITYR[24] &= (~(0x1F << 27));  //清零
	GICD->IPRIORITYR[24] |= (0x1 << 27);

设置GICD层中断目标分配器 

	//99号中断 --> 99/4 = 24....3 --> GICD_ITARGETSR24[25:24] = 0bx1(x代表0、1任意值)
	GICD->ITARGETSR[24] &= (~(0x3 << 24));
	GICD->ITARGETSR[24] |= (0x1 << 24);

 设置GICC层,以下归属于函数:void pf9_gicc_init();

    //设置GICC层全局中断使能寄存器
	GICC->CTRL |= (0x1 << 0);

	//设置GICC层中断优先级寄存器
	GICC->PMR &= (~(0x1F << 3));
	GICC->PMR |= (0xF << 3);  //优先级设置为15

这样初始化要写三个函数有点麻烦,于是把三个函数集成到另一个函数中

//包裹pf9
void PF9_init()
{
	pf9_exti_init();
	pf9_gicd_init();
	pf9_gicc_init();
}

在irq.c文件中,获取中断信号

//获取中断信号
unsigned int num = 0;
num = GICC->IAR;

调用switch选择结构

case 99:
		delay_ms(500); //防按键抖动
		printf("key1######\n");
		//清除EXTI中断挂起标志位
		EXTI->FPR1 |= (0x1 << 9);
		//清除GICD层中断挂起标志位
		//key1-->PF9-->EXTI9-->事件9-->中断号99
		//99 / 32 = 3...3
		GICD->ICPENDR[3] |= (0x1 << 3);

		break;

在选择结构外,清除中断信号

//清除中断信号
	GICC->EOIR &= (~(0x3FF << 0));
	GICC->EOIR |= num;

附上完整代码,

尤其要注意,由于该板的问题,key2和key1、3部分寄存器不在同一个。比如 EXIT_EXTICRx 寄存器,key1、3是EXIT_EXTICR3,而key2是EXIT_EXTICR2,不要写错了。

头文件

#ifndef __KEY_H__
#define __KEY_H__

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gic.h"

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

//初始化GICD层
void pf9_gicd_init();

//初始化GICC层
void pf9_gicc_init();

//包裹pf9
void PF9_init();

/******KEY2----->PF7******/
//初始化EXTI层
void pf7_exti_init();

//初始化GICD层
void pf7_gicd_init();

//初始化GICC层
void pf7_gicc_init();

//包裹pf9
void PF7_init();

/******KEY3----->PF9******/
//初始化EXTI层
void pf8_exti_init();

//初始化GICD层
void pf8_gicd_init();

//初始化GICC层
void pf8_gicc_init();

//包裹pf8
void PF8_init();


#endif

功能函数:

#include "key.h"

//初始化EXTI层
void pf9_exti_init()
{
	/***********RCC初始化**************/
	//使能GPIOF
	RCC->MP_AHB4ENSETR = (0x1 << 5);
	
	/*****GPIO章节初始化*****/
	//设置PF9引脚为输入模式
	//GPIOF_MODER[19:18] = 0b00
	GPIOF->MODER &= (~(0x3 << 18));

	/*******EXTI章节初始化********/
	//1.设置PF9引脚和EXTI9控制器进行链接
	//EXIT_EXTICR3[15:8] = 0x05
	EXTI->EXTICR3 &= (~(0xff << 8));  //清零
	EXTI->EXTICR3 |= (0x05 << 8);   //置1

	//2.设置PF9引脚检测方式为下降沿
	//EXTI_FTSR1[9] = 0x01
	EXTI->FTSR1 |= (0x1 << 9);

	//3.设置PF9引脚中断不屏蔽
	//EXTI_IMR1[9] = 0x01
	EXTI->C1IMR1 |= (0x01 << 9);
}

//初始化GICD层
void pf9_gicd_init()
{
	//设置GICD层全局中断使能寄存器
	GICD->CTRL |= (0X01 << 0);
	
	//设置GICD层中断使能寄存器
	//EXTI9-->99号-->GICD_ISENABLER[3][3] = 1
	GICD->ISENABLER[3] |= (0x1 << 3);

	//设置GICD层中断优先级寄存器
	//99号中断-->GICD_IPRIORITYR24[31:27] = 10 //数字随意
	GICD->IPRIORITYR[24] &= (~(0x1F << 27));  //清零
	GICD->IPRIORITYR[24] |= (0x1 << 27);

	//设置GICD层中断目标分配器
	//99号中断 --> 99/4 = 24....3 --> GICD_ITARGETSR24[25:24] = 0bx1(x代表0、1任意值)
	GICD->ITARGETSR[24] &= (~(0x3 << 24));
	GICD->ITARGETSR[24] |= (0x1 << 24);
}


//初始化GICC
void pf9_gicc_init()
{
	//设置GICC层全局中断使能寄存器
	GICC->CTRL |= (0x1 << 0);

	//设置GICC层中断优先级寄存器
	GICC->PMR &= (~(0x1F << 3));
	GICC->PMR |= (0xF << 3);  //优先级设置为15
}


//初始化EXTI层
void pf7_exti_init()
{
	/***********RCC初始化**************/
	//使能GPIOF
	//RCC->MP_AHB4ENSETR = (0x1 << 5);
	
	/*****GPIO章节初始化*****/
	//设置PF7引脚为输入模式
	//GPIOF_MODER[15:14] = 0b00
	GPIOF->MODER &= (~(0x3 << 14));

	/*******EXTI章节初始化********/
	//1.设置PF7引脚和EXTI控制器进行链接
	//EXIT_EXTICR2[31:24] = 0x05
	EXTI->EXTICR2 &= (~(0xff << 24));  //清零
	EXTI->EXTICR2 |= (0x05 << 24);   //置1

	//2.设置PF7引脚检测方式为下降沿
	//EXTI_FTSR1[7] = 0x01
	EXTI->FTSR1 |= (0x1 << 7);

	//3.设置PF7引脚中断不屏蔽
	//EXTI_IMR1[7] = 0x01
	EXTI->C1IMR1 |= (0x01 << 7);
}

//初始化GICD层
void pf7_gicd_init()
{
	//设置GICD层全局中断使能寄存器
	//GICD->CTRL |= (0X01 << 0);
	
	//设置GICD层中断使能寄存器
	//EXTI7-->97号-->GICD_ISENABLER[3][1] = 1
	GICD->ISENABLER[3] |= (0x1 << 1);

	//设置GICD层中断优先级寄存器
	//99号中断-->GICD_IPRIORITYR24[31:27] = 2 //数字随意
	GICD->IPRIORITYR[24] &= (~(0x1F << 11));  //清零
	GICD->IPRIORITYR[24] |= (0x2 << 11);

	//设置GICD层中断目标分配器
	//99号中断 --> 97/4 = 24....1 --> GICD_ITARGETSR24[9:8] = 0bx1(x代表0、1任意值)
	GICD->ITARGETSR[24] &= (~(0x3 << 8));
	GICD->ITARGETSR[24] |= (0x1 << 8);
}


//初始化GICC
void pf7_gicc_init()
{
	//设置GICC层全局中断使能寄存器
	//GICC->CTRL |= (0x1 << 0);

	//设置GICC层中断优先级寄存器
	GICC->PMR &= (~(0x1F << 3));
	GICC->PMR |= (0x10 << 3);  //优先级设置为15
}


//初始化EXTI层
void pf8_exti_init()
{
	/***********RCC初始化**************/
	//使能GPIOF
	//RCC->MP_AHB4ENSETR = (0x1 << 5);
	
	/*****GPIO章节初始化*****/
	//设置PF8引脚为输入模式
	//GPIOF_MODER[17:16] = 0b00
	GPIOF->MODER &= (~(0x3 << 16));

	/*******EXTI章节初始化********/
	//1.设置PF8引脚和EXTI8控制器进行链接
	//EXIT_EXTICR3[7:0] = 0x05
	EXTI->EXTICR3 &= (~(0xff << 0));  //清零
	EXTI->EXTICR3 |= (0x05 << 0);   //置1

	//2.设置PF8引脚检测方式为下降沿
	//EXTI_FTSR1[8] = 0x01
	EXTI->FTSR1 |= (0x1 << 8);

	//3.设置PF9引脚中断不屏蔽
	//EXTI_IMR1[8] = 0x01
	EXTI->C1IMR1 |= (0x01 << 8);
}

//初始化GICD层
void pf8_gicd_init()
{
	//设置GICD层全局中断使能寄存器
	//GICD->CTRL |= (0X01 << 0);
	
	//设置GICD层中断使能寄存器
	//EXTI8-->98号-->GICD_ISENABLER[3][2] = 1
	GICD->ISENABLER[3] |= (0x1 << 2);

	//设置GICD层中断优先级寄存器
	//98号中断-->GICD_IPRIORITYR24[23:19] = 3 //数字随意
	GICD->IPRIORITYR[24] &= (~(0x1F << 27));  //清零
	GICD->IPRIORITYR[24] |= (0x3 << 27);

	//设置GICD层中断目标分配器
	//98号中断 --> 98/4 = 24....2 --> GICD_ITARGETSR24[17:16] = 0bx1(x代表0、1任意值)
	GICD->ITARGETSR[24] &= (~(0x3 << 16));
	GICD->ITARGETSR[24] |= (0x1 << 16);
}


//初始化GICC
void pf8_gicc_init()
{
	//设置GICC层全局中断使能寄存器
	//GICC->CTRL |= (0x1 << 0);

	//设置GICC层中断优先级寄存器
	GICC->PMR &= (~(0x1F << 3));
	GICC->PMR |= (0x11 << 3);  //优先级设置为17
}



//包裹pf9
void PF7_init()
{
	pf7_exti_init();
	pf7_gicd_init();
	pf7_gicc_init();
}



//包裹pf9
void PF8_init()
{
	pf8_exti_init();
	pf8_gicd_init();
	pf8_gicc_init();
}



//包裹pf9
void PF9_init()
{
	pf9_exti_init();
	pf9_gicd_init();
	pf9_gicc_init();
}

irq.c

#include "key.h"

extern void delay_ms(int ms);

extern void printf(const char *fmt, ...);

//unsigned int i = 0;
void do_irq(void) 
{
	unsigned int num = 0;
	//获取中断信号
	num = GICC->IAR;
	switch(num)
	{
	case 97:	
		delay_ms(500); //防按键抖动
		printf("key2######\n");
		//清除EXTI中断挂起标志位
		EXTI->FPR1 |= (0x1 << 7);
		//清除GICD层中断挂起标志位
		//key1-->PF9-->EXTI9-->事件9-->中断号99
		//97 / 32 = 3...1
		GICD->ICPENDR[3] |= (0x1 << 1);

		break;
	case 98:	
		delay_ms(500); //防按键抖动
		printf("key3######\n");
		//清除EXTI中断挂起标志位
		EXTI->FPR1 |= (0x1 << 8);
		//清除GICD层中断挂起标志位
		//key1-->PF9-->EXTI9-->事件9-->中断号99
		//98 / 32 = 3...2
		GICD->ICPENDR[3] |= (0x1 << 2);

		break;
	case 99:
		delay_ms(500); //防按键抖动
		printf("key1######\n");
		//清除EXTI中断挂起标志位
		EXTI->FPR1 |= (0x1 << 9);
		//清除GICD层中断挂起标志位
		//key1-->PF9-->EXTI9-->事件9-->中断号99
		//99 / 32 = 3...3
		GICD->ICPENDR[3] |= (0x1 << 3);

		break;
	}
	//清除中断信号
	GICC->EOIR &= (~(0x3FF << 0));
	GICC->EOIR |= num;
}

你可能感兴趣的:(每日练习,arm,单片机,stm32)