按键中断实验

该代码示例展示了在STM32MP1xx微控制器上如何使用HAL库初始化按键中断,包括GPIO、EXTI和GIC配置。当按键被按下时,会触发相应的中断服务函数do_irq(),在该函数中根据中断源点亮或熄灭对应的LED灯,并清除中断标志位。
摘要由CSDN通过智能技术生成

按键中断实验

##现象展示
在这里插入图片描述

main.c

#include "key.h"
int main()
{
	extern void printf(const char* fmt, ...);
	
	hal_exit_key1_init();
	hal_gic_key1_init();

	while(1)
	{
		//当按键按下之后,触发irq异常源
		//执行中断处理函数
		//do_irq();
	
	}

	return 0;
}

key.c

#include "key.h"

void delay_ms(int ms)
{
	int i, j;
	for (i = 0; i < ms; i++)
		for (j = 0; j < 1800; j++);
}

//KEY1--->PF9
//RCC/GPIO/EXTI章节初始化
void hal_exit_key1_init()
{
	//RCC章节初始化
	//1.设置GPIOF组使能
	RCC->MP_AHB4ENSETR |= (0X1 << 5);
	//设置灯引脚使能
	RCC->MP_AHB4ENSETR |= (0X1 << 4);

	//GPIO章节初始化
	//1.设置PF9引脚为输入模式
	GPIOF->MODER &= (~(0X3 << 18));		//KEY1		PF9
	GPIOF->MODER &= (~(0X3 << 14));		//KEY2		PF7
	GPIOF->MODER &= (~(0X3 << 16));		//KEY3		PF8
	//对LED1引脚初始化
	//MODER (21:20) 01
	GPIOE->MODER &= (~(0x1 << 21));
	GPIOE->MODER |= (0x1 << 20);
	//OTYPER  (10) 0
	GPIOE->OTYPER &= (~(0x1 << 10));
	//OSPEEDR (21:20) 00
	GPIOE->OSPEEDR &= (~(0x1 << 20));
	GPIOE->OSPEEDR &= (~(0x1 << 21));
	//PUPDR  (21:20) 00
	GPIOE->PUPDR &= (~(0x1 << 20));
	GPIOE->PUPDR &= (~(0x1 << 21));
	//对LED2引脚初始化
	//MODER (21:20) 01
	GPIOF->MODER &= (~(0x1 << 21));
	GPIOF->MODER |= (0x1 << 20);
	//OTYPER  (10) 0
	GPIOF->OTYPER &= (~(0x1 << 10));
	//OSPEEDR (21:20) 00
	GPIOF->OSPEEDR &= (~(0x1 << 20));
	GPIOF->OSPEEDR &= (~(0x1 << 21));
	//PUPDR  (21:20) 00
	GPIOF->PUPDR &= (~(0x1 << 20));
	GPIOF->PUPDR &= (~(0x1 << 21));
	//对LED3引脚初始化
	//MODER (17:16) 01
	GPIOE->MODER &= (~(0x1 << 17));
	GPIOE->MODER |= (0x1 << 16);
	//OTYPER  (8) 0
	GPIOE->OTYPER &= (~(0x1 << 8));
	//OSPEEDR (17:16) 00
	GPIOE->OSPEEDR &= (~(0x1 << 16));
	GPIOE->OSPEEDR &= (~(0x1 << 17));
	//PUPDR  (17:16) 00
	GPIOE->PUPDR &= (~(0x1 << 16));
	GPIOE->PUPDR &= (~(0x1 << 17));


	//EXTI章节初始化
	// 外部中断选择寄存器
	//KEY1		PF9
	EXTI->EXTICR3 &= (~(0XFF << 8));
	EXTI->EXTICR3 |= (0X05 << 8);

	//KEY2		PF7
	EXTI->EXTICR2 &= (~(0XFF << 24));
	EXTI->EXTICR2 |= (0X05 << 24);

	//KEY3		PF8
	EXTI->EXTICR3 &= (~(0XFF << 0));
	EXTI->EXTICR3 |= (0X05 << 0);

	//下降沿选择触发寄存器
	//KEY1		PF9
	EXTI->FTSR1 |= (0X1 << 9);

	//KEY2		PF7
	EXTI->FTSR1 |= (0X1 << 7);

	//KEY3		PF8
	EXTI->FTSR1 |= (0X1 << 8);

	//设置中断不屏蔽
	//KEY1		PF9
	EXTI->C1IMR1 |= (0X1 << 9);

	//KEY2		PF7
	EXTI->C1IMR1 |= (0X1 << 7);

	//KEY3		PF8
	EXTI->C1IMR1 |= (0X1 << 8);

}

