分析电路图可知三个按键对应的管脚为:KEY1----->PF9 KEY2----->PF7 KEY3----->PF8
本次实验采用延时函数来解决按键按下时的电平抖动问题
功能分析如下
如上图所示
1.需要分析GPIOF章节:设置引脚为输入模式
2.需要分析EXTI章节:检测中断的触发方式
3.需要分析GIC章节:设置GPIOF引脚对应的中断号
代码实现
一、key.h——头文件的包络和功能函数的声明
#ifndef __KEY_H__
#define __KEY_H__#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"
#include "stm32mp1xx_gpio.h"//初始化EXTI层——key1
void pf9_exti_init();//初始化GICD层——key1
void pf9_gicd_init();//初始化GICC层——key1
void pf9_gicc_init();//初始化EXTI层——key3
void pf8_exti_init();//初始化GICD层——key3
void pf8_gicd_init();//初始化GICC层——key3
void pf8_gicc_init();//初始化EXTI层——key2
void pf7_exti_init();//初始化GICD层——key2
void pf7_gicd_init();//初始化GICC层——key2
void pf7_gicc_init();#endif
二、key.c——功能函数的声明
以key1为例
1、RCC章节初始化——设置GPIOF组时钟使能
RCC->MP_AHB4ENSETR |= (0x1 << 5);
2、GPIO章节初始化——设置PF9引脚为输入模式
GPIOF->MODER &= (~(0x3 << 18));
3、EXTI章节初始化
1)设置PF9引脚和EXIT9控制器进行连接
EXTI->EXTICR3 &= (~(0xff << 8));
EXTI->EXTICR3 |= (0x5 << 8);
2)设置PF9引脚检测方式下降沿
EXTI->FTSR1 |= (0x1 << 9);
3)设置PF9引脚中断不屏蔽
EXTI->C1IMR1 |= (0x1 << 9);
4、GICD层初始化
1)设置GICD层全局中断使能寄存器
GICD->CTRL |= (0x1 << 0);
2)设置GICD层中断使能寄存器
GICD->ISENABLER[3] |= (0x1 << 3);
3)设置GICD层中断优先级寄存器
GICD->IPRIORITYR[24] &= (~(0x1f << 27));
GICD->IPRIORITYR[24] |= (0x1 << 27);
4)设置GICD层中断目标分配寄存器
GICD->ITARGETSR[24] |= (0x3 << 24);
5、GICC层初始化
1)设置GICC层全局中断使能寄存器
GICC->CTRL |= (0x1 << 0);
2)设置GICC层中断优先级寄存器
GICC->PMR &= (~(0x1f << 3));
GICC->PMR |= (0x9 << 3);
6、完整代码
#include "key.h"//初始化EXTI层——key1
void pf9_exti_init()
{/****RCC章节初始化*******///1.设置GPIOF组时钟使能RCC->MP_AHB4ENSETR |= (0x1 << 5);/****GPIO章节初始化*******///1.设置PF9引脚为输入模式GPIOF->MODER &= (~(0x3 << 18));/*****EXTI章节初始化******///1.设置PF9引脚和EXIT9控制器进行连接EXTI->EXTICR3 &= (~(0xff << 8));EXTI->EXTICR3 |= (0x5 << 8);//2.设置PF9引脚检测方式下降沿EXTI->FTSR1 |= (0x1 << 9);//3.设置PF9引脚中断不屏蔽EXTI->C1IMR1 |= (0x1 << 9);
}//初始化GICD层——key1
void pf9_gicd_init()
{//1.设置GICD层全局中断使能寄存器GICD->CTRL |= (0x1 << 0); //2.设置GICD层中断使能寄存器GICD->ISENABLER[3] |= (0x1 << 3);//3.设置GICD层中断优先级寄存器GICD->IPRIORITYR[24] &= (~(0x1f << 27));GICD->IPRIORITYR[24] |= (0x1 << 27);//4.设置GICD层中断目标分配寄存器GICD->ITARGETSR[24] |= (0x3 << 24);
}//初始化GICC层——key1
void pf9_gicc_init()
{//1.设置GICC层全局中断使能寄存器GICC->CTRL |= (0x1 << 0);//2.设置GICC层中断优先级寄存器GICC->PMR &= (~(0x1f << 3));GICC->PMR |= (0x9 << 3);
}//初始化EXTI层——key3
void pf8_exti_init()
{/****GPIO章节初始化*******///1.设置PF8引脚为输入模式GPIOF->MODER &= (~(0x3 << 16));/*****EXTI章节初始化******///1.设置PF8引脚和EXIT8控制器进行连接EXTI->EXTICR3 &= (~(0xff << 0));EXTI->EXTICR3 |= (0x5 << 0);//2.设置PF8引脚检测方式下降沿EXTI->FTSR1 |= (0x1 << 8);//3.设置PF8引脚中断不屏蔽EXTI->C1IMR1 |= (0x1 << 8);
}//初始化GICD层——key3
void pf8_gicd_init()
{//1.设置GICD层全局中断使能寄存器GICD->CTRL |= (0x1 << 0); //2.设置GICD层中断使能寄存器GICD->ISENABLER[3] |= (0x1 << 2);//3.设置GICD层中断优先级寄存器GICD->IPRIORITYR[24] &= (~(0x1f << 19));GICD->IPRIORITYR[24] |= (0x3 << 19);//4.设置GICD层中断目标分配寄存器GICD->ITARGETSR[24] |= (0x3 << 16);
}//初始化GICC层——key3
void pf8_gicc_init()
{//1.设置GICC层全局中断使能寄存器GICC->CTRL |= (0x1 << 0);//2.设置GICC层中断优先级寄存器GICC->PMR &= (~(0x1f << 3));GICC->PMR |= (0x8 << 3);
}//初始化EXTI层——key2
void pf7_exti_init()
{/****GPIO章节初始化*******///1.设置PF7引脚为输入模式GPIOF->MODER &= (~(0x3 << 14));/*****EXTI章节初始化******///1.设置PF7引脚和EXIT7控制器进行连接EXTI->EXTICR2 &= (~(0xff << 24));EXTI->EXTICR2 |= (0x5 << 24);//2.设置PF7引脚检测方式下降沿EXTI->FTSR1 |= (0x1 << 7);//3.设置PF7引脚中断不屏蔽EXTI->C1IMR1 |= (0x1 << 7);
}//初始化GICD层——key2
void pf7_gicd_init()
{//1.设置GICD层全局中断使能寄存器GICD->CTRL |= (0x1 << 0); //2.设置GICD层中断使能寄存器GICD->ISENABLER[3] |= (0x1 << 1);//3.设置GICD层中断优先级寄存器GICD->IPRIORITYR[24] &= (~(0x1f << 11));GICD->IPRIORITYR[24] |= (0x2 << 11);//4.设置GICD层中断目标分配寄存器GICD->ITARGETSR[24] |= (0x3 << 8);
}//初始化GICC层——key2
void pf7_gicc_init()
{//1.设置GICC层全局中断使能寄存器GICC->CTRL |= (0x1 << 0);//2.设置GICC层中断优先级寄存器GICC->PMR &= (~(0x1f << 3));GICC->PMR |= (0x7 << 3);
}
三、do_irq.c——中断处理函数,当有中断产生时会自动调用该函数
实现效果为不同按键按下时,串口打印不同的提示信息
#include "key.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 & 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 << 0);GICC->EOIR |= num;
}
四、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()
{/******key1初始化*****/ //初始化EXTI层pf9_exti_init();//初始化GICD层pf9_gicd_init();//初始化GICC层pf9_gicc_init();/******key3初始化*****///初始化EXTI层pf8_exti_init();//初始化GICD层pf8_gicd_init();//初始化GICC层pf8_gicc_init();/******key3初始化*****///初始化EXTI层pf7_exti_init();//初始化GICD层pf7_gicd_init();//初始化GICC层pf7_gicc_init();while(1) //使程序不结束,响应按键的中断{}return 0;
}