arm (exti中断)

src/key_it.c

cs 复制代码
  1 #include "key_it.h"
  2 
  3 //按键1中断配置
  4 void key1_config()
  5 {
  6     //RCC章节
  7     //1:使能gpio f
  8     RCC->MP_AHB4ENSETR |= (0x1<<5);
  9     //因为exti和gic属于芯片内部 所以无需使能
 10 
 11     //GPIO章节
 12     //1:将key1对应的pf9引脚模式设置为输入
 13     RCC->MODER &= (~(0x3<<18));
 14 
 15     //EXTI章节
 16     //1:设置PF9生成exti9事件
 17     //EXTI_EXTICR3:外部中断选择寄存器,选择和哪一个EXTI编号进行连接
 18     //EXTI编号 / 4 = 商...余数        9/4=2...1
 19     //商+1:表示操作哪一个寄存器      编号3寄存器
 20     //余数*8:操作寄存器8位中的最低位 8
 21     //每8位管理一个寄存器编号,所以长度为8位->[15:8]
 22     //pf9对应值为0x05 [15:8]->0x05
 23     EXTI->EXTICR3 &= (~(0xFF<<8));
 24     EXTI->EXTICR3 |= (0x05<<8);
 25 
 26     //2:设置下降沿检测EXTI9事件
 27     //EXTI_FTSR1:下降沿事件选择寄存器
 28     //设置EXTI编号为下降沿触发
 29     //每一位检测一个事件 写1使能
 30     EXTI->FTSR1 |= (0x1<<9);
 31 
 32     //3:取消exti的事件屏蔽
 33     //EXTI_IMR1:中断屏蔽寄存器 设置EXTI层中断是否屏蔽
 34     //设置1不屏蔽
 35     EXTI->C1IMR1 |= (0x1<<9);
 36 
 37     //4:EXTI_FPR1:下降沿挂起寄存器 清除EXTI层中断挂起标志位
 38     //置1清除
 39     //EXTI->FPR1 |= (0x1<<9);
 40                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
 41     //GIC章节
 42     //GICD_CTLR:设置GICD层组0使能
 43     GICD->cTRL |= 0x1;
 44 
 45     //GICD_ISENABLERx(0 ~ 8):中断设置使能寄存器
 46     //设置对应的中断号使能
 47     //GIC层一共管理288个中断号
 48     //一个寄存器32位,每一位管理一个中断号,所以一个寄存器最多管理32个中断号
 49     //288 / 32 = 9 个中断设置使能寄存器GICD_ISENABLERx(0 ~ 8)
 50     //根据中断号,可以直接计算出操作哪一个寄存器,以及寄存器的位数
 51     //中断号 / 32 = 商........余数 99/32=3...3
 52     //商:表示操作哪一个寄存器     3号寄存器
 53     //余数:操作寄存器位数         
 54     //KEY1==>PF9==>EXTI9编号=>事件9=>99中断号=99/32=3...3=>GICD_ISENABLER3[3]=1
 55     GICD->ISENABLER[3] |= (0x1<<3);
 56 
 57     //GICD_IPRIORITYRx(0 ~ 71):中断优先级寄存器
 58     //设置GICD层中99号中断优先级
 59     //GIC层一共管理288个中断号(16个PPI,16个SGI,256个SPI)
 60     //寄存器32位,每八位管理一个中断号,所以一个寄存器最多管理4个中断号
 61     //288/4=72个寄存器
 62     //中断号 / 4 = 商........余数 99/4=24...3
 63     //商:表示操作哪一个寄存器    第24个寄存器
 64     //余数*8+3:操作寄存器位数中五位中最低位  27  [31,27](8位空三位)
 65     GICD->IPRIORITYR[24] &= (~(0x1F<<27));//设置为0 数值越小表示优先级越高
 66 
 67     //GICD_ITARGETSRx(0 ~ 71):中断目标分配寄存器 设置GICD层中断分配给哪一个cpu
 68     //288个中断号
 69     //寄存器32位,每八位管理一个中断号,所以一个寄存器最多管理4个中断号
 70     //288/4=72 个中断优先级寄存器GICD_ITARGETSRx(0 ~ 71)
 71     //中断号 / 4 = 商........余数          99/4=26...3
 72     //商:表示操作哪一个寄存器             26
 73     //余数*8:操作寄存器位数中五位中最低位 24 [25,24] 6位置空
 74     GICD->ITARGETSR[26] &= (~(0x3<<24));
 75     GICD->ITARGETSR[26] |= (0x1<<24); // 0b01 =====> 分配给cpu0
 76 
 77     //GICD_ICPENDRx(0 ~ 8):清除GICD层中断挂起标志位
 78     //288个中断号,寄存器32位每一位管理一个中断号,一个寄存器最多管理32个中断号
 79     //288 / 32 = 9
 80     //中断号 / 32 = 商........余数 99/32=3...3
 81     //商:表示操作哪一个寄存器     3
 82     //余数:操作寄存器位数         3
 83     //GICD->ICPENDR[3] |= (0x1<<3);
 84 
 85     //GICC_CTLR:设置GICC层组0使能
 86     //GICC_CTLR[0] = 1 =======> 设置GICC层组0使能
 87     GICC->CTLR |= 0x1;
 88 
 89     //GICC_PMR:GICC层中断优先级屏蔽寄存器
 90     //GICC_PMR[7:3] = 设置优先级值
 91     //1)GICD层的优先级需要比GICC层优先级高
 92    // 2)数值越小表示优先级越高
 93     GICC->PMR |= (0x1F<<3);
 94 }
