main.h
#include "key_interrupt.h"#include "myuart.h"void delay(int ms){int i,j;for(i=0;i<ms;i++){for(j=0;j<2000;j++);}}int main(){//中断初始化key1_it_config();key2_it_config();key3_it_config();//灯初始化led_init();//现象是发送一个a串口工具打印一个bwhile(1){}return 0;}
key_interrupt.h
#ifndef __KEY_INTERRUPT_H__
#define __KEY_INTERRUPT_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gic.h"void key1_it_config();
void key2_it_config();
void key3_it_config();
#endif
key_interrupt.c
#include"key_interrupt.h"void key1_it_config()
{// 1.设置GPIOF时钟使能RCC->MP_AHB4ENSETR |= (0x1 << 5);// 2.将PF9管脚设置为输入GPIOF->MODER &= (~(0x3 << 18));// 3.设置由PF9产生EXTI9事件EXTI->EXTICR3 &= (~(0xff << 8));EXTI->EXTICR3 |= (0x05 <<8);// 4.设置EXTI9事件的检测方式为下降沿检测EXTI->FTSR1 |= (0x1 << 9);// 5.允许中断不屏蔽,可以被转发到GICEXTI->C1IMR1 |= (0x1 << 9);// 6.允许EXTI9(99号)中断被保存在组0中GICD->ISENABLER[3] |= (0x1 << 3);// 7.设置99号中断优先级GICD->IPRIORITYR[24] &= (~(0x1f << 27));GICD->IPRIORITYR[24] |= (0x0 << 27);// 8.设置99号中断可以被CPU0处理GICD->ITARGETSR[24] &= (~(0x3 << 24));GICD->ITARGETSR[24] |= (0x1 << 24);// 9.允许99号中断被转发到CPU接口层GICD->CTLR |= (0x1);// 10.设置中断优先级掩码GICC->PMR |= (0x1f<<3);// 11.允许中断被转发给CPU处理GICC->CTRL |= (0x1);}
void key3_it_config()
{//设置GPIOF时钟使能RCC->MP_AHB4ENSETR |= (0x1 << 5);//将PF8设置为输入模式GPIOF->MODER &= (~(0x3 << 16));//设置由PF8产生EXIT8事件---[7:0]的8位先清零,再置位为0x05EXTI->EXTICR3 &= (~(0xff));EXTI->EXTICR3 |= (0x05);//设置下降沿检测EXTI->FTSR1 |= (0x1 << 8);//设置中断不屏蔽EXTI->C1IMR1 |= (0x1 << 8);//设置允许中断发送到GICD中GICD->ISENABLER[3] |= (0x1 << 2);//设置优先级GICD->IPRIORITYR[24] &= (~(0x1f << 19));GICD->IPRIORITYR[24] |= (0x0 << 19);//选择进程目标处理器GICD->ITARGETSR[24] &= (~(0x3 << 16));GICD->ITARGETSR[24] |= (0x1 << 16);//允许中断到CPU接口层GICD->CTLR |= (0x1);//使能中断转发到CPU中GICC->CTRL |= 0x1;//设置优先级掩码GICC->PMR |= (0x1f << 3);}void key2_it_config()
{//1.设置GPIOF组使能----------------------PF7RCC->MP_AHB4ENSETR |= (0x1<<5);//2.设置PF7为输入模式GPIOF->MODER &= (~(0x3 << 14));//3.设置exti的事件选择为exti7模式EXTI->EXTICR2 &= (~(0xff << 24));EXTI->EXTICR2 |= (0x05 << 24);//4.设置不屏蔽中断EXTI->C1IMR1 |= (0x1 << 7);//5.设置下降沿检测EXTI->FTSR1 |= (0x1 << 7);//6.GICD允许中断进入GICD中GICD->ISENABLER[3] |= (0x1 << 1);//7.设置优先级GICD->IPRIORITYR[24] &= (~(0x1f << 11));GICD->IPRIORITYR[24] |= (0x0 << 11);//8.设置目标处理器GICD->ITARGETSR[24] &= ((~0x3 << 8));GICD->ITARGETSR[24] |= (0x1 << 8);//9.设置使能进入GICCGICD->CTLR |= (0x1);//11.设置优先级掩码GICC->PMR |= (0x1f << 3);//10.设置允许进入GICCGICC->CTRL |= 0x1;
}
do_irq
#include "key_interrupt.h"
#include "myuart.h"extern void printf(const char *fmt, ...);
unsigned int i = 0;
void do_irq(void)
{//获取中断号,根据中断号的不同进行不同的中断处理int irqno;irqno=GICC->IAR&0x3ff;static int i=0,j=0,k=0;switch(irqno){case 99:printf("key1 int\n");if(i==0){led1_on();i = 1;}else if(i==1){led1_off();i = 0;}//清除exti中断标志位EXTI->FPR1 |= (0x1 << 9);//清除GICD中断标志位GICD->ICPENDR[3] = (0x1 << 3);break;case 98:printf("key3 int\n");if(k==0){led3_on();k = 1;}else if(k==1){led3_off();k = 0;}//清除exti中断标志位EXTI->FPR1 |= (0x1 <<8);//清除GICD中断标志位GICD->ICPENDR[3] |= (0x1 <<2);break;case 97:printf("key2 int\n");if(j==0){led2_on();j = 1;}else if(j==1){led2_off();j = 0;}EXTI->FPR1 |= (0x1 << 7);GICD->ICPENDR[3] |= (0x1 << 1);break;}//清除IAR寄存器的值GICC->EOIR = irqno;}