外部中断与计时器

中断相关的特殊寄存器:

(1)中断允许控制寄存器(IE)--------控制各中断的开放和屏蔽

(2)定时器/计数器控制寄存器(TCON)-------定时器和外部中断的控制

(3)串行口控制寄存器(SCON)-------串行中断的控制

(4)中断优先级控制寄存器(IP)-------设置各中断的优先级

中断配置步骤思路:

  1. 时钟配置(GPIO时钟、AFIO时钟)
  2. GPIO配置(中断功能,映射)
  3. EXTI配置(触发方式,中断使能,)
  4. NVIC配置(优先级分组,中断使能)
  5. 中断服务子程序(判断标志,清除标志)

中断配置步骤实施方式:

1、初始化IO口为输入;

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

GPIO_Init();

2、开启IO口复用时钟

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

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

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

3、设置IO口与中断线的映射关系

void GPIO_EXTILineConfig()

4、初始化线上中断,设置触发条件

EXTI_Init()

5、配置中断分组,并且使能中断

就是配置中断的分组,以及使能,对STM32的中断来说,只有配置了NVIC的设置,并开启才能被执行,否则是不会执行到中断服务函数里面去的。关于NVIC的详细介绍,请参考前面章节。

NVIC_Init()

6、编写中断服务函数

断设置的最后一步,中断服务函数,是必不可少的,如果在代码里面开启了中断,但是没编写中断服务函数,就可能引起硬件错误,从而导致程序崩溃!所以在开启了某个中断后,一定要记得为该中断编写服务函数。

EXTIx_IRQHander()

7、清除中断标准位

EXTI_ClearITPendingBit()

中断代码

//exti.c
#include "exti.h"


void KEY_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA,ENABLE);	//使能复用功能时钟
	
	GPIO_InitTypeDef gpiost;
	gpiost.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_3;
	gpiost.GPIO_Speed = GPIO_Speed_50MHz;
	gpiost.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOE,&gpiost);
	
	gpiost.GPIO_Pin = GPIO_Pin_0;
	gpiost.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(GPIOA,&gpiost);
	
}

void exti_init(void)
{
	EXTI_InitTypeDef extist;
	NVIC_InitTypeDef nvicst;
	KEY_Init();
	
	
	
	
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟
	
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
	extist.EXTI_Line = EXTI_Line3;
	extist.EXTI_Mode = EXTI_Mode_Interrupt;
	extist.EXTI_Trigger = EXTI_Trigger_Falling;
	extist.EXTI_LineCmd = ENABLE;
	EXTI_Init(&extist);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
	extist.EXTI_Line = EXTI_Line4;
	extist.EXTI_Mode = EXTI_Mode_Interrupt;
	extist.EXTI_Trigger = EXTI_Trigger_Falling;
	extist.EXTI_LineCmd = ENABLE;
	EXTI_Init(&extist);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
	extist.EXTI_Line = EXTI_Line0;
	extist.EXTI_Mode = EXTI_Mode_Interrupt;
	extist.EXTI_Trigger = EXTI_Trigger_Rising;
	extist.EXTI_LineCmd = ENABLE;
	EXTI_Init(&extist);
	
	
	nvicst.NVIC_IRQChannel = EXTI3_IRQn;
	nvicst.NVIC_IRQChannelPreemptionPriority = 0x02;
	nvicst.NVIC_IRQChannelSubPriority = 0x02;
	nvicst.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&nvicst);
	
	nvicst.NVIC_IRQChannel = EXTI4_IRQn;
	nvicst.NVIC_IRQChannelPreemptionPriority = 0x02;
	nvicst.NVIC_IRQChannelSubPriority = 0x01;
	nvicst.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&nvicst);
	
	nvicst.NVIC_IRQChannel = EXTI0_IRQn;
	nvicst.NVIC_IRQChannelPreemptionPriority = 0x02;
	nvicst.NVIC_IRQChannelSubPriority = 0x03;
	nvicst.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&nvicst);

}

void EXTI0_IRQHandler(void)
{
	led1 = !led1;
	led2 = !led2;
	EXTI_ClearITPendingBit(EXTI_Line0);
}

void EXTI3_IRQHandler(void)
{
	led1 = !led1;
	EXTI_ClearITPendingBit(EXTI_Line3);
}

void EXTI4_IRQHandler(void)
{
	led2 = !led2;
	EXTI_ClearITPendingBit(EXTI_Line4);
}


//main()函数
int main(void)
{
	Stm32_Clock_Init();
	GPIOB_And_E_Config();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//主优先级0-3共四级,从优先级0-3四级。
	exti_init();
	led1 = 0;
	led2 = 0;

	while(1)
	{
 		//等待外部中断到来		
	}
}

按键中断

按键连续按下

在这里插入图片描述

不支持连续

在这里插入图片描述

二合一

在这里插入图片描述

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值