按键中断实验
##现象展示
main.c
#include "key.h"
int main()
{
extern void printf(const char* fmt, ...);
hal_exit_key1_init();
hal_gic_key1_init();
while(1)
{
//当按键按下之后,触发irq异常源
//执行中断处理函数
//do_irq();
}
return 0;
}
key.c
#include "key.h"
void delay_ms(int ms)
{
int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 1800; j++);
}
//KEY1--->PF9
//RCC/GPIO/EXTI章节初始化
void hal_exit_key1_init()
{
//RCC章节初始化
//1.设置GPIOF组使能
RCC->MP_AHB4ENSETR |= (0X1 << 5);
//设置灯引脚使能
RCC->MP_AHB4ENSETR |= (0X1 << 4);
//GPIO章节初始化
//1.设置PF9引脚为输入模式
GPIOF->MODER &= (~(0X3 << 18)); //KEY1 PF9
GPIOF->MODER &= (~(0X3 << 14)); //KEY2 PF7
GPIOF->MODER &= (~(0X3 << 16)); //KEY3 PF8
//对LED1引脚初始化
//MODER (21:20) 01
GPIOE->MODER &= (~(0x1 << 21));
GPIOE->MODER |= (0x1 << 20);
//OTYPER (10) 0
GPIOE->OTYPER &= (~(0x1 << 10));
//OSPEEDR (21:20) 00
GPIOE->OSPEEDR &= (~(0x1 << 20));
GPIOE->OSPEEDR &= (~(0x1 << 21));
//PUPDR (21:20) 00
GPIOE->PUPDR &= (~(0x1 << 20));
GPIOE->PUPDR &= (~(0x1 << 21));
//对LED2引脚初始化
//MODER (21:20) 01
GPIOF->MODER &= (~(0x1 << 21));
GPIOF->MODER |= (0x1 << 20);
//OTYPER (10) 0
GPIOF->OTYPER &= (~(0x1 << 10));
//OSPEEDR (21:20) 00
GPIOF->OSPEEDR &= (~(0x1 << 20));
GPIOF->OSPEEDR &= (~(0x1 << 21));
//PUPDR (21:20) 00
GPIOF->PUPDR &= (~(0x1 << 20));
GPIOF->PUPDR &= (~(0x1 << 21));
//对LED3引脚初始化
//MODER (17:16) 01
GPIOE->MODER &= (~(0x1 << 17));
GPIOE->MODER |= (0x1 << 16);
//OTYPER (8) 0
GPIOE->OTYPER &= (~(0x1 << 8));
//OSPEEDR (17:16) 00
GPIOE->OSPEEDR &= (~(0x1 << 16));
GPIOE->OSPEEDR &= (~(0x1 << 17));
//PUPDR (17:16) 00
GPIOE->PUPDR &= (~(0x1 << 16));
GPIOE->PUPDR &= (~(0x1 << 17));
//EXTI章节初始化
// 外部中断选择寄存器
//KEY1 PF9
EXTI->EXTICR3 &= (~(0XFF << 8));
EXTI->EXTICR3 |= (0X05 << 8);
//KEY2 PF7
EXTI->EXTICR2 &= (~(0XFF << 24));
EXTI->EXTICR2 |= (0X05 << 24);
//KEY3 PF8
EXTI->EXTICR3 &= (~(0XFF << 0));
EXTI->EXTICR3 |= (0X05 << 0);
//下降沿选择触发寄存器
//KEY1 PF9
EXTI->FTSR1 |= (0X1 << 9);
//KEY2 PF7
EXTI->FTSR1 |= (0X1 << 7);
//KEY3 PF8
EXTI->FTSR1 |= (0X1 << 8);
//设置中断不屏蔽
//KEY1 PF9
EXTI->C1IMR1 |= (0X1 << 9);
//KEY2 PF7
EXTI->C1IMR1 |= (0X1 << 7);
//KEY3 PF8
EXTI->C1IMR1 |= (0X1 << 8);
}
//GIC章节初始化
void hal_gic_key1_init()
{
//GICD章节初始化
// 中断设置使能
//KEY1中断号99
GICD->ISENABLER[3] |= (0X1 << 3);
//KEY2中断号97
GICD->ISENABLER[3] |= (0X1 << 1);
//KEY3中断号98
GICD->ISENABLER[3] |= (0X1 << 2);
//中断优先级设置
//KEY1
GICD->IPRIORITYR[24] &= (~(0X1F << 27));
GICD->IPRIORITYR[24] |= (0X1 << 27);
//KEY2
GICD->IPRIORITYR[24] &= (~(0X1F << 11));
GICD->IPRIORITYR[24] |= (0X2 << 11);
//KEY3
GICD->IPRIORITYR[24] &= (~(0X1F << 19));
GICD->IPRIORITYR[24] |= (0X3 << 19);
//中断目标分配寄存器设置
//KEY1
GICD->ITARGETSR[24] &= (~(0X3 << 24));
GICD->ITARGETSR[24] |= (0X1 << 24);
//KEY2
GICD->ITARGETSR[24] &= (~(0X3 << 8));
GICD->ITARGETSR[24] |= (0X1 << 8);
//KEY3
GICD->ITARGETSR[24] &= (~(0X3 << 16));
GICD->ITARGETSR[24] |= (0X1 << 16);
//使能对应组中断
GICD->CTRL |= (0X1 << 0);
//GICC章节初始化
//设置中断优先级
GICC->PMR &= (~(0X1F << 3));
GICC->PMR |= (0X4 << 4);
//设置GICC层组0中断使能
GICC->CTRL |= (0X1 << 0);
}
void led1_on()
{
GPIOE->ODR |= (0x1 << 10);
}
void led1_off()
{
GPIOE->ODR &= (~(0x1 << 10));
}
void led2_on()
{
GPIOF->ODR |= (0x1 << 10);
}
void led2_off()
{
GPIOF->ODR &= (~(0x1 << 10));
}
void led3_on()
{
GPIOE->ODR |= (0x1 << 8);
}
void led3_off()
{
GPIOE->ODR &= (~(0x1 << 8));
}
do_srq.c
#include "key.h"
extern void printf(const char *fmt, ...);
extern void delay_ms(int ms);
extern void led1_on();
extern void led1_off();
extern void led2_on();
extern void led2_off();
extern void led3_on();
extern void led3_off();
unsigned int i = 0;
void do_irq(void)
{
unsigned int num;
num = GICC->IAR & 0X3FF;
switch (num)
{
//KEY2
case 97:
printf("KEY2 *************\n");
unsigned int num3;
num3 = GPIOF->ODR & (0X1 << 10);
if (num3 == 0)
{
led2_on();
}
else
{
led2_off();
}
//写1清除中断挂起标志位 EXTI_FPR1[7] = 1
EXTI->FPR1 |= (0x1 << 7);
//清除GICD层挂起标志位 GICD_ISENABLER3[1] = 1
GICD->ISENABLER[3] |= (0x1 << 1);
break;
//KEY3
case 98:
printf("KEY3 *************\n");
unsigned int num2;
num2 = GPIOE->ODR & (0X1 << 8);
if (num2 == 0)
{
led3_on();
}
else
{
led3_off();
}
//写1清除中断挂起标志位 EXTI_FPR1[8] = 1
EXTI->FPR1 |= (0x1 << 8);
//清除GICD层挂起标志位 GICD_ISENABLER3[1] = 1
GICD->ISENABLER[3] |= (0x1 << 2);
break;
//KEY1
case 99:
printf("KEY1 *************\n");
unsigned int num1;
num1 = GPIOE->ODR & (0X1 << 10);
if (num1 == 0)
{
//led1_on();
GPIOE->ODR |= (0x1 << 10);
}
else
{
//led1_off();
GPIOE->ODR &= (~(0x1 << 10));
}
//写1清除中断挂起标志位 EXTI_FPR1[9] = 1
EXTI->FPR1 |= (0x1 << 9);
//清除GICD层挂起标志位 GICD_ISENABLER3[3] = 1
GICD->ISENABLER[3] |= (0x1 << 3);
break;
}
GICC->EOIR = num;
}
key.h
#ifndef __KEY_H__
#define __KEY_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"
#include "stm32mp1xx_gpio.h"
//KEY1--->PF9 KEY2--->PF7 KEY3--->PF8
//RCC/GPIO/EXTI章节初始化
void hal_exit_key1_init();
void hal_gic_key1_init();
#endif