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