Press the ARM_key1 button to achieve ① print key1press ② invert the state of light 1

inclde/key.h

#ifndef __KEY_H__
#define __KEY_H__

#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"

#define PF9 (unsigned int) 0x05
#define PF7 (unsigned int) 0x05
#define PF8 (unsigned int) 0x05


//对RCC/GPIO/EXTI章节的初始化
void hal_key1_exit_init();
void hal_key2_exit_init();
void hal_key3_exit_init();



//对GIC的初始化
void hal_key1_gic_init();
void hal_key2_gic_init();
void hal_key3_gic_init();


//EXTI章节初始化
//参数:EXTI编号,GPIOF编号,中断触发方式:1上升沿0下降沿 
void hal_exit_init(int E,int F,int X);



//GIC章节初始化
//参数:中断号,中断优先级
void hal_gic_init(int L,int S);



//引脚封装
#define GPIO_PIN_0 0
#define GPIO_PIN_1 1
#define GPIO_PIN_2 2
#define GPIO_PIN_3 3
#define GPIO_PIN_4 4
#define GPIO_PIN_5 5
#define GPIO_PIN_6 6
#define GPIO_PIN_7 7
#define GPIO_PIN_8 8
#define GPIO_PIN_9 9
#define GPIO_PIN_10 10
#define GPIO_PIN_11 11
#define GPIO_PIN_12 12
#define GPIO_PIN_13 13
#define GPIO_PIN_14 14
#define GPIO_PIN_15 15
 
 
 
 
//模式寄存器 0 1 2 3
typedef enum
{
	INPUT,
	OUTPUT,
	ALT,
	ANALOG,
 
}gpio_moder_t;
 
//输出类型寄存器
typedef enum
{
	PP, 	//推挽
	OD, 	//开漏
}gpio_otyper_t;
 
//输出速度寄存器
typedef enum
{
	LOW,
	MED,
	HIGH,
	VERY_HIGH,
}gpio_ospeedr_t;
 
//是否需要上下拉电阻寄存器封装
typedef enum
{
	NO_PUPDR, 	//禁止 0
	PU, 		//上拉 1
	PD, 		//下拉 2
 
}gpio_pupdr_t;
 
//输出高低电平寄存器封装
typedef enum
{
	GPIO_RESET_T, 	//输出低电平 0
	GPIO_SET_T, 	//输出高电平 1
}gpio_odr_t;
 
//寄存器初始化封装
typedef struct
{
	gpio_moder_t moder; 	//模式
	gpio_otyper_t otyper; 	//输出类型
	gpio_ospeedr_t ospeedr; //输出速率
	gpio_pupdr_t pupdr; 	//是否需要上下拉电阻
 
}gpio_init_t;
 
 
 
 
 
//结构体封装
typedef struct{
	char* cmd_arr;    //命令符字符串 
	gpio_t * gpio;  //gpio组号
	unsigned int pin; //对应的引脚编号
	gpio_odr_t status; //LED灯状态
	void (*gpio_write_p)(gpio_t * gpio,unsigned int pin, gpio_odr_t status);
}cmd_t;   

//灯的初始化GPIO初始化
void my_Initi_Led(gpio_t* gpiox,unsigned int pin,gpio_init_t* init);
//灯的设置高低电平
void hal_gpio_write(gpio_t* gpiox,unsigned int pin);

#endif

src/key.c

#include "key.h"


//EXTI章节初始化
void hal_exit_init(int E,int F,int X)
{
	//RCC
	RCC->MP_AHB4ENSETR |= (0x1 << 5);
	//GPIO设置输入模式
	GPIOF->MODER &= (~(0x3 << E*2));
	//1.外部中断选择寄存器,选择与哪个EXTI(16)链接
	int num1 = (E/4)+1;
	int num2 = (E%4)*8;
	switch(num1)
	{
		case 1:
			EXTI->EXTICR1 &= (~(0xff << num2));
			EXTI->EXTICR1 |= (F << num2);
			break;
		case 2:
			EXTI->EXTICR2 &= (~(0xff << num2));
			EXTI->EXTICR2 |= (F << num2);
			break;
		case 3:
			EXTI->EXTICR3 &= (~(0xff << num2));
			EXTI->EXTICR3 |= (F << num2);
			break;
		case 4:
			EXTI->EXTICR4 &= (~(0xff << num2));
			EXTI->EXTICR4 |= (F << num2);
			break;
	}
	//2.设置中断下降沿触发方式
	if(X == 0)
	{
		EXTI->FTSR1 |= (0x1 << E);
	}
	else
	{
		EXTI->FTSR1 |= (0x1 << E);	
	}
	//3.中断屏蔽选择寄存器
	EXTI->C1IMR1 |= (0b01 << E);
}



