Skip to content Skip to footer

【经验分享】STM32F103:外部中断(EXTI)——原理和程序

一、外部中断(EXTI)—简介

EXTI (External interrupt/event controller)——外部中断/事件控制器。

互联型STM32有20个能够产生事件/中断请求的边沿检测器,STM32F103系列有19个能够产生事件/中断请求的边沿检测器。

每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。

每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求。

二、外部中断(EXTI)—框图

U7QW(4}J]5Q7A4SP`887_ZR.png (110.96 KB, 下载次数: 18)

下载附件

保存到相册

2022-5-3 13:30 上传

三、外部中断(EXTI)—线路映像

通用I/O端口以下图的方式连接到16个外部中断/事件线上:

X$_F]RV$_}B23`0WR)PBG.png (77.15 KB, 下载次数: 14)

下载附件

保存到相册

2022-5-3 13:30 上传

}23LB{Q_WTZ`MTCF)Q1C8Z8.png (27.6 KB, 下载次数: 12)

下载附件

保存到相册

2022-5-3 13:30 上传

四、外部中断(EXTI)—寄存器

从外部中断(EXTI)结构框图可以知道,外部中断功能由六个寄存器配置。

1. 中断屏蔽寄存器(EXTI_IMR)

2HWBB)MWI}Y2YHI57FC@AHP.png (120.55 KB, 下载次数: 14)

下载附件

保存到相册

2022-5-3 13:30 上传

2. 事件屏蔽寄存器(EXTI_EMR)

W$UVLY8X3JZH[N6P85HX7HU.png (118.6 KB, 下载次数: 10)

下载附件

保存到相册

2022-5-3 13:30 上传

3. 上升沿触发选择寄存器(EXTI_RTSR)

ZP)$VBV9@BX8XX6P1{JC.png (193.64 KB, 下载次数: 14)

下载附件

保存到相册

2022-5-3 13:30 上传

4. 下降沿触发选择寄存器(EXTI_FTSR)

C_A%){O`4[MH3AAXNCMO_(1.png (194.8 KB, 下载次数: 13)

下载附件

保存到相册

2022-5-3 13:30 上传

5. 软件中断事件寄存器(EXTI_SWIER)

C_(A`W%{93HSWC{`}J9XBIK.png (150.66 KB, 下载次数: 15)

下载附件

保存到相册

2022-5-3 13:30 上传

6. 挂起寄存器(EXTI_PR)

TI]KVG%TZGZ0}QJ(UJ27J93.png (139.82 KB, 下载次数: 11)

下载附件

保存到相册

2022-5-3 13:30 上传

五、外部中断(EXTI)—配置

1. 外部中断(EXTI)—映射关系

3E495[UXR2WRFZL6Z6%LUR6.png (49.57 KB, 下载次数: 18)

下载附件

保存到相册

2022-5-3 13:30 上传

2. 外部中断(EXTI)—GPIO引脚配置

OP2][U321@PV$C~2[ZQLB.png (60.93 KB, 下载次数: 15)

下载附件

保存到相册

2022-5-3 13:30 上传

由上图可知,外部中断的GPIO引脚可以配置一下三种:GPIO_Mode_IN_FLOATING //浮空输入

GPIO_Mode_IPU //上拉输入

GPIO_Mode_IPD //下拉输入复制代码

3. 外部中断(EXTI)—触发方式

外部中断(EXTI)有三种触发方式:EXTI_Trigger_Rising //上升沿触发

EXTI_Trigger_Falling //下降沿触发

EXTI_Trigger_Rising_Falling //上升沿和下降沿都可以触发复制代码

六、外部中断(EXTI)—程序

外部中断配置程序

void EXTIX_Init(void)

{

EXTI_InitTypeDef EXTI_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

//初始化时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);//使能PORTA,PORTB,PORTC时钟

//初始化GPIO端口

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_4; //PA0,PA4

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //PA0设置成浮空输入,默认下拉

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最高输出速率50MHz

GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_8; //PB6,PB8

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入,默认下拉

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最高输出速率50MHz

GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_14; //PC12,PC14

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置成下拉输入,默认下拉

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最高输出速率50MHz

GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOC

/*GPIOA0中断初始化配置*/

EXTI_ClearITPendingBit(EXTI_Line0); //清除线0 IO口中断清除挂起位(清除中断标志位)

EXTI_InitStructure.EXTI_Line=EXTI_Line0; //中断线选择

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //EXTI为中断模式

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发

EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断

EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); //将GPIOA0挂到中断上

/*GPIOA4中断初始化配置*/

EXTI_ClearITPendingBit(EXTI_Line4); //清除线4 IO口中断清除挂起位(清除中断标志位)

EXTI_InitStructure.EXTI_Line=EXTI_Line4; //中断线选择

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //EXTI为中断模式

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发

EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断

EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource4); //将GPIOA4挂到中断上

/*GPIOB6中断初始化配置*/

EXTI_ClearITPendingBit(EXTI_Line6); //清除线6 IO口中断清除挂起位(清除中断标志位)

EXTI_InitStructure.EXTI_Line=EXTI_Line6; //中断线选择

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //EXTI为中断模式

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//上升沿和下降沿都可以触发

EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断

EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource6); //将GPIOB6挂到中断上

/*GPIOB8中断初始化配置*/

EXTI_ClearITPendingBit(EXTI_Line8); //清除线8 IO口中断清除挂起位(清除中断标志位)

EXTI_InitStructure.EXTI_Line=EXTI_Line8; //中断线选择

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //EXTI为中断模式

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发

EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断

EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource8); //将GPIOB8挂到中断上

/*GPIOC12中断初始化配置*/

EXTI_ClearITPendingBit(EXTI_Line12); //清除线12 IO口中断清除挂起位(清除中断标志位)

EXTI_InitStructure.EXTI_Line=EXTI_Line12; //中断线选择

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //EXTI为中断模式

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发

EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断

EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource12); //将GPIOC12挂到中断上

