main.h
cpp
#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串口工具打印一个b
while(1)
{
}
return 0;
}
key_interrupt.h
cpp
#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
cpp
#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.允许中断不屏蔽,可以被转发到GIC
EXTI->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位先清零,再置位为0x05
EXTI->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组使能----------------------PF7
RCC->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.设置使能进入GICC
GICD->CTLR |= (0x1);
//11.设置优先级掩码
GICC->PMR |= (0x1f << 3);
//10.设置允许进入GICC
GICC->CTRL |= 0x1;
}
do_irq
cpp
#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;
}