key.h
#ifndef _H_
#define _H_
//KEY1-->PF9
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
void key_rcc_gpio_init();
void led_gpio_init(gpio_t *gpiox,unsigned int pin);
void hal_exit_pf9_init(unsigned int pin);
void hal_gic_pf9_init(unsigned int id);
#endif
key.c
#include "key.h"
void key_rcc_gpio_init()
{
//RCC章节初始化 GPIOF组控制器使能[5]=1
RCC->MP_AHB4ENSETR |=(0x1<<5);
//GPIO章节初始化 PF9[19,18],8[15,14],7[17,16]输入模式=00
GPIOF->MODER &= (~(0x3 << 18));
GPIOF->MODER &= (~(0x3 << 14));
GPIOF->MODER &= (~(0x3 << 16));
}
void led_gpio_init(gpio_t *gpiox,unsigned int pin)
{
//GPIO的led章节初始化
//MODER设置为输出模式01
gpiox->MODER &= (~(0x3 << 2*pin));
gpiox->MODER |= (0X1 << 2*pin);
//OTYPER设置为推挽输出类型0
gpiox->OTYPER &=(~(0X1 << pin));
//OSPEEDR设置为输出低速 00
gpiox->OSPEEDR &= (~(0X3 << 2*pin));
//PUPDR设置为禁止上下拉电阻 00
gpiox->PUPDR &= (~(0x3 << 2*pin));
//ODR设置为开关
//gpiox->ODR &= (~(0X1 << pin));熄灭
//gpiox->ODR |= (0x1 << pin);点亮
}
//RCC/GPIO/EXTI章节初始化
void hal_exit_pf9_init(unsigned int pin)
{
//EXTI章节初始化
//EXTICR3 外部中断选择寄存器 按键与引脚连接 [15:8][31:24][7:0]=0x05
if((pin/4)+1==3)
{
EXTI->EXTICR3 &= (~(0xff << (pin%4)*8));
EXTI->EXTICR3 |= (0x5 << (pin%4)*8);
}
else if((pin/4)+1==2)
{
EXTI->EXTICR2 &= (~(0xff <<(pin%4)*8));
EXTI->EXTICR2 |= (0x5 <<(pin%4)*8);
}
//FTSR1 [9:7]=0x7 设置触发为下降沿
EXTI->FTSR1 |= (0x1 << pin);
//IMR1 [9:7]=0X7 中断屏蔽器
EXTI->C1IMR1 |= (0X1 << pin);
}
//GIC章节初始化
void hal_gic_pf9_init(unsigned int id)
{
//GPCD章节初始化
//CTLR [0]=0X0
GICD->CTRL |= (0x1 <<0);
//ISENABLER3 [3:1]=0X1
GICD->ISENABLER[3] |= (0x1 << (id%32));
//IPRIORITYR4 [31:27][15:11][23:19]=0B00000
GICD->IPRIORITYR[24] &= (~(0x1f << (id%4*8+3)));
//ITARGETSR4 [25:24][9:8][17:16]=0B01
GICD->ITARGETSR[24] &= (~(0X3 << (id%4*8)));
GICD->ITARGETSR[24] |= (0X1 << (id%4*8));
//GPCC章节初始化
//CTLR[0]=1
GICC->CTRL |= (0X1);
//PMR[7:3]=0B11111
GICC->PMR |= (0X1F <<3);
}
do_irq.c
#include "key.h"
extern void printf(const char *fmt, ...);
unsigned int i = 0;
//中断处理函数
void do_irq(void)
{
//1.获取中断号
i=GICC->IAR &(0x3ff);
//2.判断中断号,并且打印一句话
switch(i)
{
case 99:
printf("I am key1\n");
//3.清除EXTI层中断挂起标志位
EXTI->FPR1 |= (0X1 <<9);
//4.清除GICD层中断挂起标志位 ICPENDR[3]第三位
GICD->ICPENDR[3] |= (0X1 <<3);
GPIOE->ODR ^=(0X1<<10);
break;
case 98:
printf("I am key3\n");
//3.清除EXTI层中断挂起标志位
EXTI->FPR1 |= (0X1 <<8);
//4.清除GICD层中断挂起标志位 ICPENDR[3]第三位
GICD->ICPENDR[3] |= (0X1 <<2);
GPIOE->ODR ^=(0X1<<8);
break;
case 97:
printf("I am key2\n");
//3.清除EXTI层中断挂起标志位
EXTI->FPR1 |= (0X1 <<7);
//4.清除GICD层中断挂起标志位 ICPENDR[3]第三位
GICD->ICPENDR[3] |= (0X1 <<1);
GPIOF->ODR ^=(0X1<<10);
break;
}
//5.清除获取到中断号
GICC->EOIR = i;
}
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()
{
key_rcc_gpio_init();
led_gpio_init(GPIOE,10);
led_gpio_init(GPIOF,10);
led_gpio_init(GPIOE,8);
hal_exit_pf9_init(7);
hal_exit_pf9_init(8);
hal_exit_pf9_init(9);
hal_gic_pf9_init(97);
hal_gic_pf9_init(98);
hal_gic_pf9_init(99);
while(1);
return 0;
}