ARM day8 key1/2/3&led

key_led.h

#ifndef _KEY_H_
#define _KEY_H_

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

//EXTI编号
typedef enum
{
	EXTI0,
	EXTI1,
	EXTI2,
	EXTI3,
	EXTI4,
	EXTI5,
	EXTI6,
	EXTI7,
	EXTI8,
	EXTI9,
	EXTI10,
}EXTI_t;

//上升沿 下降沿
typedef enum
{
	Falling,
	Upping,
}Ftsr1_t;

//封装引脚编号
#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

//模式寄存器
typedef enum
{
	Input,//输入模式
	Output,//输出模式
	Alt,//复用功能模式
	Analog,//模拟模式
}gpio_moder_t;

//输出类型寄存器
typedef enum
{
	Push_pull,//推挽输出
	Open_drain//开漏输出
}gpio_otyper_t;

//输出速率寄存器
typedef enum
{
	Low_speed,//低速
	Medium_speed,//中速
	High_speed,//高速
	Very_high_speed//超高速
}gpio_ospeed_t;

//是否需要上下拉电阻寄存器
typedef enum
{
	No_up_down,//不用上下拉
	Pull_up,//上拉
	Oull_down,//下拉
	Reserved//保留
}gpio_pupdr_t;

//输出高低电平寄存器
typedef enum
{
	Off,//低电平
	On//高电平
}gpio_odr_t;

//封装初始化结构体
typedef struct
{
	gpio_moder_t moder;
	gpio_otyper_t otyper;
	gpio_ospeed_t ospeedr;
	gpio_pupdr_t pupdr;

}gpio_init_t;

/*函数功能:GPIO引脚初始化操作*/
void hal_gpio_init(volatile gpio_t* GPIOx,unsigned int pin,gpio_init_t *init);
/*操控灯亮灯灭*/
void hal_gpio_write(volatile gpio_t* GPIOx,unsigned int pin,gpio_odr_t status);

//初始化RCC
void rcc_init();
//EXIT初始化
void hal_exit_init(EXTI_t EXTIx,unsigned int Gpio_num,Ftsr1_t f_type);
//GIC初始化
void hal_gic_init(unsigned int Inte_num,unsigned int Inte_level);

#endif

key_led.c

#include "key_led.h"

//EXTI初始化
//第一个参数:EXTI号,第二个参数:GPIO组号,第三个参数:触发方式
void hal_exit_init(EXTI_t EXTIx,unsigned int Gpio_num,Ftsr1_t f_type)
{
	/*******RCC章节初始化*******/
	//使能GPIOF组控制器  RCC->MP_AHB4ENSETR[5]=1 
	RCC->MP_AHB4ENSETR |= (0X1<<5);

	/*******GPIO章节初始化******/
	//设置key1/2/3为输入模式 
	GPIOF->MODER &= (~(0x3<< (EXTIx*2) ));

	/*******EXTI章节初始化******/
	//1.设置key1/2/3与EXTI进行连接 
	unsigned int a=EXTIx/4;
	unsigned int b=EXTIx%4;

	if(a==2)
	{
		EXTI->EXTICR3 &= (~( 0xff<<(8*b) ));
		EXTI->EXTICR3 |= ( Gpio_num<<(8*b) );
	}
	else if(a==1)
	{
		EXTI->EXTICR2 &= (~( 0xff<<(8*b) ));
		EXTI->EXTICR2 |= ( Gpio_num<<(8*b) );
	}

	//2.设置key1/2/3为下降沿触发 
	if(f_type==Falling)
	{
		EXTI->FTSR1 |= (0x1<<EXTIx);	
	}

	//3.设置key1/2/3中断不屏蔽 
	EXTI->C1IMR1 |= (0x1<<EXTIx);
}

//GIC初始化
//第一个参数:中断号,第二个参数:中断级别
void hal_gic_init(unsigned int Inte_num,unsigned int Inte_level)
{	
	/*******GICD章节初始化******/
	//1.使能GICD层(cpu0) GICD_CTRL[0]=1
	GICD->CTRL |= (0X1<<0);

	//2.设置key1/2/3 GICD层中断使能(中断号) 
	unsigned int a=Inte_num/32;
	unsigned int b=Inte_num%32;

	GICD->ISENABLER[a] |= (0x1<<b);

	//3.设置GICD层中断优先级  值越低,级别越高
	unsigned int c=Inte_num/4;
	unsigned int d=Inte_num%4;
	GICD->IPRIORITYR[c] &= (~( Inte_level<<(d*8+3) )); 

	//4.设置中断目标分配寄存器 分配给cpu0,
	unsigned int e=Inte_num/4;
	unsigned int f=Inte_num%4;
	GICD->ITARGETSR[e] &= (~( 0x3<<(f*8) ));
	GICD->ITARGETSR[e] |= ( 0x1<<(f*8) );


	/*******GICC章节初始化******/
	//2.使能组0中断 GICC_CTRL[0]=1
	GICC->CTRL |= (0x1<<0);

	//1.设置GICC层中断优先级 GICC_PMR[7:3]=11111
	GICC->PMR &= (~(0x1f<<3));
	GICC->PMR |= (Inte_level<<3);

}

