RCC和GPIO初始化函数:
EXTI初始化函数:通用的函数,对KEY1/KEY2/KEY3进行使用
void hal_exti_init(事件编号,GPIOF组对应编号,触发方式)
GIC层初始化函数:通用的函数,对KEY1/KEY2/KEY3进行使用
void hal_GIC_init(中断id,优先级)
实验现象: 当按键1按下之后,
1)打印一句话,并且需要打印出中断号 2)
LED1灯的状态进行取反 当按键2按下之后,1)打印一句话,并且需要打印出中断号 2)LED2灯的状态进行取反
当按键3按下之后,1)打印一句话,并且需要打印出中断号 2)LED3灯的状态进行取反
main.c
#include "key.h"
#include "led.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++);
}
#define EXTI7_INPUT_EVENT 7
#define EXTI8_INPUT_EVENT 8
#define EXTI9_INPUT_EVENT 9
#define GPIOGROUP 0x05
#define KEY1_ID 99
#define KEY2_ID 97
#define KEY3_ID 98
#define IPR_EXTI7 7
#define IPR_EXTI8 8
#define IPR_EXTI9 9
int main()
{
all_led_init();
key_gpio_rcc_init();
//KEY1
hal_exti_key_init(EXTI9_INPUT_EVENT,GPIOGROUP,Falling);
hal_gic_key_init(KEY1_ID,IPR_EXTI9);
//KEY2
hal_exti_key_init(EXTI7_INPUT_EVENT,GPIOGROUP,Falling);
hal_gic_key_init(KEY2_ID,IPR_EXTI7);
//KEY3
hal_exti_key_init(EXTI8_INPUT_EVENT,GPIOGROUP,Falling);
hal_gic_key_init(KEY3_ID,IPR_EXTI8);
while(1)
{
}
return 0;
}
led.h:
#ifndef __LED_H__
#define __LED_H__
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
//定义寄存器组织结构体//定义GPIOE和GPIOF
void all_led_init();
#endif
key.h:
#ifndef __KEY_H__
#define __KEY_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"
typedef enum//枚举
{
Rising =0, //上升沿
Falling, //下降沿
}triger_t;
//GPIO章节和RCC章节初始化
void key_gpio_rcc_init();
//EXTI章节初始化
void hal_exti_key_init(unsigned int input_event,
unsigned int gpiogroup,triger_t trigger);
//GIC章节初始化
void hal_gic_key_init(unsigned int id,unsigned int ipr);
#endif
key.c
#include "key.h"
void key_gpio_rcc_init()
{
//KEY1->PF9
//KEY2->PF7
//KEY3->PF8
//设置GPIOF使能 MP_AHB4ENSETR[5]=1
RCC->MP_AHB4ENSETR |=(0x1<<5);
//设置PF9为输入模式 MODER[19:18]=00
GPIOF->MODER&=(~(0x3<<18));
//设置PF7为输入模式 MODER[15:14]=00
GPIOF->MODER&=(~(0x3<<14));
//设置PF8为输入模式 MODER[17:16]=00
GPIOF->MODER&=(~(0x3<<16));
}
//EXIT章节初始化
//input_event:事件编号
//gpiogroup:gpio对应组的编号
//trigger:触发方式
void hal_exti_key_init(unsigned int input_event,
unsigned int gpiogroup,triger_t trigger)
{
//设置GPI引脚和EXTI进行连接
switch (input_event/4)
{
case 1:
EXTI->EXTICR2 &=(~(0xff<<(input_event%4*8)));
EXTI->EXTICR2 |=(gpiogroup<<(input_event%4*8));
break;
case 2:
EXTI->EXTICR3 &=(~(0xff<<(input_event%4*8)));
EXTI->EXTICR3 |=(gpiogroup<<(input_event%4*8));
break;
case 3:
break;
}
//设置中断触发方式
if(trigger==Falling)//触发方式为下降沿触发
{
EXTI->FTSR1|=(0x1<RTSR1 |=(0x1<C1IMR1 |=(0x1<ISENABLER[id/32]&=(~(0x1<<(id%32)));
GICD->ISENABLER[id/32] |=(0x1<<(id%32));
//设置GICD层中断优先级寄存器
GICD->IPRIORITYR[id/4] &=(~(0x1f<<(id%4 *8 +3)));
GICD->IPRIORITYR[id/4] |=(ipr<<(id%4 *8 +3));
//设置GICD层中断目标分配寄存器
GICD->ITARGETSR[id/4] &=(~(0x3<<(id%4*8)));
GICD->ITARGETSR[id/4] |=(0x1<<(id%4*8));
//设置GICD层中断全局控制器
GICD->CTRL |=(0x1<<0);
//设置GICC层中断优先级寄存器
GICC->PMR |=(0x1f<<3);
//设置GICC层中断全局控制器
GICC->CTRL |= (0x1<<0);
}
do_irq.c:
#include "key.h"
#include "led.h"
extern void delay_ms(int ms);
extern void printf(const char *fmt, ...);
//按键按下之后,打印一句话
void do_irq(void)
{
unsigned int num;
//获取中断号
num=GICC->IAR &0x3ff;
//判断中断号
switch (num)
{
case 97:// KEY2 ---->LED2---->PF10
GPIOF->ODR ^= (0x1 << 10);
printf("key2 interrupt id = %d\n",num);
EXTI->FPR1 |= (0x1 << 7);
GICD->ICPENDR[3] |= (0x1 << 1);
break;
case 98:// KEY3 ---->LED3--->PE8
GPIOE->ODR ^= (0x1 << 8);
printf("key3interrupt id = %d\n",num);
EXTI->FPR1 |= (0x1 << 8);
GICD->ICPENDR[3] |= (0x1 << 2);
break;
case 99://KEY1 ---->LED1---->PE10
GPIOE->ODR ^= (0x1 << 10);
printf("key1 interrupt id = %d\n",num);
delay_ms(500);
EXTI->FPR1 |= (0x1 << 9);
GICD->ICPENDR[3] |= (0x1 << 3);
break;
}
//5.清除中断号EOIR
GICC->EOIR = num;
}