一、外部请求:
线0~15:对应外部IO口的输入中断。
线16:连接到PVD输出。
线17:连接到RTC闹钟事件。
线18:连接到USB唤醒事件。
二、中断方式
每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位
三、中断线
看图:
GPIOx.0映射到EXTI0
GPIOx.1映射到EXTI1
…
GPIOx.15映射到EXTI15
选择不同闪存容量的32,中断线有点不一样
中断线使用需要注意的问题:
IO口每个都可以作为中断使用,但是却不能同时使用,稍不注意,都会造成程序错误,但是却不报错,运行的结果与自己想的相差甚远,却找不出原因:
外部中断配置寄存器AFIO_EXITCRx(x=1,2,3,4),每个寄存器控制IO端口(A~G)的4个IO口
例如:AFIO_EXITCR1的[3:0]控制(PA0~PG0);[3:0]=0x0000,选PA0; =0x0001,选PB0;以此类推
AFIO_EXITCR1的[7:4]控制(PA1~PG1);[3:0]=0x0000,选PA1; =0x0001,选PB1;以此类推
AFIO_EXITCR2的[3:0]控制(PA4~PG4);[3:0]=0x0000,选PA4; =0x0001,选PB4;以此类推
即:AFIO_EXITCR1控制(PA~PG)端口的0~3 I/O 口,AFIO_EXITCR2控制(PA~PG)端口的4~7 I/O 口,
AFIO_EXITCR1控制(PA~PG)端口的8~11 I/O 口,AFIO_EXITCR2控制(PA~PG)端口的12~15 I/O 口,
因此,每次只能出现一个相同数字的IO口(PA0~PG0,一个工程最多只能出现其中一个,其它的也一样)则每次最多有16个外部中断
即:假如AFIO_EXITCR1的[3:0] 为 0000时,选择的是PA0作为中断
但是STM32只有7个中断服务函数分别为
EXIT0, 供PA0,PB0,,,,PG0使用
EXIT1, 供PA1,PB1,,,,PG1使用
EXIT2, 供PA2,PB2,,,,PG2使用
EXIT3, 供PA3,PB3,,,,PG3使用
EXIT4, 供PA4,PB4,,,,PG4使用
EXIT9_5, 供PA5~PA9,PB5~PB9,,,,PG5~PG9使用
EXIT15_10, 供PA10~PA15,PB10~PB15,,,,PG10~PG15使用
因为,一个中断服务函数,一次只能给一个IO口使用,所以同时只能有7个外部中断
四、代码初始化
我现在使用的是原子的寄存器的代码,粘贴上来吧
步骤:
1、初始化IO口为输入 RCC->APB2ENR|
2、开启与该 IO 口相对的线上中断/事件,设置触发条件。 Ex_NVIC_Config(GPIO_A,0,RTIR); PA0 ,上升沿触发
3、配置中断分组(NVIC),并使能中断。 MY_NVIC_Init(2,3,EXTI0_IRQn,2); /抢占2,子优先级3,中断线0,组2
4、编写中断服务函数。
void EXTI0_IRQHandler(void)
中断初始化:
void EXTIX_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA时钟
RCC->APB2ENR|=1<<6; //使能PORTE时钟
GPIOA->CRL&=0XFFFFFFF0; //PA0设置成输入,默认下拉
GPIOA->CRL|=0X00000008;
GPIOE->CRL&=0XFFF00FFF; //PE3/4设置成输入
GPIOE->CRL|=0X00088000;
GPIOE->ODR|=3<<3; //PE3/4 上拉
Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发
Ex_NVIC_Config(GPIO_E,3,FTIR); //下降沿触发
Ex_NVIC_Config(GPIO_E,4,FTIR); //下降沿触发
MY_NVIC_Init(2,3,EXTI0_IRQn,2); //抢占2,子优先级3,组2
MY_NVIC_Init(2,1,EXTI3_IRQn,2); //抢占2,子优先级1,组2
MY_NVIC_Init(2,0,EXTI4_IRQn,2); //抢占2,子优先级0,组2
}
中断服务函数:
void EXTI0_IRQHandler(void)
{
delay_ms(10); //消抖
if(WK_UP==1) //WK_UP按键
{
//中断想要实现什么功能,可以写在这里
}
EXTI->PR=1<<0; //清除LINE0上的中断标志位
}
//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY1==0) //按键KEY1
{
//中断想要实现什么功能,可以写在这里
}
EXTI->PR=1<<3; //清除LINE3上的中断标志位
}
//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY0==0) //按键KEY0
{
//中断想要实现什么功能,可以写在这里
}
EXTI->PR=1<<4; //清除LINE4上的中断标志位
}
简述:
每个IO口都可以作为外部中断,
但是只有4个配置寄存器,因此同时只能配置16个IO口作为外部中断;
但是只有7个外部中断服务函数,并且不能共用,因此同时最多只能有7个外部中断。