EXTI章节初始化
void hal_exit_init(EXTI编号,GPIOF组编号,中断触发方式)
调用:hal_exit_init(EXTI9,0x05,下降沿触发)
调用: hal_exit_init(EXTI7,0x05,下降沿触发)
调用: hal_exit_init(EXTI8,0x05,下降沿触发)
GIC章节初始化
void hal_gic_init(中断号,中断优先级)
调用: hal_gic_init(99,9)
调用: hal_gic_init(97,7)
调用: hal_gic_init(98,8)
实现key1/ key2/key3三个按键触发
1)打印一句话 2)灯的状态取反
key1按下之后,打印key1 press ,LED1灯状态取反
key2按下之后,打印key2 press,LED2灯状态取反
key3按下之后,打印key3 press,LED3灯状态取反
//头文件
#ifndef __KEY_H__
#define __KEY_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_uart.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"
#define rising 1
#define falling 0
#define EXTI9 9
#define EXTI8 8
#define EXTI7 7
#define GPIO_PIN_10 10
#define GPIO_PIN_8 8
#define GPIO_RESET 0
#define GPIO_SET 1
//对RCC GPIO EXTI进行初始化
void hal_key_exti_init(int extix,int extix_gpiox,int status);
//对GIC进行初始化
void hal_key_gic_init(int num, int priority);
//LED初始化
void led_init(gpio_t * gpio,unsigned int pin,int gpio_status);
#endif
//功能函数
#include "key.h"
extern void printf(const char *fmt, ...);
//exti编号,exti对应组编号,触发方式
void hal_key_exti_init(int extix,int extix_gpiox,int status)
{
/*******RCC章节初始化**********/
//GPIOF组使能
RCC->MP_AHB4ENSETR |= (0x1 << 5);
/*******GPIO章节初始化*********/
//设置模式为输入模式
// key1(PF9): GPIOF_MODER[19:18] = 00
// key2(PF7): GPIOF_MODER[15:14] = 00
// key3(PF8): GPIOF_MODER[17:16] = 00
GPIOF->MODER &= (~(0x3f << 14));
/*******EXTI章节初始化*********/
int quotient = extix / 4; //商
int remainder = extix % 4; //余数
//1.外部中断选择寄存器
if (quotient == 0) //EXTICR1
{
EXTI->EXTICR1 |= (extix_gpiox << remainder*8); //余数 * 8:操作8位中的最低位
}
else if(quotient == 1) //EXTICR2
{
EXTI->EXTICR2 |= (extix_gpiox << remainder*8);
}
else if(quotient == 2) //EXTICR3
{
EXTI->EXTICR3 |= (extix_gpiox << remainder*8);
}
//2.EXTI触发选择寄存器
if(status == falling) //下降沿触发
{
EXTI->FTSR1 |= (0x1 << extix);
}
else if(status == rising)
{
EXTI->RTSR1 |= (0x1 <<extix);
}
//3.EXTI中断屏蔽寄存器
EXTI->C1IMR1 |= (0x1 << extix);
}
void hal_key_gic_init(int num, int priority)
{
/********GICD初始化**********/
//1.使能GICD层组0中断:GICD_CTLR[0] = 1
GICD->CTRL |= (0x1 << 0);
//2.中断设置使能寄存器
int quo = num / 32; //商
int rem = num % 32; //余数
// 商:操作哪个寄存器
// 余数:操作寄存器的位数
GICD->ISENABLER[quo] |= (0x1 << rem);
//3.GICD层中断优先级寄存器
quo = num / 4;
rem = num % 4;
//商:操作哪个寄存器
//余数*8+3:操作寄存器的位数
GICD->IPRIORITYR[quo] |= (0x1 << (rem*8+3));
//4.GICD层中断目标分配寄存器
//商:操作哪个寄存器
//余数*8:操作寄存器的位数
GICD->ITARGETSR[quo] |= (0b01 << rem*8);
/********GICC初始化**********/
//1.使能GICC层组0中断:GICC_CTLR[0] = 1
GICC->CTRL |= (0x1 << 0);
//2.GICC层中断优先级屏蔽寄存器
//GICC_PMR[7:3] = 中断优先级值
if(priority > 1)
{
GICC->PMR |= (priority << 3);
}
else
{
printf("优先级输入有误\n");
}
}
void led_init(gpio_t * gpio,unsigned int pin,int gpio_status)
{
//RCC初始化
RCC->MP_AHB4ENSETR |= (0x3 << 4); //将第4 5位置1
//设置模式01
gpio->MODER &= (~(0x3 << (2*pin)));
gpio->MODER |= (0x1 << (2*pin));
//设置输出类型 推挽 0
gpio->OTYPER &= ~(0x1 << pin);
//设置输出速度 00
gpio->OSPEEDR &= ~(0x3 << (2 * pin));
//设置禁止上下拉电阻 00
gpio->PUPDR &= ~(0x3 << (2 * pin));
//判断输入的值是否为低电平
if(gpio_status == GPIO_RESET)
{
gpio->ODR &= (~(0x1 << pin));
}
else
{
gpio->ODR |= (0x1 << pin);
}
}
//中断处理函数
#include "key.h"
extern void printf(const char *fmt, ...);
void do_irq(void)
{
unsigned int num;
//获取中断
num=GICC->IAR & (0x3ff);
//判断中断号
//99---->key1----->printf(key1)
//98---->key2
//97---->key3
//清除对应中断挂起的标志位
switch (num)
{
case 97:
printf("key2 press!! LED2状态取反\n");
//清除EXTI层中断挂起标志位
EXTI->FPR1 |= (0x1 << 7);
//清除GICD层中断挂起标志位
GICD->ICPENDR[3] |= (0x1 <<1);
//LED2状态取反
GPIOF->ODR ^= (0x1 << 10);
break;
case 98:
printf("key3 press!! LED3状态取反\n");
//清除EXTI层中断挂起标志位
EXTI->FPR1 |= (0x1 << 8);
//清除GICD层中断挂起标志位
GICD->ICPENDR[3] |= (0x1 <<2);
//LED3状态取反
GPIOE->ODR ^= (0x1 << 8);
break;
case 99:
printf("key1 press!! LED1状态取反\n");
//清除EXTI层中断挂起标志位
EXTI->FPR1 |= (0x1 << 9);
//清除GICD层中断挂起标志位
GICD->ICPENDR[3] |= (0x1 <<3);
//LED1状态取反
GPIOE->ODR ^= (0x1 << 10);
break;
}
//清除获取到的中断号
GICC->EOIR = num;
}
//主函数
#include "key.h"
extern void printf(const char *fmt, ...);
int main()
{
hal_key_exti_init(EXTI9,0x05,falling);
hal_key_exti_init(EXTI8,0x05,falling);
hal_key_exti_init(EXTI7,0x05,falling);
hal_key_gic_init(99,2);
hal_key_gic_init(98,3);
hal_key_gic_init(97,4);
led_init(GPIOE,GPIO_PIN_10,GPIO_RESET);
led_init(GPIOF,GPIO_PIN_10,GPIO_RESET);
led_init(GPIOE,GPIO_PIN_8,GPIO_RESET);
while(1)
{
}
return 0;
}
结果