/*GPIOC14中断初始化配置*/

EXTI_ClearITPendingBit(EXTI_Line14); //清除线14 IO口中断清除挂起位(清除中断标志位)

EXTI_InitStructure.EXTI_Line=EXTI_Line14; //中断线选择

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //EXTI为中断模式

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//上升沿和下降沿都可以触发

EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断

EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource14); //将GPIOC14挂到中断上

/*NVIC初始化配置*/

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //配置NVIC优先级分组为0

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能线0所在的外部中断通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道

NVIC_Init(&NVIC_InitStructure); //初始化外设NVIC寄存器

NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn; //使能线4所在的外部中断通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道

NVIC_Init(&NVIC_InitStructure); //初始化外设NVIC寄存器

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能线9到线5所在的外部中断通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0,

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级1

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道

NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能线15到线10所在的外部中断通道

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道

NVIC_Init(&NVIC_InitStructure);

}复制代码

外部中断服务函数

//外部中断0服务函数

void EXTI0_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line0)!= RESET)//有中断申请

{

/**

其他功能程序

**/

EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位

}

}

//外部中断4服务函数

void EXTI4_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line4)!= RESET)//有中断申请

{

/**

其他功能程序

**/

EXTI_ClearITPendingBit(EXTI_Line4); //清除LINE4上的中断标志位

}

}

//外部中断9_5服务函数

void EXTI9_5_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line6)!= RESET)//有中断申请

{

/**

其他功能程序

**/

EXTI_ClearITPendingBit(EXTI_Line6); //清除LINE6上的中断标志位

}

if(EXTI_GetITStatus(EXTI_Line8)!= RESET)//有中断申请

{

/**

其他功能程序

**/

EXTI_ClearITPendingBit(EXTI_Line8); //清除LINE8上的中断标志位

}

}

//外部中断15_10服务函数

void EXTI15_10_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line12)!= RESET)//有中断申请

{

/**

其他功能程序

**/

EXTI_ClearITPendingBit(EXTI_Line12); //清除LINE12上的中断标志位

}

if(EXTI_GetITStatus(EXTI_Line14)!= RESET)//有中断申请

{

/**

其他功能程序

**/

EXTI_ClearITPendingBit(EXTI_Line14); //清除LINE14上的中断标志位

}

}

复制代码

Copyright © 2088 U20世界杯_u20世界杯葡萄牙 - kwllb.com All Rights Reserved.
友情链接