stm32外部中断系列

1.中断组简介

STM32 将中断分为 5 个组,组 0 ~ 4。该分组的设置是由 SCB->AIRCR 寄存器的 bit10 ~ 8 来定义的。
在这里插入图片描述
在这里插入图片描述
通过这个表,我们就可以清楚的看到组 0~4 对应的配置关系,例如组设置为 3,那么此时所有的 60 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是响应优先级。每个中断,你可以设置抢占优先级为 0 ~ 7,响应优先级为 1 或 0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。

第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。
举例:假定设置中断优先级组为 2,然后设置中断 3(RTC 中断)的抢占优先级为 2,响应优先级为 1。中断 6(外部中断 0)的抢占优先级为 3,响应优先级为 0。中断 7(外部中断 1)的抢占优先级为 2,响应优先级为 0。那么这 3 个中断的优先级顺序为:中断 7>中断 3>中断 6。
上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互
打断!

2.NVIC控制器结构体成员

NVIC_InitTypeDef 结构体中间有四个成员变量,这四个成员变量的作用是:

NVIC_IRQChannel:
定义初始化的是哪个中断,这个我们可以在 stm32f10x.h 中找到每个中断对应的名字。例如 USART1_IRQn。
NVIC_IRQChannelPreemptionPriority:
定义这个中断的抢占优先级别。
NVIC_IRQChannelSubPriority:
定义这个中断的子优先级别。
NVIC_IRQChannelCmd:
该中断是否使能。

3外部中断控制器结构体成员


typedef struct
{
  uint32_t EXTI_Line;               /*!< Specifies the EXTI lines to be enabled or disabled.
                                         This parameter can be any combination of @ref EXTI_Lines */
   
  EXTIMode_TypeDef EXTI_Mode;       /*!< Specifies the mode for the EXTI lines.
                                         This parameter can be a value of @ref EXTIMode_TypeDef */

  EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
                                         This parameter can be a value of @ref EXTIMode_TypeDef */

  FunctionalState EXTI_LineCmd;     /*!< Specifies the new state of the selected EXTI lines.
                                         This parameter can be set either to ENABLE or DISABLE */ 
}EXTI_InitTypeDef;


4.外部中断简介

STM32 的每个 IO 都可以作为外部中断的中断输入口。STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的19 个外部中断为:
线 0~15:对应外部 IO 口的输入中断。
线 16:连接到 PVD 输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件。

STM32 供 IO 口使用的中断线只有 16 个,但是 STM32 的 IO 口却远远不止 16 个,那么 STM32 是怎么把 16 个中断线和 IO 口一一对应起来的呢?
GPIO 的管脚 GPIOx.0 ~ GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 0~15。这样每个中
断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。

5.外部中断相关函数

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); //确定端口与中断线映射关系

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct); //初始化中断线,触发方式
typedef struct
{
uint32_t EXTI_Line; //指定要配置的中断线

EXTIMode_TypeDef EXTI_Mode; //模式:事件or中断

EXTITrigger_TypeDef EXTI_Trigger; //触发方式:上升沿/下降沿/双沿

FunctionalState EXTI_LineCmd; //是否使能
}EXTI_InitTypeDef;

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); //判断中断线中断状态是否发生

void EXTI_ClearITPendingBit(uint32_t EXTI_Line); //清楚中断线上的中断标志位

6.实现步骤

1.先打开gpio时钟和AFIO复用时钟
2.打开gpio和中断组映射
3.串口中断组的选择
4.gpio结构体配置与初始化
4.用外部中断的如gpio要配置exti外部中断与初始化
5.外部中断控制器结构体配置与初始化
中断线控制器结构体配置与初始化
6.编写中断服务函数
说明:中断服务函数中多次EXTI_GetITStatus判断是否发生中断,if和清除中断标志位配合写,避免在执行完中断前发生下一次中断

附上代码
.c文件

#include "stm32f10x.h"
#include "exti.h"

void exti_init(void)//中断io和前面配置的shake复用
{

	GPIO_InitTypeDef shake_init;//gpio结构体变量名
	EXTI_InitTypeDef exti_init;//外部中断结构体变量名
	NVIC_InitTypeDef nvic_init;//中断控制器结构体变量名
	
	
	

//1.打开gpioA时钟
	
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);


//2.打开gpio中断线映射关系
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);


	//3.配置中断组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

//4.配置gpioA结构体
	
	
	shake_init.GPIO_Pin  = GPIO_Pin_1;
	shake_init.GPIO_Speed= GPIO_Speed_10MHz;
	shake_init.GPIO_Mode = GPIO_Mode_IPD;
	//gpioA初始化
	GPIO_Init(GPIOA,  &shake_init);


//5.配置exti外部中断结构体与初始化
exti_init.EXTI_Line		=EXTI_Line1;
exti_init.EXTI_Mode		=EXTI_Mode_Interrupt;
exti_init.EXTI_Trigger=EXTI_Trigger_Falling;
exti_init.EXTI_LineCmd=ENABLE;


EXTI_Init(&exti_init);
//6.配置NICV中断控制器与初始化
nvic_init.NVIC_IRQChannel										=EXTI1_IRQn;//中断通道
nvic_init.NVIC_IRQChannelPreemptionPriority =1;//抢占优先级

nvic_init.NVIC_IRQChannelSubPriority				=1;//子优先级
nvic_init.NVIC_IRQChannelCmd								=ENABLE;

NVIC_Init(&nvic_init);//初始化


}


main函数的中断服务函数

void XTI1_IRQHandler(void)//中断函数配置
{
	if(EXTI_GetITStatus(EXTI_Line1)!= RESET)//判断是否法发生中断
	{
	GPIO_ResetBits(GPIOA,GPIO_Pin_3);//拉低函数,将3电平拉低,初始化继电器为关闭状态
	delay(1000);
	GPIO_SetBits(GPIOA,GPIO_Pin_3);//拉高函数,将A3电平拉高

	}
	EXTI_ClearFlag(EXTI_Line1);//清除中断标志位

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打酱油的;

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值