//main.c
#include "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()
{
hal_exit_init(EXTI9,PF9,FTSR);
hal_gic_init(99,0x1d);
hal_exit_init(EXTI7,PF8,FTSR);
hal_gic_init(97,0x1e);
hal_exit_init(EXTI8,PF7,FTSR);
hal_gic_init(98,0x1f);
led_init();
while(1)
{
}
return 0;
}
//led.h
#ifndef __LED_H__
#define __LED_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"
//引脚封装
#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
#define PF7 0x05
#define PF8 0x05
#define PF9 0x05
#define EXTI7 7
#define EXTI8 8
#define EXTI9 9
#define RTSR 0 //上升沿
#define FTSR 1 //下降沿
typedef unsigned int status_t;
typedef struct{
char *cmd_arr; //命令符字符串
gpio_t *gpio; //gpio组号
unsigned int pin; //对应的引脚编号
status_t status; //LED灯状态
void (*gpio_write_p)(gpio_t * gpio,unsigned int pin, status_t status);
}cmd_t;
//模式寄存器封装
typedef enum{
INPUT, //0 0b00
OUTPUT, //1 0b01
ALT, //2 0b10
ANALOG, //3 0b11
}gpio_moder_t; //4
//输出类型寄存器封装
typedef enum{
PP, //推挽 0 0b0
OD, //开漏 1 0b1
}gpio_otyper_t;
//输出速度寄存器封装
typedef enum{
LOW, //低速 0 0b00
MED, //中速 1 0b01
HIGH, //高速 2 0b10
VERT_HIGH, //超高速 3 0b11
}gpio_ospeedr_t;
//是否需要上下拉电阻寄存器封装
typedef enum{
NO_PUPDR, //禁止 0 0b00
PU, //上拉 1 0b01
PD, //下拉 2 0b10
}gpio_pupdr_t;
//输出高低电平寄存器封装
typedef enum{
GPIO_RESET_T, //输出低电平 0 0b0
GPIO_SET_T, //输出高电平 1 0b1
}gpio_odr_t;
//寄存器初始化封装
typedef struct{
gpio_moder_t moder; //模式
gpio_otyper_t otyper; //输出类型
gpio_ospeedr_t ospeedr; //输出速率
gpio_pupdr_t pupdr; //是否需要上下拉电阻
}gpio_init_t;
//EXIT章节初始化
void hal_exit_init(volatile unsigned int my_EXTI,unsigned int gpio, unsigned int RF);
//GIC章节初始化
void hal_gic_init(unsigned int interNum,unsigned int priority);
//PE10 PF10 PE8
//函数: 1)GPIO组号 2)引脚编号 3)初始化相关的值
//无返回值
void hal_gpio_init(gpio_t* gpiox,unsigned int pin, gpio_init_t* init);
//函数2功能:对GPIO引脚操作,写0输出低电平 写1输出高电平
//参数:1)GPIO组号 2)引脚编号 3)写入的值
//无返回值
void hal_gpio_write(gpio_t* gpiox,unsigned int pin,unsigned int gpio_status);
void led_init();
#endif
//led.c
#include "led.h"
void hal_exit_init(volatile unsigned int my_EXTI, unsigned int gpio, unsigned int RF)
{
RCC->MP_AHB4ENSETR |= (0x1 << 5);
//计算EXTICRn的偏移量 9/4=2 8/4=2 7/4=1
int exticrn = my_EXTI/4;
int bExticrn = my_EXTI%4;
GPIOF->MODER &=(~(0x3 << my_EXTI *2));//led1 pf9
//key和exit做连接
*(&(EXTI->EXTICR1)+exticrn) &= (~(0xff << bExticrn*8));
*(&(EXTI->EXTICR1)+exticrn) |= (gpio << bExticrn*8);
//设置下降沿触发
if(RF == 1) //=1上升沿触发
EXTI->FTSR1 |= (0x1 << my_EXTI);
else
EXTI->RTSR1 |= (0x1 << my_EXTI);
//设置中断不屏蔽
EXTI->C1IMR1 |= (0x1 << my_EXTI);
}
void hal_gic_init(unsigned int interNum, unsigned int priority)
{
GICD->CTRL |=(0x1<<0);
//GICD层中断使能寄存器
int consult = 0;
int remain =0;
consult = interNum/32;
remain = interNum%32;
GICD->ISENABLER[consult] |=(0x1 << remain);
//GICD层中断优先级寄存器
consult = interNum / 4;
remain = interNum % 4;
GICD->IPRIORITYR[consult] &=(~(priority << (remain*8+3)));
//GICD层中断目标分配寄存器
consult = interNum / 4;
remain = interNum % 4;
GICD->ITARGETSR[consult] &= (~(0x03 << remain*8));
GICD->ITARGETSR[consult] |= (0x01 << remain*8);
//使能GICC层控制器
GICC->CTRL |= (0x1 << 0);
//设置GICC层中断优先级
GICC->PMR |= (0x2 << 3);
}
//led 初始化函数
void hal_gpio_init(gpio_t* gpiox, unsigned int pin, gpio_init_t* init)
{
//设置GPIO引脚模式
gpiox->MODER &= (~(0x3<<(pin*2))); //对21:20(以PE10为例)清0
gpiox->MODER |= (init->moder << (pin*2)); //将21:20设置为moder代表的模式
//设置GPIO引脚类型
gpiox->OTYPER &= (~(0x1 << pin));
gpiox->OTYPER |= (init->otyper << pin);
//设置GPIO引脚速率
gpiox->OSPEEDR &= (~(0x1 << (pin *2)));
gpiox->OSPEEDR |= (init->ospeedr << (pin * 2));
//设置GPIO引脚上下拉电阻
gpiox->PUPDR &= (~(0x1 << (pin * 2)));
gpiox->PUPDR |= (init->pupdr << (pin *2));
}
//控制led打开或关闭
void hal_gpio_write(gpio_t* gpiox,unsigned int pin,unsigned int gpio_status)
{
//判断输入的值是否为低电平
if(gpio_status == GPIO_RESET_T)
{
gpiox->ODR &= (~(0x1 << pin)); //将LEDn关闭
}
else
{
gpiox->ODR |= (0x1<< pin); //将LEDn打开
}
}
//led初始化函数
void led_init()
{
//结构体初始化 设置输出模式,类型,速率,上下拉电阻
gpio_init_t init = {OUTPUT,PP,LOW,NO_PUPDR};
//调用gpio初始化函数
//LED1
hal_gpio_init(GPIOE, GPIO_PIN_10, &init);
//LED2
hal_gpio_init(GPIOF, GPIO_PIN_10, &init);
//LED3
hal_gpio_init(GPIOE, GPIO_PIN_8, &init);
}
//do_irq.c
#include "led.h"
extern void printf(const char *fmt, ...);
unsigned int i = 0;
//标记led开启/关闭状态
int ledState[3]={0,0,0};
void do_irq(void)
{
unsigned int num;
//获取中断号
num = GICC->IAR & (0x3ff);
switch(num)
{
case 97:
printf("key2 press!\n");
//对led2的状态取反
ledState[1] ^=0x01;
hal_gpio_write(GPIOF,GPIO_PIN_10,ledState[1]);
EXTI->FPR1 |=(0x1<<7);
GICD->ICPENDR[3] |=(0x1 << 1);
break;
case 98:
printf("key3 press!\n");
//对led3的状态取反
ledState[2] ^=0x01;
hal_gpio_write(GPIOE,GPIO_PIN_8,ledState[2]);
EXTI->FPR1 |=(0x1<<8);
GICD->ICPENDR[3] |=(0x1 << 2);
break;
case 99:
printf("key1 pres!\n");
//对led3的状态取反
ledState[0] ^=0x01;
hal_gpio_write(GPIOE,GPIO_PIN_10,ledState[0]);
//1.清除EXIT层中断挂起标志位
EXTI->FPR1 |=(0x1<<9);
//2.清除GICD中断挂起标志位
GICD->ICPENDR[3] |=(0x1 << 3);
break;
}
//3.清除获取到的中断号
GICC->EOIR = num;
}
基于STM32A7核按键点亮LED灯的示例程序
该代码实现了一个基于STM32MP1xx微处理器的GPIO初始化、EXTI中断配置和GIC中断控制器设置的程序,用于LED灯的控制。主要功能包括LED初始化、中断服务函数do_irq,以及针对EXTI7、EXTI8和EXTI9的中断处理,根据按键按下触发不同LED的状态改变。
摘要由CSDN通过智能技术生成