外部中断实验
通常来说,外部中断可以理解为是通过一个独立按钮,发送一个中断信号,后发生一系列活动。
外部中断实验就是在
独立按键实验
的基础上,添加
外部中断模块
而实现的。
EXTI
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line4; //中断线的标号,取值范围为EXTI_Line0~EXTI_Line15
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式,可选值为中断EXTI_Mode_Interrupt和事件 EXTI_Mode_Event
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //中断触发方式,下降沿触发 EXTI_Trigger_Falling,上升沿触发 EXTI_Trigger_Rising,或者任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断线
EXTI_Init(&EXTI_InitStructure); //根据 EXTI_InitStruct 中指定的
//参数初始化外设 EXTI 寄存器
从定义可以看出,有 4 个参数需要设置。
第一个参数是中断线的标号,取值范围为
EXTI_Line0~EXTI_Line15
。也就是说,这个函数配置的是某个中断线上的中断参数。
第二个参数是中断模式,可选值
中断 EXTI_Mode_Interrupt
和事件EXTI_Mode_Event。
第三个参数是触发方式,可以是
下降沿触发 EXTI_Trigger_Falling,
上升沿触发 EXTI_Trigger_Rising,
任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling。
最后一个参数就是使能中断线了。
NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//使能按键外部中断通道线2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //外部中断通道使能
NVIC_Init(&NVIC_InitStructure);//根据上面指定的参数初始化NVIC寄存器 中断优先级分组初始化
中断优先级设置的步骤:
-
系统运行开始的时候设置中断分组。确定组号,也就是确定
抢占优先级
和
子优先级
的
分配位数
。调用函数为
NVIC_PriorityGroupConfig()
; -
设置所用到的中断的中断优先级别。对每个中断调用函数为
NVIC_Init()
;
中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中
断线 10-15 共用中断函数 EXTI15_10_IRQHandler。在编写中断服务函数的时候会经常使用到两
个函数,第一个函数是判断某个中断线上的中断是否发生(标志位是否置位):
一共16条中断线,对应6个中断函数
外部中断的对应关系
GPIOA_0~GPIOG_0————中断线 0对应一个中断函数EXTI0_IRQHandler
GPIOA_1~GPIOG_1————中断线 1对应一个中断函数EXTI1_IRQHandler
GPIOA_2~GPIOG_2————中断线 2对应一个中断函数EXTI2_IRQHandler
GPIOA_3~GPIOG_3————中断线 3对应一个中断函数EXTI3_IRQHandler
GPIOA_4~GPIOG_4————中断线 4对应一个中断函数EXTI4_IRQHandler
GPIOA_5~GPIOG_5————中断线5
GPIOA_6~GPIOG_6————中断线6
GPIOA_7~GPIOG_7————中断线7————中断线5-9 共用中断函数 EXTI9_5_IRQHandler
GPIOA_8~GPIOG_8————中断线8
GPIOA_9~GPIOG_9————中断线9
GPIOA_10~GPIOG_10————中断线10
GPIOA_11~GPIOG_11————中断线11
GPIOA_12~GPIOG_12————中断线12
GPIOA_13~GPIOG_13————中断线13————中断线10-15 共用中断函数 EXTI15_10_IRQHandler
GPIOA_14~GPIOG_14————中断线14
GPIOA_15~GPIOG_15————中断线15
常用的中断服务函数格式为:
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2)!=RESET)//判断某个线上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line2);//清除 LINE 上的中断标志位
}
}
使用 IO 口外部中断的一般步骤:
1)初始化 IO 口为输入。
2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。
3)初始化线上中断,设置触发条件等。
4)配置中断分组(NVIC),并使能中断。
5)编写中断服务函数。
实验目的
PC5按键KEY0 控制 DS0,按一次亮,再按一次,就灭。
PA15按键KEY1 控制 DS1,按一次亮,再按一次,就灭。。
PA0按键WK_UP 按键则同时控制 DS0 和 DS1,按一次,他们的状态就翻转一次。
实验过程
硬件部分
本实验用到的硬件资源有:
1) 指示灯 DS0、DS1
2) 3 个按键:KEY0、KEY1 和 KEY_UP。
DS0、DS1 和 STM32 的连接在上一章已经介绍了,在 MiniSTM32 开发板上的按键 KEY0连接在 PC5 上、KEY1 连接在 PA15 上、WK_UP 连接在 PA0 上。
这里需要注意的是:KEY0 和 KEY1 是低电平有效的,而 WK_UP 是高电平有效的,除了
KEY1 有上拉电阻(与 JTDI 共用),其他两个都没有上下拉电阻,所以,需要在 STM32 内部设
置上下拉。
软件部分