~         

include/key_it.h

cs 复制代码
  1 #ifndef wwe
  2 #define wwe
  3 
  4 #include "stm32mp1xx_gpio.h"
  5 #include "stm32mp1xx_rcc.h"
  6 #include "stm32mp1xx_exti.h"
  7 #include "stm32mp1xx_gic.h"
  8 
  9 void key1_config();
 10 void key2_config();
 11 void key3_config();
 12 
 13 #endif  

do.c

cs 复制代码
  1 #include "key_it.h"
  2 //中断处理函数
  3 extern void printf(const char *fmt,...);
  4 void do_irp(void)
  5 {
  6     //先获取中断号
  7     //GICC_IAR:获取中断号的值 将GICC_IAR[9:0]的值读出来
  8     unsigned int irpno=(GICC->IAR &= (~(0x3FF)));
  9     switch(irpno)
 10     {
 11         case 99://key1中断
 12             //中断处理
 13             printf("key1触发\n");
 14             //清除gicd中的中断排队标志
 15     //GICD_ICPENDRx(0 ~ 8):清除GICD层中断挂起标志位
 16     //288个中断号,寄存器32位每一位管理一个中断号,一个寄存器最多管理32个中断号
 17     //288 / 32 = 9
 18     //中断号 / 32 = 商........余数 99/32=3...3
 19     //商:表示操作哪一个寄存器     3
 20     //余数:操作寄存器位数         3
 21     GICD->ICPENDR[3] |= (0x1<<3);
 22     //清除exit中的事件挂起标志
 23     //EXTI_FPR1:下降沿挂起寄存器 清除EXTI层中断挂起标志位
 24     //置1清除
 25     EXTI->FPR1 |= (0x1<<9);
 26     break;
 27 
 28     }
 29     //清除iar保存的中断号
 30     //GICC_EOIR:GICC end of interrupt register 寄存器作用:清除中断号
 31     //将获取到的中断号(IAR)进行清除
 32     GICC->EOIR = irqno;
 33 }  

main.c

cs 复制代码
  1 #include "key_it.h"
  2 extern void printf(const char *fmt,...);
  3 
  4 //封装延时函数
  5 void delay(int ms)
  6 {
  7     int i,j;
  8     for(i=0,i<ms,i++)
  9     {
 10         for(j=0,j<2000,j++)
 11         {}
 12     }
 13 }
 14 int main()
 15 {                                                                                                                                                                                                       
 16     key1_config();
 17     while(1)
 18     {
 19     printf("main.c\n");
 20     delay(1000);
 21 
 22 
 23     }
 24     return 0;
 25 }
相关推荐
DevinLGT28 分钟前
6Pin Type-C Pin脚定义:【图文讲解】
人工智能·单片机·嵌入式硬件
小A1591 小时前
STM32完全学习——系统时钟设置
stm32·嵌入式硬件·学习
CoderBob2 小时前
【EmbeddedGUI】脏矩阵设计说明
c语言·单片机
陌夏微秋3 小时前
51单片机基础02 动态数码管显示-并串转换
arm开发·单片机·嵌入式硬件·51单片机·硬件工程·信息与通信·信号处理
面包板扎3 小时前
51单片机应用开发---LCD1602显示应用
单片机·嵌入式硬件·51单片机
面包板扎3 小时前
51单片机应用开发(进阶)---定时器应用(电子时钟)
单片机
好想有猫猫3 小时前
【51单片机】LCD1602液晶显示屏
c语言·单片机·嵌入式硬件·51单片机·1024程序员节
陌夏微秋3 小时前
51单片机基础01 单片机最小系统
单片机·嵌入式硬件·51单片机·硬件工程·信息与通信
追梦少年时12 小时前
STM32-Flash闪存
stm32·单片机·嵌入式硬件·51单片机
weixin_4526006912 小时前
《青牛科技 GC6125:驱动芯片中的璀璨之星,点亮 IPcamera 和云台控制(替代 BU24025/ROHM)》
人工智能·科技·单片机·嵌入式硬件·新能源充电桩·智能充电枪