一、实验目的
理解中断的基本概念。
掌握STM32的中断源及中断优先级。
掌握STM32外部中断技术的基本使用方法。
掌握STM32中断处理程序的编程方法。
二、实验内容
硬件设计原理图如下图1所示:LED的连接在上一节已经介绍过了,在STM32开发板上的按键KEY0是接在PE4上,KEY1是接在PE3上的,KEY2是连在PE2上,WK_UP接在PA0上。
三、实验预备知识
中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大大增加,而且中断的设置也更加复杂。今天就将来探讨一下关于STM32中的中断系统。
ARM Coetex-M3内核共支持256个中断,其中16个内部中断,240个外部中断和可编程的256级中断优先级的设置。STM32目前支持的中断共84个(16个内部+68个外部),还有16级可编程的中断优先级的设置,仅使用中断优先级设置8bit中的高4位。
STM32可支持68个中断通道,已经固定分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但是STM32中只使用4位,高4位有效),每4个通道的8位中断优先级控制字构成一个32位的优先级寄存器。68个通道的优先级控制字至少构成17个32位的优先级寄存器。
STM32的每个IO口都可以作为中断输入,这点很好用。要把IO口作为外部中断输入,有以下几个步骤:
1)初始化IO口为输入。
这一步设置你要作为外部中断输入的IO口的状态,可以设置为上拉/下拉输入,也可以设置为浮空输入,但浮空的时候外部一定要带上拉,或者下拉电阻。否则可能导致中断不停的触发。在干扰较大的地方,就算使用了上拉/下拉,也建议使用外部上拉/下拉电阻,这样可以一定程度防止外部干扰带来的影响。
2)开启IO口复用时钟,设置IO口与中断线的映射关系。
STM32的IO口与中断线的对应关系需要配置外部中断配置寄存器EXTICR,这样我们要先开启复用时钟,然后配置IO口与中断线的对应关系。才能把外部中断与中断线连接起来。
3)开启与该IO口相对的线上中断/事件,设置触发条件。
这一步,我们要配置中断产生的条件,STM32可以配置成上升沿触发,下降沿触发,或者任意电平变化触发,但是不能配置成高电平触发和低电平触发。这里根据自己的实际情况来配置。同时要开启中断线上的中断,这里需要注意的是:如果使用外部中断,并设置该中断的EMR位的话,会引起软件仿真不能跳到中断,而硬件上是可以的。而不设置EMR,软件仿真就可以进入中断服务函数,并且硬件上也是可以的。建议不要配置EMR位。
4)配置中断分组(NVIC),并使能中断。
这一步,我们就是配置中断的分组,以及使能,对STM32的中断来说,只有配置了NVIC的设置,并开启才能被执行,否则是不会执行到中断服务函数里面去的。关于NVIC的详细介绍,请参考前面章节。
5)编写中断服务函数。
这是中断设置的最后一步,中断服务函数,是必不可少的,如果在代码里面开启了中断,但是没编写中断服务函数,就可能引起硬件错误,从而导致程序崩溃!所以在开启了某个中断后,一定要记得为该中断编写服务函数。在中断服务函数里面编写你要执行的中断后的操作。
通过以上几个步骤的设置,我们就可以正常使用外部中断了。
四、实验步骤
- 课下完成作业
按照教材42页-55页,新建工程,命名为“INT+你的学号”,文件夹名和工程名都为“INT+你的学号”(所需的“库函数、HARDWARE和SYSTEM文件夹”在本次实验文件夹中,自已添加即可)。工程建好后,按照教材153页,编写好main()主函数,之后编译。
- 2. 实验室完成
(1) 在课下完成的工程中修改代码,让串口向PC机打印你的“学号姓名”,之后编译、下载到开发板,看现象。
(2) 修改代码实现如下功能
- 系统开机后,LED0,LED1闪两次,蜂鸣器响一声后停止;
- 设置中断优先级分组为组3;
- 按键KEY0抢占优先级为2,响应优先级为0,控制蜂鸣器,按一次,叫一声;
- 按键KEY1抢占优先级为3,响应优先级为1,控制LED0,按一次,LED0亮一次,再按一次LED0灭;
- 按键KEY2抢占优先级为3,响应优先级为1,控制LED1,按一次,LED1闪一次;
- 按键WK_UP抢占优先级为2,响应优先级为1,控制LED0和LED1反转一次;
- 问KEY0、KEY1、KEY2、WK_UP的中断优先级顺序为?
KEY0>WK_UP>KEY1=KEY2 (KEY2 KEY2看谁先按下谁优先)
- KEY0、KEY1、KEY2、WK_UP分别对应的外部中断线为?
KEY0对于外部中断线 EXTI4
KEY1对于外部中断线 EXTI3
KEY2对于外部中断线 EXTI2
WK_UP 对于外部中断线 EXTI0
(3) 完成下列问题
假设KEY3接在PE6上,KEY4接在PE7上,输入方式配置成上拉输入,并分别控制LED0和LED1,每按一次各反转一次。
- 按键初始化代码KEY_Init(void):
答:
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOE,&GPIO_InitStructure);
}
- 中断初始化代码EXTIX_Init(void):
答:
void EXTIX_Init(void)
{
KEY_Init();
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//GPIOE.6 KEY3
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource6);
EXTI_InitStructure.EXTI_Line=EXTI_Line6;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
//优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//GPIOE.7 KEY3
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource6);
EXTI_InitStructure.EXTI_Line=EXTI_Line7;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
//优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
- 中断服务程序函数名为?
答:
void EXTI9_5_IRQHandler(void)
- 编写中断服务程序:
答:
void EXTI9_5_IRQHandler(void)
{
If (EXTI_GetITstatus(EXTI_Line6)==Set)
{
delay_ms(10);
if(KEY6==1)
{
LED0 =!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line6);
}
If (EXTI_GetITstatus(EXTI_Line7)==Set)
{
delay_ms(10);
if(KEY7===1)
{
LED1 =!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line7);
}
}
- 查看“STM32中文参考手册.pdf”第132-134页,根据“其它STM32F10XXX产品向量表”。
ü 说明STM32F10xxx有多少个中断源?
答: 73个
ü EXTI9_5、和EXTI15_10的中断入口地址是多少?
答: 0x0000_009C
0x0000_00E0