跟着战舰V3 资料盘里学习,关于中断的练习,就是用中断控制按键点灯,很简单的程序,且有例程,可是我的还是出了些问题:
外部中断和IO的对应关系设置:“STM32F103 的 EXTI 控制器支持 19 个外部中断/事件请求:
STM32F103 的19 个外部中断为:
线 0~15:对应外部 IO口的输入中断。
线 16:连接到 PVD输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件。
外部 IO 口的中断,需要一个寄存器配置,也就是 IO 复用里的外部中断配置寄存器 EXTICR。这是因为 STM32 任何一个 IO 口都可以配置成中断输入口,但是 IO 口的数目远大于中断线数(16 个)。于是 STM32 就这样设计,GPIOA~GPIOG 的[15:0]分别对应中断线 15~0。这样每个中断线对应了最多 7 个 IO 口,以线 0为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到1个IO口上,这样就需要EXTICR来决定对应的中断线配置到哪个GPIO上了。” 我的理解:断口几就只能对应线几,比如GPIOC4就只能对应中断线4,同时也就只能使用中断4的中断函数。“STM32F1的外部中断0~4都有单独的中断服务函数,但是从5开始,他们就没有单独的服务函数了,而是多个中断共用一个服务函数,比如外部中断 5~9 的中断服务函数为:void EXTI9_5_IRQHandler(void),类似的,void EXTI15_10_IRQHandler(void)就是外部中断 10~15 的中断服务函数。”
主要程序如下:
//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY1==0) //WK_UP按键
{
LED9=!LED9;
}
EXTI->PR=1<<4; //清除LINE4上的中断标志位
}
//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY2==0) //按键KEY2
{
LED10=!LED10;
}
EXTI->PR=1<<0; //清除LINE0上的中断标志位
}
//外部中断2服务程序
void EXTI2_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY3==0) //按键KEY1
{
LED11=!LED11;
}
EXTI->PR=1<<2; //清除LINE2上的中断标志位
}
//外部中断8服务程序
void EXTI9_5_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY4==0) //按键KEY0
{
LED12=!LED12;
}
EXTI->PR=1<<8; //清除LINE8上的中断标志位 这步千万别忘了
}
//外部中断初始化程序
//初始化PC4/PB0/PB2/PE8为中断输入.
void EXTIX_Init(void)
{
KEY_Init();
Ex_NVIC_Config(GPIO_C,4,FTIR); //上升沿触发
Ex_NVIC_Config(GPIO_B,0,FTIR); //下降沿触发
Ex_NVIC_Config(GPIO_B,2,FTIR); //下降沿触发
Ex_NVIC_Config(GPIO_E,8,FTIR); //下降沿触发
MY_NVIC_Init(2,3,EXTI4_IRQn,2); //抢占2,子优先级3,组2
MY_NVIC_Init(2,2,EXTI0_IRQn,2); //抢占2,子优先级2,组2
MY_NVIC_Init(2,1,EXTI2_IRQn,2); //抢占2,子优先级1,组2
MY_NVIC_Init(2,0,EXTI9_5_IRQn,2); //抢占2,子优先级0,组2
}