1. 中断实验
按下key1 led3取反
按下key2 led2取反
按下key3 led1取反
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++);
}
int main()
{
rcc_init();
led_init(GPIOE,10);
led_init(GPIOF,10);
led_init(GPIOE,8);
exti_init(EXTI9,0X05,FALLING);
exti_init(EXTI8,0X05,FALLING);
exti_init(EXTI7,0X05,FALLING);
gic_init(99,0);
gic_init(98,0);
gic_init(97,0);
led_nof(GPIOE,10);
led_nof(GPIOF,10);
led_nof(GPIOE,8);
for(;;);
return 0;
}
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 EXTI9 9
#define EXTI8 8
#define EXTI7 7
typedef enum{
RISING,
FALLING
}trigger;
//初始化gcc gicdctlr giccctlr
void rcc_init();
//初始化exti 编号 gpio组号 触发方式
void exti_init(int num,unsigned int gid,trigger t);
//初始化 gic 中断号 优先级
void gic_init(int num,unsigned int priority);
//初始化led
void led_init(gpio_t* gpio,int pin);
//开关led
void led_nof(gpio_t* gpio,int pin);
#endif
key.c
#include "key.h"
void rcc_init()
{
//rcc
RCC->MP_AHB4ENSETR |= (3<<4);
//gicd_ctrl
GICD->CTRL |= 1;
//gicc_ctrl
GICC->CTRL |= 1;
//gicc_pmr
GICC->PMR |= (0X1F << 3);
}
void exti_init(int num,unsigned int gid,trigger t)
{
GPIOF->MODER &= ~(3 << (num*2));
if((num/4) == 2)
{
EXTI->EXTICR3 &= ~(0XFF << (num%4*8));
EXTI->EXTICR3 |= (gid << (num%4*8));
}
else
{
EXTI->EXTICR2 &= ~(0XFF << (num%4*8));
EXTI->EXTICR2 |= (gid << (num%4*8));
}
//extiftsr1
if(t == FALLING)
EXTI->FTSR1 |= (1 << num);
//extiimr1
EXTI->C1IMR1 |= (1 << num);
}
void gic_init(int num,unsigned int priority)
{
//gicd_isenabler
GICD->ISENABLER[num/32] |= (1 << (num%32));
//gicd_ipriorityr
GICD->IPRIORITYR[num/4] &= ~(0X1F << (num%4*8+3));
GICD->IPRIORITYR[num/4] |= (priority << (num%4*8+3));
//GICD_ITARGETSR
GICD->ITARGETSR[num/4] |= (1 << (num%4*8));
}
void led_init(gpio_t* gpio,int pin)
{
//模式设置为输出
gpio->MODER &= ~(3 << (pin*2));
gpio->MODER |= (1 << (pin*2));
gpio->OTYPER &= ~(1 << pin);
gpio->OSPEEDR &= ~(3 << (pin*2));
gpio->PUPDR &= ~(3 << (pin*2));
}
void led_nof(gpio_t* gpio,int pin)
{
gpio->ODR ^= (1 << pin);
}
do_irq.c
extern void printf(const char *fmt, ...);
#include "key.h"
void do_irq(void)
{
//判断中断号
unsigned int iar = GICC->IAR;
unsigned int num = iar & 0x3ff;
printf("key\n");
switch(num)
{
case 97:
{
led_nof(GPIOF,10);
//清除exti
EXTI->FPR1 |= (1 << (num-90));
//gicd_icpendr 清除gicd
GICD->ICPENDR[num/32] |= (1 << (num%32));
break;
}
case 98:
{
led_nof(GPIOE,10);
//清除exti
EXTI->FPR1 |= (1 << (num-90));
//gicd_icpendr 清除gicd
GICD->ICPENDR[num/32] |= (1 << (num%32));
break;
}
case 99:
{
led_nof(GPIOE,8);
//清除exti
EXTI->FPR1 |= (1 << (num-90));
//gicd_icpendr 清除gicd
GICD->ICPENDR[num/32] |= (1 << (num%32));
break;
}
}
//清除 GICC
GICC->EOIR = iar;
}