ARM接口实验—中断实验

一、实验原理分析

实验板:stm32mp157a-fsmp1a

本次中断是检测按键的下降沿信号,接收到信号进入异常处理,进行相应的异常处理流程

ARM接口实验—中断实验_第1张图片

二、电路分析

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

KEY1----->PF9

KEY2----->PF7

KEY3----->PF8

ARM接口实验—中断实验_第2张图片 ARM接口实验—中断实验_第3张图片

三、框图分析

ARM接口实验—中断实验_第4张图片

 由上图可知需要分析芯片手册四个章节

RCC章节:使能GPIO控制器

GPIO章节:设置引脚为输入模式

EXTI章节:检测中断的触发方式

GIC章节:设置GPIOF引脚对应的中断号

四、工作流程图

ARM接口实验—中断实验_第5张图片

 流程分解:

1,按键按下

2,GPIO输入(MODER)

3,EXT检测中断触发

        3.1 中断选择(EXTI_EXTICR3)功能:GPIO控制器和EXTI控制器进行连接

        3.2 事件检测(下降沿)(EXTI_FTSR1)

        3.3 事件屏蔽(不屏蔽)(EXTI_IMR1)

        3.4 清除中断挂起标志位(EXTI_FPR1)

4,GIC设置GPIOF引脚对应的中断号

4.1 GICD层:分配器层

        4.1.1 使能GICD层(GICD_CTLR)

        4.1.2 中断设置使能 GICD_ISENABLERx

        4.1.3 中断优先级设置 GICD_IPRIORITYRx(数字越低优先级越高)

        4.1.4 选择CPU(GICD_ITARGETSRx)

        4.1.5 清除中断挂起标志位 GICD_ICPENDRx

4.2 GICC层:CPU接口层

        4.2.1 使能GICC层 (GICC_CTLR)

        4.2.2 优先级设置 (GICC_PMR)需要比GICD层设计的中断优先级的值要大

        4.2.3 获取中断号 GICC_IAR

        4.2.4 清除按键中断号 GICC_EOIR

 五、代码实现

按键按下,打印按键信息

 key.h

#ifndef __KEY5_H__
#define __KEY5_H__

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

//初始化EITI层
void pf9_exti_init();

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

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

//初始化GPIO层
void gpio_init();


#endif

key.c

#include "key5.h"

//初始化gpio层
void gpio_init()
{
	//rcc使能GPIOF寄存器
	RCC->MP_AHB4ENSETR |= (0X1 << 5);
	RCC->MP_AHB4ENSETR |= (0X1 << 4);

	/*****设置GPIOF系列寄存器****/

	//设置GPIOE 8,10,GPIOF 10为输出模式
	GPIOE->MODER &= (~(0x3 <<16));
	GPIOE->MODER |= (0X1<<16);
	GPIOE->MODER &= (~(0x3 <<20));
	GPIOE->MODER |= (0x1 <<20);
	GPIOF->MODER &= (~(0x3 <<20));
	GPIOF->MODER |= (0x1 <<20);

	//设置GPIOF,7,8,9模式为输入模式
	GPIOF->MODER &= (~(0X3 << 18));
	GPIOF->MODER &= (~(0X3 << 16));
	GPIOF->MODER &= (~(0X3 << 14));
	
	//设置GPIOE 8,10,GPIOF 10的输出类型
	GPIOE->OTYPER &= (~(0x1 <<8));
	GPIOE->OTYPER &= (~(0x1 <<10));
	GPIOF->OTYPER &= (~(0x1 <<10));
	//设置GPIOE 8,10,GPIOF 10的输出速度
	GPIOE->OSPEEDR &= (~(0X3 <<16));	
	GPIOE->OSPEEDR &= (~(0X3 <<20));	
	GPIOF->OSPEEDR &= (~(0X3 <<20));	
	//设置GPIOE 8,10,GPIOF 10上下拉
	GPIOE->PUPDR &= (~(0X3 <<16));
	GPIOE->PUPDR &= (~(0X3 <<20));
	GPIOF->PUPDR &= (~(0X3 <<20));
}


