按键中断封装

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<<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---->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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值