1.key_in.c
- #include "key_in.h"
-
- void gpio_init()
- {
- //RCC使能
- //GPIOE
- RCC->MP_AHB4ENSETR |= (0x1<<4);
- //GPIOB
- RCC->MP_AHB4ENSETR |= (0x1<<1);
-
- //PE10、PB6、PE9输出模式
- GPIOE->MODER &= ~(0x3<<20);
- GPIOE->MODER |= (0x1<<20);
- GPIOB->MODER &= ~(0x3<<12);
- GPIOB->MODER |= (0x1<<12);
- GPIOE->MODER &= ~(0x3<<18);
- GPIOE->MODER |= (0x1<<18);
- //推挽模式
- GPIOE->OTYPER &= ~(0x1<<10);
- GPIOB->OTYPER &= ~(0x1<<6);
- GPIOE->OTYPER &= ~(0x1<<9);
- //速度设置为低速
- GPIOE->OSPEEDR &= ~(0x3<<20);
- GPIOB->OSPEEDR &= ~(0x3<<12);
- GPIOE->OSPEEDR &= ~(0x3<<18);
- //设置为无上拉下拉电阻
- GPIOE->PUPDR &= ~(0x3<<20);
- GPIOB->PUPDR &= ~(0x3<<12);
- GPIOE->PUPDR &= ~(0x3<<18);
-
- }
- void key_in_config()
- {
- //RCC使能GPIOF时钟
- RCC->MP_AHB4ENSETR |= (0x1<<5);
- //设置PF9 PF7 PF8管脚为输入模式
- GPIOF->MODER &= ~(0x3f<<14);
-
- //设置PF9 PF7 PF8发生EXTI事件
- EXTI->EXTICR3 &= ~(0xff<<8);
- EXTI->EXTICR3 |= (0x05<<8);
- EXTI->EXTICR2 &= ~(0xff<<24);
- EXTI->EXTICR2 |= (0x05<<24);
- EXTI->EXTICR3 &= ~(0xff);
- EXTI->EXTICR3 |= (0x05);
- //设置EXTI中断触发模式为下降沿模式
- EXTI->FTSR1 |= (0x7<<7);
- //设置EXTI事件触发为不屏蔽
- EXTI->C1IMR1 |= (0x7<<7);
-
- //使能组0
- GICD->CTRL |= 0x1;
- //中断使能,使其可以传到CPU
- GICD->ISENABLER[3] |= (0x1<<3);
- GICD->ISENABLER[3] |= (0x1<<1);
- GICD->ISENABLER[3] |= (0x1<<2);
- //设置中断优先级
- GICD->IPRIORITYR[24] &= ~(0x1f<<27);
- GICD->IPRIORITYR[24] &= ~(0x1f<<11);
- GICD->IPRIORITYR[24] &= ~(0x1f<<19);
- //选择CPU处理中断
- GICD->ITARGETSR[24] &= ~(0x3<<24);
- GICD->ITARGETSR[24] |= (0x1<<24);
- GICD->ITARGETSR[24] &= ~(0x3<<8);
- GICD->ITARGETSR[24] |= (0x1<<8);
- GICD->ITARGETSR[24] &= ~(0x3<<16);
- GICD->ITARGETSR[24] |= (0x1<<16);
- //使能CPU处理转发的中断
- GICC->CTRL |= 0x1;
- //设置中断掩码
- GICC->PMR &= ~(0x1f<<3);
- GICC->PMR |= (0x5<<3);
-
-
- }
2. do_irq.c:
- #include "key_in.h"
- extern void printf(const char *fmt, ...);
- unsigned int i = 0;
-
- void do_irq(void)
- {
- int irqno;
- static int i1=0,i2=0,i3=0;
- irqno = GICC->IAR & 0x3ff;
- switch(irqno)
- {
- case 99:
- printf("KEY1 %d\n",irqno);
- i1++;
- //key1中断处理,LED1
- if(i1%2==1)
- GPIOE->ODR |= (0x1<<10);
- else
- GPIOE->ODR &= ~(0x1<<10);
- //清除挂起中断标识位
- GICD->ICPENDR[3] |= (0x1<<3);
- //清除事情挂起标识位
- EXTI->FPR1 |= (0x1<<9);
- break;
- case 97:
- printf("KEY2 %d\n",irqno);
- i2++;
- //key2中断处理,蜂鸣器
- if(i2%2==1)
- GPIOB->ODR |= (0x1<<6);
- else
- GPIOB->ODR &= ~(0x1<<6);
- //清除挂起中断标识位
- GICD->ICPENDR[3] |= (0x1<<1);
- //清除事情挂起标识位
- EXTI->FPR1 |= (0x1<<7);
- break;
- case 98:
- printf("KEY3 %d\n",irqno);
- i3++;
- //key3中断处理,风扇
- if(i3%2==1)
- GPIOE->ODR |= (0x1<<9);
- else
- GPIOE->ODR &= ~(0x1<<9);
- //清除挂起中断标识位
- GICD->ICPENDR[3] |= (0x1<<2);
- //清除事情挂起标识位
- EXTI->FPR1 |= (0x1<<8);
- break;
- }
- //清除处理完的中断IAR到EOIR
- GICC->EOIR=irqno;
- }
3. key_in.h:
- #ifndef __KEY_IN_H__
- #define __KEY_IN_H__
- #include "stm32mp1xx_rcc.h"
- #include "stm32mp1xx_gpio.h"
- #include "stm32mp1xx_exti.h"
- #include "stm32mp1xx_gic.h"
-
-
- void gpio_init();
- void key_in_config();
- #endif
4. main.c
- #include "key_in.h"
-
- int main()
- {
- gpio_init();
- key_in_config();
- while(1)
- {
-
- }
- return 0;
- }
5. 实验现象:
