基于标准库的STM32的外部中断EXTI

发布于:2024-06-02 ⋅ 阅读:(165) ⋅ 点赞:(0)

        毕设已经告一段落了,接下来准备开始整理一下毕设中用到的知识与技术细节,今天整理的是STM32从编码器获取数据的方式-----外部中断(EXTI):

外部中断分为四个硬件相关外设,GPIO/AFIO/EXTI/NVIC(EXTI/NVIC不需要开启时钟)

1.RCC开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//GPIOB为APB2的外设

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
2.配置GPIO

方式如我之前写的《STM32标准库编译流程》http://t.csdnimg.cn/0UkGa所示,代码如下:

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;//查阅手册可知外部中断为上拉模式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOE,&GPIO_InitStructure);
3.配置AFIO

进入GPIO库函数,找到void GPIO_AFIODeInit(void)函数,该函数负责将AFIO复位;

GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
GPIO_EventOutputCmd(FunctionalState NewState);用以配置AFIO事件输出功能。

GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);用以配置AFIO的数据选择器,用来选择想要的中断引脚。

那么配置中断的方法如下:

GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource14);

大概的目的就是选择一个引脚GPIOE1用来接收中断信号,这样GPIOE1上的电平中断信号就可以通过AFIO传入EXTI中了,接下来配置EXTI:

4.配置EXTI

进入EXTI库函数,EXTI相关的库函数如下:

158行的作用是复位,159是根据参数配置外设(这就是所需的函数),160将参数中的结构体变为默认值,161软件触发外部中断,164的作用是判断中断类型,165作用是清除中断标志位。

则初始化代码如下:

EXTI_InitTypeDef EXTI_InitStruct;//配置结构体参数
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;//分为event和interrupt,中断,所以选择
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;//触发方式
EXTI_InitStruct.EXTI_Line=EXTI_Line14;//配置中断线,引脚为GPIOE14所以选择14
EXTI_InitStruct.EXTI_LineCmd=ENABLE;//中断线的状态,分为ENABLE/DISABLE
void EXTI_Init(& EXTI_InitStruct);
5.配置NVIC

其为内部外设,所以他的库函数在misc文件中,找到196行,具体函数如下:

196的作用是指定中断的分组,197的作用是初始化,其他的暂不作了解

则配置方式如下:

NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2);//抢占与相应的比例,具体见下图:
NVIC_InitTypeDef NVIC_InitStruct;
 NVIC_InitStruct.NVIC_IRQChannel=EXTI15_10_IRQn;
 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
 NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//使用优先级
 NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(& NVIC_InitStruct);

值得注意的是,NVIC_InitStruct.NVIC_IRQChannel这个参数若引脚为10-15才为上述参数,若不是,则选择EXTIX_IRQn(X为引脚编号)

6.中断响应后执行的函数

该函数名为固定的,查找方法如下:

1.找到中断通道,本文中的是EXTI15_10_IRQn。

2.找到启动文件,即start中的startup_stm32f10x_md.s

3.找到中断向量表(大概在119行),在找到对应的函数名即可。

void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line14)==SET)//判断是否是自己想要的中断,使用前文提到的函数
{
 //写函数的功能
EXTI_ClearITPendingBit(EXTI_Line14)//清除中断标志位,否则退出后又会返回到该函数
}
}

编写完成后,若E14引脚出现电平下降,则会中断其他函数,来执行EXTI15_10_IRQHandler函数

注:主函数中只需初始化外部中断即可,因为EXTI15_10_IRQHandler函数是库中自带的只需要声明即可。

初始化函数整体如下:

int EXIT_init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//GPIOB为APB2的外设
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;//查阅手册可知外部中断为上拉模式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOE,&GPIO_InitStructure);
	
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource14);
	
EXTI_InitTypeDef EXTI_InitStruct;//配置结构体参数
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;//分为event和interrupt,中断,所以选择
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;//触发方式
EXTI_InitStruct.EXTI_Line=EXTI_Line14;//配置中断线,引脚为GPIOE14所以选择14
EXTI_InitStruct.EXTI_LineCmd=ENABLE;//中断线的状态,分为ENABLE/DISABLE
EXTI_Init(&EXTI_InitStruct);
	
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2);//抢占与相应的比例,具体见下图:
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//使用优先级
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}


网站公告

今日签到

点亮在社区的每一天
去签到