//GIC章节初始化
void hal_gic_key1_init()
{
	//GICD章节初始化
	// 中断设置使能
	//KEY1中断号99
	GICD->ISENABLER[3] |= (0X1 << 3);
	//KEY2中断号97
	GICD->ISENABLER[3] |= (0X1 << 1);
	//KEY3中断号98
	GICD->ISENABLER[3] |= (0X1 << 2);

	//中断优先级设置
	//KEY1
	GICD->IPRIORITYR[24] &= (~(0X1F << 27));
	GICD->IPRIORITYR[24] |= (0X1 << 27);

	//KEY2
	GICD->IPRIORITYR[24] &= (~(0X1F << 11));
	GICD->IPRIORITYR[24] |= (0X2 << 11);

	//KEY3
	GICD->IPRIORITYR[24] &= (~(0X1F << 19));
	GICD->IPRIORITYR[24] |= (0X3 << 19);

	//中断目标分配寄存器设置
	//KEY1
	GICD->ITARGETSR[24] &= (~(0X3 << 24));
	GICD->ITARGETSR[24] |= (0X1 << 24);

	//KEY2
	GICD->ITARGETSR[24] &= (~(0X3 << 8));
	GICD->ITARGETSR[24] |= (0X1 << 8);

	//KEY3
	GICD->ITARGETSR[24] &= (~(0X3 << 16));
	GICD->ITARGETSR[24] |= (0X1 << 16);

	//使能对应组中断
	GICD->CTRL |= (0X1 << 0);
	
	
	//GICC章节初始化
	//设置中断优先级
	GICC->PMR &= (~(0X1F << 3));
	GICC->PMR |= (0X4 << 4);

	//设置GICC层组0中断使能
	GICC->CTRL |= (0X1 << 0);

}

void led1_on()
{
	GPIOE->ODR |= (0x1 << 10);
}

void led1_off()
{
	GPIOE->ODR &= (~(0x1 << 10));
}

void led2_on()
{
	GPIOF->ODR |= (0x1 << 10);
}

void led2_off()
{
	GPIOF->ODR &= (~(0x1 << 10));
}
void led3_on()
{
	GPIOE->ODR |= (0x1 << 8);
}

void led3_off()
{
	GPIOE->ODR &= (~(0x1 << 8));
}

do_srq.c

#include "key.h"
extern void printf(const char *fmt, ...);
extern void delay_ms(int ms);
extern void led1_on();
extern void led1_off();
extern void led2_on();
extern void led2_off();
extern void led3_on();
extern void led3_off();
unsigned int i = 0;
void do_irq(void) 
{
	unsigned int num;
	num = GICC->IAR & 0X3FF;

	switch (num)
	{
		//KEY2
	case 97:
		printf("KEY2 *************\n");
		unsigned int num3;
		num3 = GPIOF->ODR & (0X1 << 10);
		if (num3 == 0)
		{
			led2_on();

		}
		else
		{
			led2_off();

		}

		//写1清除中断挂起标志位 EXTI_FPR1[7] = 1
		EXTI->FPR1 |= (0x1 << 7);
		//清除GICD层挂起标志位 GICD_ISENABLER3[1] = 1
		GICD->ISENABLER[3] |= (0x1 << 1);

		break;

		//KEY3
	case 98:
		printf("KEY3 *************\n");
		unsigned int num2;
		num2 = GPIOE->ODR & (0X1 << 8);
		if (num2 == 0)
		{
			led3_on();
			
		}
		else
		{
			led3_off();
		
		}


		//写1清除中断挂起标志位 EXTI_FPR1[8] = 1
		EXTI->FPR1 |= (0x1 << 8);
		//清除GICD层挂起标志位 GICD_ISENABLER3[1] = 1
		GICD->ISENABLER[3] |= (0x1 << 2);
		
		break;

		//KEY1
	case 99:
		printf("KEY1 *************\n");
		unsigned int num1;
		num1 = GPIOE->ODR & (0X1 << 10);
		if (num1 == 0)
		{
			//led1_on();
			GPIOE->ODR |= (0x1 << 10);
		}
		else
		{
			//led1_off();
			GPIOE->ODR &= (~(0x1 << 10));
		}
		//写1清除中断挂起标志位 EXTI_FPR1[9] = 1
		EXTI->FPR1 |= (0x1 << 9);
		//清除GICD层挂起标志位 GICD_ISENABLER3[3] = 1
		GICD->ISENABLER[3] |= (0x1 << 3);
		
		break;
	}
		GICC->EOIR = num;
}

key.h

#ifndef __KEY_H__
#define __KEY_H__

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

//KEY1--->PF9		KEY2--->PF7		KEY3--->PF8
//RCC/GPIO/EXTI章节初始化
void hal_exit_key1_init();
void hal_gic_key1_init();


#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值