成果图:
代码:
函数层
key_it.c
#include "key_init.h"
void key1_it_config()
{ //RCC时钟
RCC->MP_AHB4ENSETR |=(0X1<<5);
//设置PF9管脚为输入
GPIOF->MODER &=(~(0x3<<18));
//设置PF9管脚为exti9输入
EXTI->EXTICR3 &=(~0x1f<<8);
EXTI->EXTICR3 |=(0x05<<8);
//设置下降沿使能检测exti9
EXTI->FTSR1|=(0x1<<9);
//设置exti9事件不屏蔽
EXTI->C1IMR1|=(0x1<<9);
//GICD
//GICD使能EXTI9(99号)中断
GICD->ISENABLER[3]|=(0x1<<3);
//GICD设置99号中断的优先级
GICD->IPRIORITYR[24]&=(~(0x1f<<27));
//选择CPU0处理当前中断
GICD->ITARGETSR[24]|=(0x1<<24);
//全局使能组0中断被转发到GICC
GICD->CTRL|=(0x1);
//GICC
//设置中断的优先级掩码
GICC->PMR |=(0x1f<<3);
//允许组0中断被cpu处理
GICC->CTRL |=(0x1);
}
void key2_it_config(){
//RCC时钟
RCC->MP_AHB4ENSETR |=(0X1<<5);
//设置PF7管脚为输入
GPIOF->MODER &=(~(0x3<<14));
//设置PF7管脚为exti7输入
EXTI->EXTICR2 &=(~0x1f<<24);
EXTI->EXTICR2 |=(0x05<<24);
//设置下降沿使能检测exti7
EXTI->FTSR1|=(0x1<<7);
//设置exti7事件不屏蔽
EXTI->C1IMR1|=(0x1<<7);
//GICD
//GICD使能EXTI9(97号)中断
GICD->ISENABLER[3]|=(0x1<<1);
//GICD设置97号中断的优先级
GICD->IPRIORITYR[24]&=(~(0x1f<<11));
//选择CPU0处理当前中断
GICD->ITARGETSR[24]|=(0x1<<8);
//全局使能组0中断被转发到GICC
GICD->CTRL|=(0x1);
//GICC
//设置中断的优先级掩码
GICC->PMR |=(0x1f<<3);
//允许组0中断被cpu处理
GICC->CTRL |=(0x1);
}
void key3_it_config(){
//RCC时钟
RCC->MP_AHB4ENSETR |=(0X1<<5);
//设置PF8管脚为输入
GPIOF->MODER &=(~(0x3<<16));
//设置PF8管脚为exti8输入
EXTI->EXTICR3 &=(~0x1f<<0);
EXTI->EXTICR3 |=(0x05<<0);
//设置下降沿使能检测exti8
EXTI->FTSR1|=(0x1<<8);
//设置exti8事件不屏蔽
EXTI->C1IMR1|=(0x1<<8);
//GICD
//GICD使能EXTI8(98号)中断
GICD->ISENABLER[3]|=(0x1<<2);
//GICD设置98号中断的优先级
GICD->IPRIORITYR[24]&=(~(0x1f<<19));
//选择CPU0处理当前中断
GICD->ITARGETSR[24]|=(0x1<<16);
//全局使能组0中断被转发到GICC
GICD->CTRL|=(0x1);
//GICC
//设置中断的优先级掩码
GICC->PMR |=(0x1f<<3);
//允许组0中断被cpu处理
GICC->CTRL |=(0x1);
}
led.c
#include"led.h"
void led_inti()
{
//LED 1 PE10或风扇 PE9
RCC->MP_AHB4ENSETR |=(0x3<<4) ;
//LED 2 PF10
RCC->MP_AHB4ENSETR |=(0x3<<5) ;
//LED1 PE10
GPIOE->MODER &=(~(0x3)<<20);
GPIOE->MODER |=((0x1)<<20);
GPIOE->OTYPER &=(~(0x1<<10));
GPIOE->OSPEEDR &=(~(0x3)<<20);
GPIOE->PUPDR &=(~(0x3)<<20);
//LED2 PF10
GPIOF->MODER &=(~(0x3)<<20);
GPIOF->MODER |=(0x1)<<20;
GPIOF->OTYPER &=(~(0x1<<10));
GPIOF->OSPEEDR &=(~(0x3)<<20);
GPIOF->PUPDR &=(~(0x3)<<20);
//风扇 PE9
GPIOE->MODER &=(~(0x3)<<18);
GPIOE->MODER |=((0x1)<<18);
GPIOE->OTYPER &=(~(0x1<<9));
GPIOE->OSPEEDR &=(~(0x3)<<18);
GPIOE->PUPDR &=(~(0x3)<<18);
}
//PE10
void led_1_on(){
GPIOE->ODR |=((0x1)<<10);
}
void led_1_off(){
GPIOE->ODR &=(~(0x1<<10));
}
//PF10
void led_2_on(){
GPIOF->ODR |=((0x1)<<10);
}
void led_2_off(){
GPIOF->ODR &=(~(0x1<<10));
}
//PE9
void staff_on(){
GPIOE->ODR |=((0x1)<<9);
}
void staff_off(){
GPIOE->ODR &=(~(0x1<<9));
}
do_irq.c
#include"key_init.h"
#include"led.h"
extern void printf(const char *fmt, ...);
unsigned int i = 0;
void do_irq(void)
{
int irqno=(GICC->IAR &0x3ff);
switch (irqno)
{
case 97:
printf("KEY2_INT\n");
led_2_on();
//清除GICD的中断排队标志
GICD->ICPENDR[1]|=(0x1<<1);
//清除exti的事件触发标志
EXTI->FPR1 |=(0X1<<7);
break;
case 98:
printf("KEY3_INT\n");
staff_on();
//清除GICD的中断排队标志
GICD->ICPENDR[3]|=(0x1<<2);
//清除exti的事件触发标志
EXTI->FPR1 |=(0X1<<8);
break;
case 99:
printf("KEY1_INT\n");
led_1_on();
//清除GICD的中断排队标志
GICD->ICPENDR[3]|=(0x1<<3);
//清除exti的事件触发标志
EXTI->FPR1 |=(0X1<<9);
break;
}
//清除中断信号
GICC->EOIR=irqno;
}
头文件
led.h
#ifndef __LED_HEAD__
#define __LED_HEAD__
#include"stm32mp1xx_rcc.h"
#include"stm32mp1xx_gpio.h"
void led_inti();
void led_1_on();
void led_1_off();
void led_2_on();
void led_2_off();
void staff_on();
void staff_off();
#endif
key_init.h
#ifndef __key_init_HEAD__
#define __key_init_HEAD__
#include"stm32mp1xx_gpio.h"
#include"stm32mp1xx_gic.h"
#include"stm32mp1xx_rcc.h"
#include"stm32mp1xx_exti.h"
void key1_it_config();
void key2_it_config();
void key3_it_config();
#endif
主函数
main.c
#include "gpio.h"
#include "key_init.h"
#include"led.h"
void daley(int ms)
{
int i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<2000;j++);
}
}
int main()
{
key1_it_config();
key2_it_config();
key3_it_config();
led_inti();
while (1)
{
printf("login in...\n");
led_1_off();
led_2_off();
daley(1000);
}
return 0;
}