//RCC初始化
void rcc_init()
{
	//使能GPIOE组
	//使能GPIOF组
	RCC->MP_AHB4ENSETR |= (0X1<<4);
	RCC->MP_AHB4ENSETR |= (0X1<<5);
}

//函数功能:GPIO引脚初始化操作
//参数:第一个参数:GPIO组号; 第二个参数:引脚编号; 第三个参数:初始化内容
void hal_gpio_init(volatile gpio_t* GPIOx,unsigned int pin,gpio_init_t *init)
{
	//1.设置模式
	GPIOx->MODER &= ( ~ (0x3 << (pin*2)) );
	GPIOx->MODER |= ( (init->moder) << (pin*2) );
	//2.设置输出类型
	GPIOx->OTYPER &=( ~(0x1<<pin));
	GPIOx->OTYPER |= ( (init->otyper) << pin );
	//3.设置输出速率
	GPIOx->OSPEEDR &= ( ~ (0x3 << (pin*2)) );
	GPIOx->OSPEEDR |= ( (init->ospeedr) << (pin*2) );
	//4.设置输出是否需要上下拉电阻
	GPIOx->PUPDR &= ( ~ (0x3 << (pin*2)) );
	GPIOx->PUPDR |= ( (init->pupdr) << (pin*2) );

}
/*操控灯亮灯灭*/
//参数:第一个参数:GPIO组号; 第二个参数:引脚编号; 第三个参数:写0(熄灭)/写1(点亮)
void hal_gpio_write(volatile gpio_t* GPIOx,unsigned int pin,gpio_odr_t status)
{
	if(status==Off)
	{
		GPIOx->ODR &=(~(0x1<<pin));
	}
	else
	{	
		GPIOx->ODR |=(0x1<<pin);
	}
}

main.c

#include "key_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++);

}



int main()

{

	//初始化按键key1

	hal_exit_init(EXTI9,5,Falling);

	hal_gic_init(99,0x1f);

	//初始化按键key2

	hal_exit_init(EXTI7,5,Falling);

	hal_gic_init(97,0x1c);

	//初始化按键key3

	hal_exit_init(EXTI8,5,Falling);

	hal_gic_init(98,0x1a);



	//RCC初始化

    rcc_init();

	//初始化结构体

	gpio_init_t led_a={Output,Push_pull,Low_speed,No_up_down};

	//LED1初始化 PE10

	hal_gpio_init(GPIOE,GPIO_PIN_10,&led_a);

	//LED2初始化 PF10

	hal_gpio_init(GPIOF,GPIO_PIN_10,&led_a);

	//LED3初始化 PE8

	hal_gpio_init(GPIOE,GPIO_PIN_8,&led_a);	

	

	while(1)

	{

	}

	return 0;

}

do_irq.c

#include "key_led.h"

extern void printf(const char *fmt, ...);
extern void delay_ms(int ms);
void do_irq(void) 
{
	unsigned int num;
	//获取中断号 IAR[9:0]
	num = GICC->IAR & (0x3ff);

	switch(num)
	{
	case 97:
		printf("this is key2 $$$$$$$$$$$$$$ \n");
		//key1清除EXTI层中断挂起标志位 EXTI_FPR1[9]=0X1
		EXTI->FPR1 |= (0x1<<7);

		//清除GICD层中断挂起标志位 GICD_ICPENDR[3] [3]=1
		GICD->ICPENDR[3] |= (0x1<<1);

		//调用LED2点亮函数
		hal_gpio_write(GPIOF,GPIO_PIN_10,On);
		delay_ms(500);

		//调用LED2熄灭函数
		hal_gpio_write(GPIOF,GPIO_PIN_10,Off);		
		delay_ms(500);	

		break;
	case 98:
		printf("this is key3 ############# \n");
		//key1清除EXTI层中断挂起标志位 EXTI_FPR1[9]=0X1
		EXTI->FPR1 |= (0x1<<8);

		//清除GICD层中断挂起标志位 GICD_ICPENDR[3] [3]=1
		GICD->ICPENDR[3] |= (0x1<<2);

		//调用LED1点亮函数
		hal_gpio_write(GPIOE,GPIO_PIN_10,On);
		delay_ms(500);

		//调用LED1熄灭函数
		hal_gpio_write(GPIOE,GPIO_PIN_10,Off);
		delay_ms(500);

		break;
	case 99:
		printf("this is key1 \n");
		//key1清除EXTI层中断挂起标志位 EXTI_FPR1[9]=0X1
		EXTI->FPR1 |= (0x1<<9);

		//清除GICD层中断挂起标志位 GICD_ICPENDR[3] [3]=1
		GICD->ICPENDR[3] |= (0x1<<3);

		//调用LED3点亮函数
		hal_gpio_write(GPIOE,GPIO_PIN_8,On);
		delay_ms(500);
	
		//调用LED3熄灭函数
		hal_gpio_write(GPIOE,GPIO_PIN_8,Off);
		delay_ms(500);	
		
		break;
	}
	//清除获取到的中断号 
	GICC->EOIR = num;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值