机电传动控制 实验4按键中断Word格式文档下载.docx
《机电传动控制 实验4按键中断Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《机电传动控制 实验4按键中断Word格式文档下载.docx(17页珍藏版)》请在冰点文库上搜索。
如图所示,KEY1通过底板接口连接到STM32的PE11,KEY2连接到PE13、KEY3连接到PE15、KEY4连接到PB11;
当没有按键按下时,由于上拉电阻的存在,端口状态为逻辑“1”,当按键按下时端口状态为逻辑“0”。
因此,当按键按下时会产生一个下降沿,当按键断开时会产生一个上升沿。
✧EXTI寄存器描述
中断屏蔽寄存器EXTI_IMR
功能描述:
用来屏蔽/开启来自IO口的中断。
事件屏蔽寄存器EXTI_EMR
屏蔽/开启IO口的事件请求。
上升沿触发选择寄存器EXTI_RTSR
禁止/允许IO口的上升沿触发。
下降沿触发选择寄存器EXTI_FTSR
禁止/允许输入线的下降沿触发。
外部中断配置寄存器1AFIO_EXTICR1
外部中断配置寄存器2AFIO_EXTICR2
外部中断配置寄存器3AFIO_EXTICR3
6.程序流程
1)设置系统时钟
2)初始化LED
3)配置按键1为输入模式
4)配置NVIC嵌套中断寄存器
5)配置外部中断寄存器
6)设置外部中断源
7)编写中断函数
7.实验步骤
1)拷贝“实验3按键检测”工程文件并保存在..\STM32工程文件目录下并命名为“实验4外部中断检测”(实际步骤参考上节实验);
2)新建EXIT.c、EXIT.h,并保存在“实验4外部中断检测”..\bsp目录下。
3)修改工程文件名称并打开工程文件
4)添加源文件到工程(相关操作参照实验1建立工程模板)
5)添加“EXIT.h”到“includes.h“文件
6)修改EXIT.c
#include"
includes.h"
/*外部中断配置函数
KEY1--PE11*/
voidEXIT_Config(void)
{
/*第一步:
配置GPIO为浮空输入模式*/
GPIO_Config();
/*第二步:
配置NVIC寄存器组*/
NVIC_config();
/*第三步:
配置外部中断配置寄存器*/
Interrupt_Config();
}
从上面的一段代码中,我们将配置外部中断按功能分为三个步骤:
首先,既然我们需要通过IO口来检测外部是否有中断发生,那么毫无疑问我们需要将对应的IO配置为输入模式,在这需要注意的是,如果外部IO有上拉电阻,那么我们只需要将其配置为浮空输入即可,如果没有上拉电阻,由于我们要检测的是下降沿中断,所以在没有中断触发的时候我们需要给他一个固定的高电平的状态以便按键按下的时候可以产生一个下降沿,故此时我们需要将其配置成上拉输入;
其次,在Cortex-m3的中断体系中有一个特点,那就是中断可以互相嵌套,所以就涉及到一个抢占优先级与响应优先级的概念,至于什么是抢占优先级,什么是响应优先级以及NVIC寄存器组由于篇幅有限在此不再赘述,感兴趣的同学可自行查阅资料;
最后,我们需要配置EXTI等相关寄存器来配置外部中断,至此中断初始化完毕。
voidGPIO_Config(void)
使能时钟*/
RCC->
APB2ENR|=1<
<
6;
//使能PORTE时钟
0;
//使能AFIO时钟
设置外部中断引脚工作模式
设置PE11为输入模式;
注意如果有外部上拉电阻
则可以设置成浮空输入,
如果没有的话则必须设置
成上拉输入*/
GPIOE->
CRH&
=0xFFFF0FFF;
CRH|=0x00004000;
对于GPIO的配置部分,上一节实验我们已经讲过,在此不再赘述。
voidNVIC_config(void)
NVIC_InitTypeDefNVIC_InitStructure;
/*声明嵌套中断结构体*/
/*中断分组*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/*外部中断15_10*/
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
/*抢占优先级1*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
/*子优先级0*/
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
/*使能*/
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&
NVIC_InitStructure);
/*外部中断源配置*/
代码讲解:
理解stm32的中断,必须要先从stm32的中断优先级分组是怎么回事。
要理解优先级分组,就要先理解什么是先占优先级,和次占优先级。
先占优先级的概念等同于51单片机中的中断。
假设有两中断先后触发,已经在执行的中断先占优先级如果没有后触发的中断先占优先级更高,就会先处理先占优先级高的中断。
也就是说又有较高的先占优先级的中断可以打断先占优先级较低的中断。
这是实现中断嵌套的基础。
次占优先级只在同一先占优先级的中断同时触发时起作用,先占优先级相同,则优先执行次占优先级较高的中断。
次占优先级不会造成中断嵌套。
如果中断的两个优先级都一致,则优先执行位于中断向量表中位置较高的中断。
还需要注意的一点是这里的中断优先级高是指
是指是否更接近0级,0级优先级是最高的。
voidInterrupt_Config(void)
{
AFIO->
EXTICR[2]&
=0x0FFF;
//初始化
EXTICR[2]|=0x4000;
//中断线配置为PE11
//允许外部中断
EXTI->
IMR|=1<
11;
//屏蔽事件请求
EMR&
=~(1<
11);
//禁止上升沿触发
RTSR&
//使能下降沿触发
FTSR|=1<
我们右击EXTICR找到定义的地方,实际上它分别代表寄存器EXTICR1~EXTICR4,所以EXTICR[2]实际表示寄存器EXTICR3
EXTICR3寄存器描述
由于我们配置的是按键1即PE11脚作为中断输入脚,所以我们需要给寄存器赋值0100,转化成16进制数就是0x4,于是就有了下面的一段代码:
//清除之前的配置而不影响其他位的配置
中断屏蔽寄存器(EXTI_IMR)
在此我们需要开启来自线11(PE11)上的中断请求,所以我们需要将对应的控制位置1:
其他的都是一样的,在此不再赘述。
7)打开“stm32f10x_it.c”,添加外部中断处理函数
8)将“includes.h”文件添加到“stm32f10x_it.c”文件中
9)添加“voidEXTI15_10_IRQHandler(void)”函数声明到“stm32f10x_it.h”文件
说明:
声明中断处理函数并不是我们自己随意声明的,如何声明我们必须按照它的启动汇编文件里定义的格式来,我们双击打开此文件:
找到关于中断函数的部分:
从上面的截图部分我们可以看到各个中断函数的具体写法,我们在声明中断的时候必须按照这个格式来做。
10)在“stm32f10x_it.c”文件中编写中断处理函数
voidEXTI15_10_IRQHandler(void)
if(EXTI_GetITStatus(EXTI_Line11)!
=RESET)
{
LED1_OFF;
LED2_OFF;
//清除中断请求标志
EXTI_ClearITPendingBit(EXTI_Line11);
}
}
按键中断触发之后进入中断处理函数,中断完成的功能为将LED1和LED2熄灭,以此来判断是否进入了中断处理函数,由于中断10到中断15共同使用此中断函数,所以在此函数中我们需要通过中断标志位来确定是哪个中断源触发的中断;
EXTI_GetITStatus(EXTI_Line11)函数是stm32库函数之一,我们右击找到与它相关的定义:
我们可以看到,它检测寄存器IMR与PR对应的位的状态来判断是哪个中断触发,具体来讲首先它检测EXTI->
IMR寄存器来判断是否允许线11中断,如果允许再通过检测EXTI->
PR寄存器来判断是否发生了中断触发请求:
在中断处理完毕之后内核不会自动清除中断触发请求,所以需要我们手动调用EXTI_ClearITPendingBit(EXTI_Line11)函数来清除中断请求标志位。
11)修改voidApplication.c
/*
------------------------------------------------------------------------
*函数名称:
voidBoard_Init(void)
*函数功能:
初始化开发板硬件
*输入形参:
无
*返回值:
*/
SystemInit();
//调用延时初始化函数,利用SYSTICK定时器做精确定时
delay_init(72);
//调用LED初始化函数
LED_Init();
EXTI_Config();
在Board_Init()函数之中,我们调用了其他源文件提供的初始化函数,其中就包含了中断初始化函数。
12)修改Application()函数
voidApplication(void)
while
(1)
{
13)修改main.c如下:
intmain(void)
/*硬件初始化*/
Board_Init();
/*应用函数*/
Application();
/*正常情况下不会执行到这一步*/
return0;
14)编译程序无误后通过JTAG下载到板子上并按下复位运行
8.实现现象
按下KEY_1对应的LED_1和LED_2熄灭。
课后思考
外部中断初始化的步骤是什么?