//初始化EITI层
void pf9_exti_init()
{
	/****设置EXTI系列寄存器*****/

	//1.中断寄存器与GPIO连接
	EXTI->EXTICR3 &= (~(0xff << 8));
	EXTI->EXTICR3 |= (0X05 << 8);
	EXTI->EXTICR3 &= (~(0xff << 0));
	EXTI->EXTICR3 |= (0X05 << 0);
	EXTI->EXTICR2 &= (~(0xff << 24));
	EXTI->EXTICR2 |= (0X05 << 24);
	
	//2.检测事件为下降沿
	EXTI->FTSR1 |= (0X1 <<7);
	EXTI->FTSR1 |= (0X1 <<8);
	EXTI->FTSR1 |= (0X1 <<9);

	//3.设置中断屏蔽寄存器为不屏蔽
	EXTI->C1IMR1 |= (0X1 <<7);
	EXTI->C1IMR1 |= (0X1 <<8);
	EXTI->C1IMR1 |= (0X1 <<9);

}

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

	/*****设置GICD系列寄存器*****/
	//使能GICD(全局)
	GICD->CTRL |= (0X1 <<0);
	//中断设置使能(对应中断号)
	GICD->ISENABLER[3] |= (0X1 <<3);
	GICD->ISENABLER[3] |= (0X1 <<1);
	GICD->ISENABLER[3] |= (0X1 <<2);
	//中断优先级设置
	GICD->IPRIORITYR[24] &= (~(0X1F <<11));
	GICD->IPRIORITYR[24] |= (0X1 <<11);
	GICD->IPRIORITYR[24] &= (~(0X1F <<19));
	GICD->IPRIORITYR[24] |= (0X1 <<19);
	GICD->IPRIORITYR[24] &= (~(0X1F <<27));
	GICD->IPRIORITYR[24] |= (0X1 <<27);
	//选择CPU,0号,设置中断目标分配
	GICD->ITARGETSR[24] &= (~(0X3 <<8));
	GICD->ITARGETSR[24] |= (0X1 <<8);
	GICD->ITARGETSR[24] &= (~(0X3 <<16));
	GICD->ITARGETSR[24] |= (0X1 <<16);
	GICD->ITARGETSR[24] &= (~(0X3 <<24));
	GICD->ITARGETSR[24] |= (0X1 <<24);


}

//初始化GICC层
void pf9_dicc_init()
{

	/*****设置GICC系列寄存器*****/

	//使能GICC
	GICC->CTRL |= (0X1 <<0);
	//输入中断优先级
	GICC->PMR &= (~(0X1F <<3));
	GICC->PMR |= (0XF <<3);
}

main.c

#include "key5.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()
{
	//调用初始化函数
	gpio_init();
	pf9_exti_init();
	pf9_gicd_init();
	pf9_dicc_init();
	while(1)
	{
	
	}
	return 0;
}

do_irq.c(异常处理函数)

#include "key5.h"

extern void printf(const char *fmt, ...);
extern void delay_ms(int ms);
unsigned int i = 0;
void do_irq(void) 
{
	unsigned int num =0;

	//获取中断号
	num=GICC->IAR & 0X1FF;
	switch(num)
	{
		case 97:
			{
				delay_ms(500);

				printf("key2######\n");
				//清除EXTI层挂起标志位
				EXTI->FPR1 |= (0x1 <<7);
				EXTI->FPR1 |= (0x1 <<8);
				EXTI->FPR1 |= (0x1 <<9);

				//清除GICD层挂起标志位
				GICD->ICPENDR[3] |= (0X1 <<3);
				GICD->ICPENDR[3] |= (0X1 <<1);
				GICD->ICPENDR[3] |= (0X1 <<2);
		
			
			}
			break;
		case 98:
			{
				delay_ms(500);

				printf("key3######\n");

				//清除EXTI层挂起标志位
				EXTI->FPR1 |= (0x1 <<7);
				EXTI->FPR1 |= (0x1 <<8);
				EXTI->FPR1 |= (0x1 <<9);

				//清除GICD层挂起标志位
				GICD->ICPENDR[3] |= (0X1 <<3);
				GICD->ICPENDR[3] |= (0X1 <<1);
				GICD->ICPENDR[3] |= (0X1 <<2);	
			}
			break;
		case 99:
			{
				delay_ms(500);


				printf("key1######\n");

				//清除EXTI层挂起标志位
				EXTI->FPR1 |= (0x1 <<7);
				EXTI->FPR1 |= (0x1 <<8);
				EXTI->FPR1 |= (0x1 <<9);

				//清除GICD层挂起标志位
				GICD->ICPENDR[3] |= (0X1 <<3);
				GICD->ICPENDR[3] |= (0X1 <<1);
				GICD->ICPENDR[3] |= (0X1 <<2);
			}
			break;
	}
	//清除中断号
	GICC->EOIR &= (~(0X1FF));
	GICC->EOIR |= num;
}

实验现象:

ARM接口实验—中断实验_第6张图片

 

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