key.h
#ifndef __KEY_H__
#define __KEY_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"
void hal_key_init();
#endif
key.c
#include "key.h"
void hal_key_init()
{
/*******RCC章节初始化********/
RCC->MP_AHB4ENSETR|=(0x1<<5);
/*******GPIO章节初始化*************/
//1.key1设置为输入模式
GPIOF->MODER&=(~(0x3<<18));
//2.key2设置为输入模式
GPIOF->MODER&=(~(0x3<<14));
//3.key3设置为输入模式
GPIOF->MODER&=(~(0x3<<16));
/************EXTI章节初始化****************/
/********EXTI_EXTICRn********/
//1.key1:EXTI_EXTICR3[15:8]=0x05
EXTI->EXTICR3|=(0x5<<8);
//2.key2:EXTI_EXTICR2[31:24]=0x05
EXTI->EXTICR2|=(0x5<<24);
//3.key3:EXTI_EXTICR3[7:0]=0x05
EXTI->EXTICR3|=(0x5<<0);
/************EXTI_FTSR1下降沿选择寄存器********/
//1.key1:EXTI_FTSR1[9]=1
EXTI->FTSR1|=(0x1<<9);
//2.key2:EXTI_FTSR1[7]=1
EXTI->FTSR1|=(0x1<<7);
//3.key3:EXTI_FTSR1[8]=1
EXTI->FTSR1|=(0x1<<8);
/******EXTI_IMR1设置中断是否屏蔽**********/
//1.key1:EXTI_IMR1[9]=1
EXTI->C1IMR1|=(0x1<<9);
//2.key2:EXTI_IMR1[7]=1
EXTI->C1IMR1|=(0x1<<7);
//3.key3:EXTI_IMR1[8]=1
EXTI->C1IMR1|=(0x1<<8);
/**********GIC章节初始化***************/
//使能GICD层
GICD->CTLR|=0x1;
//GICD_ISENABLERx中断设置使能寄存器
//1.key1
GICD->ISENABLER[3]|=(0x1<<3);
//2.key2
GICD->ISENABLER[3]|=(0x1<<1);
//3.key3
GICD->ISENABLER[3]|=(0x1<<2);
//GICD_IPRIORITYRx
//1.key1:GICD_IPRIORITYR24[31:27]
GICD->IPRIORITYR[24]|=(0x1<<27);
//2.key2:GICD_IPRIORITYR24[15:11]
GICD->IPRIORITYR[24]|=(0x1<<11);
//3.key3:GICD_IPRIORITYR24[23:19]
GICD->IPRIORITYR[24]|=(0x1<<19);
//GICD_ITARGETSRx
//1.key1:GICD_ITARGETSR24[25:24]
GICD->ITARGETSR[24]|=(0x1<<24);
//2.key2:GICD_ITARGETSR24[9:8]
GICD->ITARGETSR[24]|=(0x1<<8);
//1.key1:GICD_ITARGETSR24[17:16]
GICD->ITARGETSR[24]|=(0x1<<16);
//GICC层使能
GICC->CTLR|=0x1;
//设置GICC中断优先级屏蔽寄存器
GICC->PMR|=(0x5<<3);
}
do_irq.c
#include "key.h"
extern void printf(const char *fmt, ...);
extern void delay_ms(int ms);
void do_irq(void)
{
unsigned int num = 0;
//获取中断号
num = GICC->IAR & 0X3FF;
switch(num)
{
case 97:
delay_ms(500);
printf("key2#######\n");
//清除EXTI层中断挂起标志位
EXTI->FPR1 |= (0X1<<7);
//清除GICD层中断挂起标志位
GICD->ICPENDR[3] |=(0X1<<1);
break;
case 98:
delay_ms(500);
printf("key3#######\n");
//清除EXTI层中断挂起标志位
EXTI->FPR1 |= (0X1<<8);
//清除GICD层中断挂起标志位
GICD->ICPENDR[3] |=(0X1<<2);
break;
case 99:
delay_ms(500);
printf("key1#######\n");
//清除EXTI层中断挂起标志位
EXTI->FPR1 |= (0X1<<9);
//清除GICD层中断挂起标志位
GICD->ICPENDR[3] |=(0X1<<3);
break;
}
//清除中断号
GICC->EOIR &= (~(0X3FF));
GICC->EOIR |= num;
}
main.c
#include "key.h"
extern void do_irq(void);
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()
{
hal_key_init();
while(1)
{
}
return 0;
}
实验现象: