ARM 中断实验

ARM 中断实验_第1张图片

key.h

#ifndef _H_
#define _H_
//KEY1-->PF9
#include "stm32mp1xx_exti.h" 
#include "stm32mp1xx_gic.h"  
#include "stm32mp1xx_rcc.h" 
#include "stm32mp1xx_gpio.h"

void key_rcc_gpio_init();

void led_gpio_init(gpio_t *gpiox,unsigned int pin);

void hal_exit_pf9_init(unsigned int pin);

void hal_gic_pf9_init(unsigned int id);

#endif

key.c

#include "key.h"
void key_rcc_gpio_init()
{
	//RCC章节初始化 GPIOF组控制器使能[5]=1
	RCC->MP_AHB4ENSETR |=(0x1<<5);

	//GPIO章节初始化 PF9[19,18],8[15,14],7[17,16]输入模式=00
	GPIOF->MODER &= (~(0x3 << 18));
	GPIOF->MODER &= (~(0x3 << 14));
	GPIOF->MODER &= (~(0x3 << 16));

}

void led_gpio_init(gpio_t *gpiox,unsigned int pin)
{
	//GPIO的led章节初始化
	//MODER设置为输出模式01
	gpiox->MODER &= (~(0x3 << 2*pin));
	gpiox->MODER |= (0X1 << 2*pin);

	//OTYPER设置为推挽输出类型0 
	gpiox->OTYPER &=(~(0X1 << pin));

	//OSPEEDR设置为输出低速 00
	gpiox->OSPEEDR &= (~(0X3 << 2*pin));

	//PUPDR设置为禁止上下拉电阻 00
	gpiox->PUPDR &= (~(0x3 << 2*pin));

	//ODR设置为开关
	//gpiox->ODR &= (~(0X1 << pin));熄灭
	//gpiox->ODR |= (0x1 << pin);点亮
	
}

//RCC/GPIO/EXTI章节初始化
void hal_exit_pf9_init(unsigned int pin)
{	
	//EXTI章节初始化	
	//EXTICR3 外部中断选择寄存器 按键与引脚连接 [15:8][31:24][7:0]=0x05
	if((pin/4)+1==3)
	{
	EXTI->EXTICR3 &= (~(0xff << (pin%4)*8));
	EXTI->EXTICR3 |= (0x5 << (pin%4)*8);
	}
	else if((pin/4)+1==2)
	{
	EXTI->EXTICR2 &= (~(0xff <<(pin%4)*8));
	EXTI->EXTICR2 |= (0x5 <<(pin%4)*8);
	}

	//FTSR1 [9:7]=0x7 设置触发为下降沿
	EXTI->FTSR1 |= (0x1 << pin);

	//IMR1 [9:7]=0X7 中断屏蔽器
	EXTI->C1IMR1 |= (0X1 << pin);
	
}
//GIC章节初始化
void hal_gic_pf9_init(unsigned int id)
{

	//GPCD章节初始化
	//CTLR [0]=0X0
	GICD->CTRL |= (0x1 <<0);

	//ISENABLER3 [3:1]=0X1
	GICD->ISENABLER[3] |= (0x1 << (id%32));

	//IPRIORITYR4 [31:27][15:11][23:19]=0B00000
	GICD->IPRIORITYR[24] &= (~(0x1f << (id%4*8+3)));
	 
	//ITARGETSR4 [25:24][9:8][17:16]=0B01
	GICD->ITARGETSR[24] &= (~(0X3 << (id%4*8)));
	GICD->ITARGETSR[24] |= (0X1 << (id%4*8));


	//GPCC章节初始化
	//CTLR[0]=1
	GICC->CTRL |= (0X1);

	//PMR[7:3]=0B11111
	GICC->PMR |= (0X1F <<3);
	
}

do_irq.c

#include "key.h"
extern void printf(const char *fmt, ...);
unsigned int i = 0;
//中断处理函数
void do_irq(void) 
{
	//1.获取中断号
	i=GICC->IAR &(0x3ff);
	//2.判断中断号,并且打印一句话
	switch(i)
	{
	case 99:
		printf("I am key1\n");
	//3.清除EXTI层中断挂起标志位
	EXTI->FPR1 |= (0X1 <<9);
	//4.清除GICD层中断挂起标志位 ICPENDR[3]第三位
	GICD->ICPENDR[3] |= (0X1 <<3);	
	
	GPIOE->ODR ^=(0X1<<10);
	break;
	case 98:
		printf("I am key3\n");
	//3.清除EXTI层中断挂起标志位
	EXTI->FPR1 |= (0X1 <<8);
	//4.清除GICD层中断挂起标志位 ICPENDR[3]第三位
	GICD->ICPENDR[3] |= (0X1 <<2);
	GPIOE->ODR ^=(0X1<<8);
	break;
	case 97:
		printf("I am key2\n");
	//3.清除EXTI层中断挂起标志位
	EXTI->FPR1 |= (0X1 <<7);
	//4.清除GICD层中断挂起标志位 ICPENDR[3]第三位
	GICD->ICPENDR[3] |= (0X1 <<1);
	GPIOF->ODR ^=(0X1<<10);
	break;
	}
	//5.清除获取到中断号
	GICC->EOIR = i;

}

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


int main()
{
	key_rcc_gpio_init();	
	led_gpio_init(GPIOE,10);
	led_gpio_init(GPIOF,10);
	led_gpio_init(GPIOE,8);

	hal_exit_pf9_init(7);
	hal_exit_pf9_init(8);
	hal_exit_pf9_init(9);

	hal_gic_pf9_init(97);
	hal_gic_pf9_init(98);
	hal_gic_pf9_init(99);


	while(1);
	return 0;
}

 

你可能感兴趣的:(linux,运维,服务器)