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]=1GICD->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]=1GICC->CTRL |= (0x1<<0);//1.设置GICC层中断优先级 GICC_PMR[7:3]=11111GICC->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(){//初始化按键key1hal_exit_init(EXTI9,5,Falling);hal_gic_init(99,0x1f);//初始化按键key2hal_exit_init(EXTI7,5,Falling);hal_gic_init(97,0x1c);//初始化按键key3hal_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初始化 PE10hal_gpio_init(GPIOE,GPIO_PIN_10,&led_a);//LED2初始化 PF10hal_gpio_init(GPIOF,GPIO_PIN_10,&led_a);//LED3初始化 PE8hal_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]=0X1EXTI->FPR1 |= (0x1<<7);//清除GICD层中断挂起标志位 GICD_ICPENDR[3] [3]=1GICD->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]=0X1EXTI->FPR1 |= (0x1<<8);//清除GICD层中断挂起标志位 GICD_ICPENDR[3] [3]=1GICD->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]=0X1EXTI->FPR1 |= (0x1<<9);//清除GICD层中断挂起标志位 GICD_ICPENDR[3] [3]=1GICD->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;
}