inclde/key.h
#ifndef __KEY_H__
#define __KEY_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"
#define PF9 (unsigned int) 0x05
#define PF7 (unsigned int) 0x05
#define PF8 (unsigned int) 0x05
//对RCC/GPIO/EXTI章节的初始化
void hal_key1_exit_init();
void hal_key2_exit_init();
void hal_key3_exit_init();
//对GIC的初始化
void hal_key1_gic_init();
void hal_key2_gic_init();
void hal_key3_gic_init();
//EXTI章节初始化
//参数:EXTI编号,GPIOF编号,中断触发方式:1上升沿0下降沿
void hal_exit_init(int E,int F,int X);
//GIC章节初始化
//参数:中断号,中断优先级
void hal_gic_init(int L,int S);
//引脚封装
#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
#define GPIO_PIN_11 11
#define GPIO_PIN_12 12
#define GPIO_PIN_13 13
#define GPIO_PIN_14 14
#define GPIO_PIN_15 15
//模式寄存器 0 1 2 3
typedef enum
{
INPUT,
OUTPUT,
ALT,
ANALOG,
}gpio_moder_t;
//输出类型寄存器
typedef enum
{
PP, //推挽
OD, //开漏
}gpio_otyper_t;
//输出速度寄存器
typedef enum
{
LOW,
MED,
HIGH,
VERY_HIGH,
}gpio_ospeedr_t;
//是否需要上下拉电阻寄存器封装
typedef enum
{
NO_PUPDR, //禁止 0
PU, //上拉 1
PD, //下拉 2
}gpio_pupdr_t;
//输出高低电平寄存器封装
typedef enum
{
GPIO_RESET_T, //输出低电平 0
GPIO_SET_T, //输出高电平 1
}gpio_odr_t;
//寄存器初始化封装
typedef struct
{
gpio_moder_t moder; //模式
gpio_otyper_t otyper; //输出类型
gpio_ospeedr_t ospeedr; //输出速率
gpio_pupdr_t pupdr; //是否需要上下拉电阻
}gpio_init_t;
//结构体封装
typedef struct{
char* cmd_arr; //命令符字符串
gpio_t * gpio; //gpio组号
unsigned int pin; //对应的引脚编号
gpio_odr_t status; //LED灯状态
void (*gpio_write_p)(gpio_t * gpio,unsigned int pin, gpio_odr_t status);
}cmd_t;
//灯的初始化GPIO初始化
void my_Initi_Led(gpio_t* gpiox,unsigned int pin,gpio_init_t* init);
//灯的设置高低电平
void hal_gpio_write(gpio_t* gpiox,unsigned int pin);
#endif
src/key.c
#include "key.h"
//EXTI章节初始化
void hal_exit_init(int E,int F,int X)
{
//RCC
RCC->MP_AHB4ENSETR |= (0x1 << 5);
//GPIO设置输入模式
GPIOF->MODER &= (~(0x3 << E*2));
//1.外部中断选择寄存器,选择与哪个EXTI(16)链接
int num1 = (E/4)+1;
int num2 = (E%4)*8;
switch(num1)
{
case 1:
EXTI->EXTICR1 &= (~(0xff << num2));
EXTI->EXTICR1 |= (F << num2);
break;
case 2:
EXTI->EXTICR2 &= (~(0xff << num2));
EXTI->EXTICR2 |= (F << num2);
break;
case 3:
EXTI->EXTICR3 &= (~(0xff << num2));
EXTI->EXTICR3 |= (F << num2);
break;
case 4:
EXTI->EXTICR4 &= (~(0xff << num2));
EXTI->EXTICR4 |= (F << num2);
break;
}
//2.设置中断下降沿触发方式
if(X == 0)
{
EXTI->FTSR1 |= (0x1 << E);
}
else
{
EXTI->FTSR1 |= (0x1 << E);
}
//3.中断屏蔽选择寄存器
EXTI->C1IMR1 |= (0b01 << E);
}
//GIC章节初始化
//参数:中断号,中断优先级
void hal_gic_init(int L,int S)
{
//GICD的初始化
//1.使能GICD层控制器
GICD->CTRL |= 0x1;
//2.设置GICD层的中断使能
GICD->ISENABLER[L/32] |= (0x1 << (L%32));
//3.设置GICD层中断优先级
GICD->IPRIORITYR[L/4] |= ((S-1) << ((L%32)*8+3));
//4.设置GICD层中断目标分配寄存器
GICD->ITARGETSR[L/4] |= (0x1 << (L%4)*8);
//GICC章节初始化
//1.使能GICC层控制器
GICC->CTRL |= 0x1;
//2.设置GICC层中断优先级
GICC->PMR |= (S << 3);
}
//灯的设置高低电平
void hal_gpio_write(gpio_t* gpiox,unsigned int pin)
{
gpiox->ODR ^= (0x1 << pin);
}
//GPIO初始化相关操作
void my_Initi_Led(gpio_t* gpiox,unsigned int pin,gpio_init_t* init)
{
//模式
gpiox->MODER &= (~(0x3 << (2*pin)));
gpiox->MODER |= (init->moder << (2*pin));
//类型
gpiox->OTYPER &= (~(0x1 << pin));
gpiox->OTYPER |= (init->otyper << pin);
//速度
gpiox->OSPEEDR &= (~(0x3 << (2*pin)));
gpiox->OSPEEDR |= (init->ospeedr << (2*pin));
//上下拉电阻
gpiox->PUPDR &= (~(0x3 << (2*pin)));
gpiox->PUPDR |= (init->pupdr << (2*pin));
}
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++);
}
//
void init_Led()
{
//通过RCC章节 将GPIOE GPIOF 组控制器使能
RCC->MP_AHB4ENSETR |= (0x3 << 4);
//结构体初始化
gpio_init_t init = {OUTPUT,PP,LOW,NO_PUPDR};
//调用函数初始化
my_Initi_Led(GPIOE,GPIO_PIN_10, &init);
my_Initi_Led(GPIOF,GPIO_PIN_10, &init);
my_Initi_Led(GPIOE,GPIO_PIN_8, &init);
}
int main()
{
hal_exit_init(9,PF9,0);
hal_exit_init(7,PF7,0);
hal_exit_init(8,PF8,0);
hal_gic_init(99,9);
hal_gic_init(97,7);
hal_gic_init(98,8);
init_Led();
while(1)
{
}
return 0;
}
src/do_irq.c
#include "key.h"
extern void printf(const char *fmt, ...);
//key1----->PF9----->EXTI9---->EXTI_FPR1[9]
//key2----->PF7----->EXTI7---->EXTI_FPR1[7]
//key3----->PF8----->EXTI8---->EXTI_FPR1[8]
void do_irq(void)
{
unsigned int num;
num = GICC->IAR & 0x3ff;
switch (num)
{
case 99:
printf("key1 press#####\n");
hal_gpio_write(GPIOE,10);
//1.消除EXTI层中断挂起标志位
EXTI->FPR1 |= (0x1 << 9);
//2.消除GICD层的中断挂起标志位
GICD->ICPENDR[3] |= (0x1 << 3);
break;
case 97:
printf("key2 press#####\n");
hal_gpio_write(GPIOF,10);
//1.消除EXTI层中断挂起标志位
EXTI->FPR1 |= (0x1 << 7);
//2.消除GICD层的中断挂起标志位
GICD->ICPENDR[3] |= (0x1);
break;
case 98:
printf("key3 press#####\n");
hal_gpio_write(GPIOE,8);
//1.消除EXTI层中断挂起标志位
EXTI->FPR1 |= (0x1 << 8);
//2.消除GICD层的中断挂起标志位
GICD->ICPENDR[3] |= (0x1 << 2);
break;
}
//3.清除获取到的中断号
GICC->EOIR |= num;
}