//GIC章节初始化
//参数:中断号,中断优先级
void hal_gic_init(int L,int S)
{
	//GICD的初始化
	//1.使能GICD层控制器
	GICD->CTRL |= 0x1;
	//2.设置GICD层的中断使能
	GICD->ISENABLER[L/32] |= (0x1 << (L%32));
	//3.设置GICD层中断优先级
	GICD->IPRIORITYR[L/4] |= ((S-1) << ((L%32)*8+3));
	//4.设置GICD层中断目标分配寄存器
	GICD->ITARGETSR[L/4] |= (0x1 << (L%4)*8);

	//GICC章节初始化
	//1.使能GICC层控制器
	GICC->CTRL |= 0x1;
	//2.设置GICC层中断优先级
	GICC->PMR |= (S << 3);
}



//灯的设置高低电平
void hal_gpio_write(gpio_t* gpiox,unsigned int pin)
{
			gpiox->ODR ^= (0x1 << pin);
}


//GPIO初始化相关操作
void my_Initi_Led(gpio_t* gpiox,unsigned int pin,gpio_init_t* init)
{
	//模式
	gpiox->MODER &= (~(0x3 << (2*pin)));
	gpiox->MODER |= (init->moder << (2*pin));
	//类型
	gpiox->OTYPER &= (~(0x1 << pin));
	gpiox->OTYPER |= (init->otyper << pin);
	//速度
	gpiox->OSPEEDR &= (~(0x3 << (2*pin)));
	gpiox->OSPEEDR |= (init->ospeedr << (2*pin));
	//上下拉电阻
	gpiox->PUPDR &= (~(0x3 << (2*pin)));
	gpiox->PUPDR |= (init->pupdr << (2*pin));
}

 main.c

#include "key.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++);
}
//
void init_Led()
{
	//通过RCC章节 将GPIOE GPIOF 组控制器使能
	RCC->MP_AHB4ENSETR |= (0x3 << 4);
	//结构体初始化
	gpio_init_t init = {OUTPUT,PP,LOW,NO_PUPDR};
	//调用函数初始化
	my_Initi_Led(GPIOE,GPIO_PIN_10, &init);
	my_Initi_Led(GPIOF,GPIO_PIN_10, &init);
	my_Initi_Led(GPIOE,GPIO_PIN_8, &init);
}

int main()
{
	hal_exit_init(9,PF9,0);
	hal_exit_init(7,PF7,0);
	hal_exit_init(8,PF8,0);

	hal_gic_init(99,9);
	hal_gic_init(97,7);
	hal_gic_init(98,8);

	
	init_Led();


	while(1)
	{
	}
	return 0;
}

 src/do_irq.c

#include "key.h"
extern void printf(const char *fmt, ...);
//key1----->PF9----->EXTI9---->EXTI_FPR1[9]
//key2----->PF7----->EXTI7---->EXTI_FPR1[7]
//key3----->PF8----->EXTI8---->EXTI_FPR1[8]
void do_irq(void) 
{
	unsigned int num;
	num = GICC->IAR & 0x3ff;
	switch (num)
	{
	case 99:
		printf("key1 press#####\n");
		hal_gpio_write(GPIOE,10);
		//1.消除EXTI层中断挂起标志位
		EXTI->FPR1 |= (0x1 << 9);
		//2.消除GICD层的中断挂起标志位
		GICD->ICPENDR[3] |= (0x1 << 3);
		break;
	case 97:
		printf("key2 press#####\n");
		hal_gpio_write(GPIOF,10);
		//1.消除EXTI层中断挂起标志位
		EXTI->FPR1 |= (0x1 << 7);
		//2.消除GICD层的中断挂起标志位
		GICD->ICPENDR[3] |= (0x1);
		break;
	case 98:
		printf("key3 press#####\n");
		hal_gpio_write(GPIOE,8);
		//1.消除EXTI层中断挂起标志位
		EXTI->FPR1 |= (0x1 << 8);
		//2.消除GICD层的中断挂起标志位
		GICD->ICPENDR[3] |= (0x1 << 2);

		break;
	}
	//3.清除获取到的中断号
	GICC->EOIR |= num;
}

 

Guess you like

Origin blog.csdn.net/lsw2604190117/article/details/131608652