外部中断的设置和一些寄存器的介绍

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1)初始化IO 口为输入。

外部中断输入的IO 口的状态,可以设置为上拉/下拉输入,也可以设置为浮空输入,但浮空的时候外部一定要带上拉,或者下拉电阻。否则可能导致中断不停的触发。在干扰较大的地方,就算使用了上拉/下拉,也建议使用外部上拉/下拉电阻,这样可以一定程度防止外部干扰带来的影响。

①使能IO口的时钟

②清除原来的相应的设置

③设置成上拉输入0x80

④把GPIO_ODR相应的位设置成 1

2)开启IO 口复用时钟,设置IO 口与中断线的映射关系。

STM32 的IO 口与中断线的对应关系需要配置外部中断配置寄存器EXTICR,这样我们要先开启复用时钟,然后配置IO 口与中断线的对应关系。才能把外部中断与中断线连接起来。

①使能复用时钟

RCC_APB1ENR第0位AFIOEN:辅助功能IO时钟使能RCC->APB1ENR |= 1<<0

②设置外部中断配置寄存器(AFIO_EXTICR1)

总共有三个配置寄存器,分别对应着15个中段线。每个寄存器存放四个。如上图。

在设置这些位时仍然2步:

首先:清除原来的设置。AFIO->EXTICR[0]&=~(0x000F<<0); //清除中断线0的原来的设置

然后:设置映射到那个端口。AFIO->EXTICR[0]|=0<<0;//设置引脚为0000也就是A口扩展:事件控制寄存器(AFIO_EVCR)

位7 EVOE:允许事件输出(Event output enable) 位7 该位可由软件读写。当设置该位后,Cortex的EVENTOUT将连接到由PORT[2:0]和PIN[3:0]选定的I/O口。

位6:4PORT[2:0]:端口选择000:选择PA 001:选择PB 010:选择PC 011:选择PD 100:选择PE

位3:0 PIN[3:0]:引脚选择(x=A…E)

0000:选择Px0 0001:选择Px1 0010:选择Px2 0011:选择Px3 0100:选择Px4 0101:选择Px5 0110:选择Px6 0111:选择Px7 1000:选择Px8 1001:选择Px9 1010:选择Px10 1011:选择Px11 1100:选择Px12 1101:选择Px13 1110:选择Px14 1111:选择Px15

3)开启与该IO 口相对的线上中断/事件,设置触发条件

我们要配置中断产生的条件,STM32 可以配置成上升沿触发,下降沿触发,或者任意电平变化触发,但是不能配置成高电平触发和低电平触发。这里根据自己的实际情况来配置,同时要开启中断线上的中断。这里需要注意的是:如果使用外部中断,并设置该中断的EMR、位的话,会引起软件仿真不能跳到中断,而硬件上是可以的。而不设置EMR,软件仿真就可以进入中断服务函数,并且硬件上也是可以的。建议不要配置EMR 位

①配置中断屏蔽寄存器(EXTI_IMR) 的相应中断线设置成 1

被设置成1 也就是开放来自线上的中断请求。

②设置触发方式。上升沿触发选择寄存器(EXTI_RTSR) 下降沿触发选择寄存器(EXTI_FTSR) 直接在相应的触发方式写1 就行了。

扩展:事件屏蔽寄存器(EXTI_EMR)使用如图上面中断屏蔽寄存器

软件中断事件寄存器(EXTI_SWIER) SWIERx: 线x上的软件中断位18:0 当该位为’0’时,写’1’将设置EXTI_PR中相应的挂起位。如果在EXTI_IMR和EXTI_EMR中允许产生该中断,则此时将产生一个中断。

注:通过清除EXTI_PR的对应位(写入’1’),可以清除该位为’0’。

挂起寄存器(EXTI_PR)PRx: 挂起位(Pending bit) 位18:0

0:没有发生触发请求

1:发生了选择的触发请求

当在外部中断线上发生了选择的边沿事件,该位被置’1’。在该位中写入’1’可以清除它,也可以通过改变边沿检测的极性清除。

4)配置中断分组(NVIC),并使能中断

配置中断的分组,以及使能,对 STM32 的中断来说,只有配置了 NVIC的设置,并开启才能被执行,否则是不会执行到中断服务函数里面去的。

//设置NVIC

//NVIC_PreemptionPriority:抢占优先级

//NVIC_SubPriority :响应优先级

//NVIC_Channel :中断编号

//NVIC_Group :中断分组 0~4

//注意优先级不能超过设定的组的范围!否则会有意想不到的错误

//组划分:

//组0:0位抢占优先级,4位响应优先级

//组1:1位抢占优先级,3位响应优先级

//组2:2位抢占优先级,2位响应优先级

//组3:3位抢占优先级,1位响应优先级

//组4:4位抢占优先级,0位响应优先级

//NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先

void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8

NVIC_Channel,u8 NVIC_Group) {

u32 temp;

u8 IPRADDR=NVIC_Channel/4; //每组只能存4个,得到组地址

u8 IPROFFSET=NVIC_Channel%4;//在组内的偏移

IPROFFSET=IPROFFSET*8+4; //得到偏移的确切位置

MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组

temp=NVIC_PreemptionPriority<<(4-NVIC_Group);

temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);

temp&=0xf;//取低四位

if(NVIC_Channel<32)NVIC->ISER[0]|=1<

话,相反操作就OK)

else NVIC->ISER[1]|=1<<(NVIC_Channel-32);

NVIC->IPR[IPRADDR]|=temp<

}

关于终端分组的介绍请参考《中断分组》。

5)编写中断服务函数

中断设置的最后一步,中断服务函数,是必不可少的,如果在代码里面开启了中断,

但是没编写中断服务函数,就可能引起硬件错误,从而导致程序崩溃!所以在开启了某个中

断后,一定要记得为该中断编写服务函数。在中断服务函数里面编写你要执行的中断后的操

作。

这里要强调的是,在中断函数里要注意一下几点:

①是否需要清除中断标志,这个在中断挂起里面相应位写1即可。

②在中断函数里尽量不要写太多的代码,应该使其快速的完成。

③中断处理函数名是固定的,别写错了。

例如:void EXTI4_IRQHandler(void){} 格式一般为void X_IRQHandler(void){}.

而在系统中对应的中段号也要一一对应。

#define WWDG_IRQChannel ((u8)0x00) /* Window WatchDog Interrupt

*/

#define PVD_IRQChannel ((u8)0x01) /* PVD through EXTI Line

detection Interrupt */

相关文档
最新文档