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 9int main(){all_led_init();key_gpio_rcc_init();//KEY1hal_exti_key_init(EXTI9_INPUT_EVENT,GPIOGROUP,Falling);hal_gic_key_init(KEY1_ID,IPR_EXTI9);//KEY2hal_exti_key_init(EXTI7_INPUT_EVENT,GPIOGROUP,Falling);hal_gic_key_init(KEY2_ID,IPR_EXTI7);//KEY3hal_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]=1RCC->MP_AHB4ENSETR |=(0x1<<5);//设置PF9为输入模式 MODER[19:18]=00GPIOF->MODER&=(~(0x3<<18));//设置PF7为输入模式 MODER[15:14]=00GPIOF->MODER&=(~(0x3<<14));//设置PF8为输入模式 MODER[17:16]=00GPIOF->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<<input_event);}else//触发方式为上升沿触发{EXTI->RTSR1 |=(0x1<<input_event);}//设置中断不屏蔽EXTI->C1IMR1 |=(0x1<<input_event);}//GIC章节初始化
//中断id
//优先级
void hal_gic_key_init(unsigned int id,unsigned int ipr)
{//设置GICD层中断使能寄存器GICD->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---->PF10GPIOF->ODR ^= (0x1 << 10);printf("key2 interrupt id = %d\n",num);EXTI->FPR1 |= (0x1 << 7);GICD->ICPENDR[3] |= (0x1 << 1);break;case 98:// KEY3 ---->LED3--->PE8GPIOE->ODR ^= (0x1 << 8);printf("key3interrupt id = %d\n",num);EXTI->FPR1 |= (0x1 << 8);GICD->ICPENDR[3] |= (0x1 << 2);break;case 99://KEY1 ---->LED1---->PE10GPIOE->ODR ^= (0x1 << 10);printf("key1 interrupt id = %d\n",num);delay_ms(500);EXTI->FPR1 |= (0x1 << 9);GICD->ICPENDR[3] |= (0x1 << 3);break;}//5.清除中断号EOIRGICC->EOIR = num;
}