历史上的今天
今天是:2024年10月20日(星期日)
2021年10月20日 | stm32专题七:EXTI(二) 外部中断
2021-10-20 来源:eefocus
EXTI外部中断的配置过程:
开启GPIO时钟,初始化要连接的GPIO端口为浮空输入(参考手册);
开启AFIO时钟;
设置IO口与中断线的映射关系,调用函数GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
初始化EXTI,设置触发条件等;
初始化NVIC(注意,有几个中断就要写几次中断源);
编写中断服务函数;
常见的中断服务函数写法:
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET) //判断某个线上的中断是否发生
{
// 中断逻辑…
}
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
}
在野火开发板中,PA0和PC13为按键,这里配置为外部中断,代码如下
bsp_exti.c
#include "bsp_exti.h"
static void EXTI_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
// 先设置中断优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
// 开启了两个中断,所以要再设置中断源
NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_Init(&NVIC_InitStruct);
}
void EXTI_Key_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
/* 配置中断优先级 */
EXTI_NVIC_Config();
/* 初始化GPIO */
// 初始化KEY1
RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK, ENABLE);
GPIO_InitStruct.GPIO_Pin = KEY1_INT_GPIO_PIN;
// 根据手册,应配置为浮空输入
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStruct);
// 初始化KEY2
RCC_APB2PeriphClockCmd(KEY2_INT_GPIO_CLK, ENABLE);
GPIO_InitStruct.GPIO_Pin = KEY2_INT_GPIO_PIN;
// 根据手册,应配置为浮空输入
GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStruct);
/* 初始化EXTI */
// 开启AFIO时钟,因为EXTI由AFIO控制
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// 选择GPIO输入线为PA0,对应着AFIO_EXTICR
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
// 这里的EXTI输入线只是为了把相应的位写入EXTI相关寄存器
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);
EXTI_InitStruct.EXTI_Line = EXTI_Line13;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
}
bsp_exti.h
#ifndef __BSP_EXTI_H
#define __BSP_EXTI_H
#include "stm32f10x.h"
#define KEY1_INT_GPIO_PIN GPIO_Pin_0
#define KEY1_INT_GPIO_PORT GPIOA
#define KEY1_INT_GPIO_CLK RCC_APB2Periph_GPIOA
#define KEY2_INT_GPIO_PIN GPIO_Pin_13
#define KEY2_INT_GPIO_PORT GPIOC
#define KEY2_INT_GPIO_CLK RCC_APB2Periph_GPIOC
static void EXTI_NVIC_Config(void);
void EXTI_Key_Config(void);
#endif /* __BSP_EXTI_H */
接下来看中断服务函数stm32f10x_it.c
void EXTI0_IRQHandler(void)
{
// 判断是否发生中断
// 与函数FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);功能相同
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
LED_R_TOGGLE;
}
// 清除标志位,往EXTI_PR寄存器写1,与函数void EXTI_ClearFlag(uint32_t EXTI_Line)功能相同
// 之所有一个功能有两个一样的函数,是为了兼容旧的固件库
EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI15_10_IRQHandler(void)
{
// 判断是否发生中断
// 与函数FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);功能相同
if (EXTI_GetITStatus(EXTI_Line13) != RESET)
{
LED_B_TOGGLE;
}
// 清除标志位,往EXTI_PR寄存器写1,与函数void EXTI_ClearFlag(uint32_t EXTI_Line)功能相同
// 之所有一个功能有两个一样的函数,是为了兼容旧的固件库
EXTI_ClearITPendingBit(EXTI_Line13);
}
有个问题,就是如果PA0 PB0 PC0都连接到EXTI0输入线上,怎么判断某次中断具体来自于哪一个呢?解决的办法就是,在中断服务函数中,读IO口的引脚电平,也就是IDR输入数据寄存器,通过比较几个GPIO端口的IDR来判断,具体如下
{
// 判断是否发生中断
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
// 中断来自于PA0,同理
if (GPIOA->IDR & GPIO_Pin_0 == GPIO_Pin_0)
{
LED_R_TOGGLE;
}
}
// 清除标志位,往EXTI_PR寄存器写1
EXTI_ClearITPendingBit(EXTI_Line0);
}
最后在主函数中调用
main.c
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_exti.h"
void delay(uint32_t count);
int main(void)
{
LED_GPIO_Config();
EXTI_Key_Config();
while (1)
{
}
}
void delay(uint32_t count)
{
for (; count != 0; count--);
}
史海拾趣
|
最近用WDK7600编译驱动时发现会出现一个Warning.但并不产生.wrn文件,Prefast里也没有任何警告.查了半天发现build时不带任何参数,即在没有编译任何文件的情况下也出现1个Warning.请问哪位大师知道是怎么会事?这到底是个什么鬼Warning? … 查看全部问答> |
|
为何在驱动中定义char rspBuf[102400]就会出错啊? error lnk1120:unresolved external symbol _chkstk referenced in fuction XXX 注释掉char rspBuf[102400]就没有错误了。… 查看全部问答> |
|
在Window XP下对U盘中一个相同的文件进行两组操作 1、将该文件拷贝到硬盘下 2、在U盘中删除该文件 Windows的提示时间是:操作1对应时间是55s,而操作2对应时间是8min。虽然Windows的提示时间不是很准确,但是明显感觉2操作的时间远长于1操作 请 ...… 查看全部问答> |
|
2012 ARM嵌入式开发应用研讨会,PDF 资料,上午是对 ARM 生态环境系统的一个介绍,下午有 Freescale ,NXP,ST,Fujitsu Cortex-Mx 单片机的介绍。 … 查看全部问答> |
|
中国物联网产业发展要耐得住寂寞 切忌过分乐观孤注一掷 核心提示: 从目前物联网产业发展来看,物联网产业的推动主要还是国有大中型企业。其产业发展的核心还是致力于智慧城市建设相关领域,主体还是以三大运营商为核心,而智慧城市建设的核心,大 ...… 查看全部问答> |




