STM32F103 外部中断 GPIO
STM32F103的外部中断有多少呢?
如何对STM32F103的外部中断进行初始化呢?
STM32F103的外部中断要怎样去使用呢?
回帖(1)
2022-3-1 14:01:32
stm32每个IO口都可以作为外部中断输入口。F103支持共19个外部中断/事件请求。每个中断设有状态位,有独立的触发和屏蔽装置。STM32F103的19个外部中断为:
线0~15:对应IO口的输入中断
线16:连接到PVD输出
线17:连接到RTC时钟事件
线18:连接到USB唤醒事件
中断线与GPIO的映射
GPIO 的管脚 GPIOx.0~GPIOx.15(x=A,B,C,D,EF,G)分别对应中断线 0~15。这样每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、 GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到一个IO口上,需要配置决定具体映射到哪个IO口。
通过函数 GPIO_EXTILineConfig() 配置GPIO与中断线的映射关系:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
这句代码将 中断线2 与 GPIOE 映射起来,显然就是GPIOE.2与EXTI2中断线连接了.
外部中断的初始化
外部中断的初始化是通过函数 EXTI_Init() 实现的。配置过程与GPIO配置类似。以下是使用范例
EXTI_InitTypeDef EXTI_InitStructure; //实例化对象
EXTI_InitStructure.EXTI_Line=EXTI_Line4; //指定中断线4
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能
EXTI_Init(&EXTI_InitStructure); //根据 EXTI_InitStruct 中指定的参数初始化外设EXTI寄存器上
既然是外部中断,涉及到中断就要设置NVIC中断优先级,这个不赘述了直接贴范例
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //使能按键外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //响应优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //中断优先级分组初始化
当然不能忘了在main()中进行中断总的分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置 NVIC 中断分组 2:2
中断服务函数
中断服务函数的名字是事先定义好的,共有6个,分别为:
EXPORT EXTI0_IRQHandler
EXPORT EXTI1_IRQHandler
EXPORT EXTI2_IRQHandler
EXPORT EXTI3_IRQHandler
EXPORT EXTI4_IRQHandler
EXPORT EXTI9_5_IRQHandler
EXPORT EXTI15_10_IRQHandler
中断线0~4每条线对应一个中断函数
中断线5~9共用中断函数 EXTI9_5_IRQHandler
中断线10~15共用中断函数 EXTI15_10_IRQHandler
编写中断服务函数时常用到下面两个函数
- 判断某个中断线上的中断是否发生
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
- 清除某个中断线上的中断标志位
void EXTI_ClearITPendingBit(uint32_t EXTI_Line); 这个函数一般用在中断服务函数结束之前,清除中断的标志位
常用的中断服务函数格式为:
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
}
}
外部中断使用总结
使用IO口外部中断的一般步骤:(1~5步可以写在同一个函数中直接初始化好)
- 初始化IO口作为输入
......(将要用到的GPIO进行相应的初始化,这里不赘述了)
- 开启AFIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO时钟
- 设置IO口与中断线的映射关系
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2); //将GPIOE.2作为外部中断
- 初始化线上中断,设置触发条件等
EXTI_InitTypeDef EXTI_InitStructure; //实例化对象
EXTI_InitStructure.EXTI_Line=EXTI_Line4; //指定中断线4
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能
EXTI_Init(&EXTI_InitStructure); //根据指定的参数初始化外设EXTI寄存器
- 配置中断分组(NVIC),并使能中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //使能按键外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
- 编写中断服务函数
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
}
}
stm32每个IO口都可以作为外部中断输入口。F103支持共19个外部中断/事件请求。每个中断设有状态位,有独立的触发和屏蔽装置。STM32F103的19个外部中断为:
线0~15:对应IO口的输入中断
线16:连接到PVD输出
线17:连接到RTC时钟事件
线18:连接到USB唤醒事件
中断线与GPIO的映射
GPIO 的管脚 GPIOx.0~GPIOx.15(x=A,B,C,D,EF,G)分别对应中断线 0~15。这样每个中断线对应了最多 7 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、 GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到一个IO口上,需要配置决定具体映射到哪个IO口。
通过函数 GPIO_EXTILineConfig() 配置GPIO与中断线的映射关系:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
这句代码将 中断线2 与 GPIOE 映射起来,显然就是GPIOE.2与EXTI2中断线连接了.
外部中断的初始化
外部中断的初始化是通过函数 EXTI_Init() 实现的。配置过程与GPIO配置类似。以下是使用范例
EXTI_InitTypeDef EXTI_InitStructure; //实例化对象
EXTI_InitStructure.EXTI_Line=EXTI_Line4; //指定中断线4
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能
EXTI_Init(&EXTI_InitStructure); //根据 EXTI_InitStruct 中指定的参数初始化外设EXTI寄存器上
既然是外部中断,涉及到中断就要设置NVIC中断优先级,这个不赘述了直接贴范例
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //使能按键外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //响应优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //中断优先级分组初始化
当然不能忘了在main()中进行中断总的分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置 NVIC 中断分组 2:2
中断服务函数
中断服务函数的名字是事先定义好的,共有6个,分别为:
EXPORT EXTI0_IRQHandler
EXPORT EXTI1_IRQHandler
EXPORT EXTI2_IRQHandler
EXPORT EXTI3_IRQHandler
EXPORT EXTI4_IRQHandler
EXPORT EXTI9_5_IRQHandler
EXPORT EXTI15_10_IRQHandler
中断线0~4每条线对应一个中断函数
中断线5~9共用中断函数 EXTI9_5_IRQHandler
中断线10~15共用中断函数 EXTI15_10_IRQHandler
编写中断服务函数时常用到下面两个函数
- 判断某个中断线上的中断是否发生
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
- 清除某个中断线上的中断标志位
void EXTI_ClearITPendingBit(uint32_t EXTI_Line); 这个函数一般用在中断服务函数结束之前,清除中断的标志位
常用的中断服务函数格式为:
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
}
}
外部中断使用总结
使用IO口外部中断的一般步骤:(1~5步可以写在同一个函数中直接初始化好)
- 初始化IO口作为输入
......(将要用到的GPIO进行相应的初始化,这里不赘述了)
- 开启AFIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO时钟
- 设置IO口与中断线的映射关系
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2); //将GPIOE.2作为外部中断
- 初始化线上中断,设置触发条件等
EXTI_InitTypeDef EXTI_InitStructure; //实例化对象
EXTI_InitStructure.EXTI_Line=EXTI_Line4; //指定中断线4
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能
EXTI_Init(&EXTI_InitStructure); //根据指定的参数初始化外设EXTI寄存器
- 配置中断分组(NVIC),并使能中断
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //使能按键外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
- 编写中断服务函数
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
{
中断逻辑…
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
}
}
举报
更多回帖