STM32快速复习(二)外部中断(EXIT)部分

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

说到外部中断,肯定需要讲AFIO
AFIO(Alternate Function I/O,复用功能I/O)
STM32 有很多的内置外设,这些外设的外部引脚都是与 GPIO 复用的。也就是说,一个 GPIO如果可以复用为内置外设的功能引脚,那么当这个 GPIO 作为内置外设使用的时候,就叫做复用。
在STM32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择。
具体复用什么功能需要查看芯片手册。

再讲讲中断
不同芯片中有不同可屏蔽中断通道(中断源),F1系列最多的中断数量,包含EXTI(外部中断)、TIM(定时器)、ADC(模数转换器)、USART(串口)、SPI通信、I2C通信、RTC实时时钟等多个外设

使用NVIC统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级。(要是不设置优先级,一同发送,芯片处理就乱了)

现在继续前一章发的例子。单纯GPIO类似一个枪口,但是,一个完整的设备。一个GPIO口应该不够。(一场战役一支枪应该打不了)
要处理随时突发的事件,此时,优先级的重要就凸显了出来。


一、外部中断触发电路

在这里插入图片描述

在这里插入图片描述

二、使用库函数代码

外部中断处理流程
第一步:配置RCC,把这里设计的外设时钟都打开
第二步:配置GPIO,选择端口为输入模式
第三步:配置AFIO,选择我们这一路用的GPIO
第四步:配置EXTI,选择边沿触发方式,比如上升沿、下降沿、双边沿,选择触发响应方式,比如中断响应、事件响应
第五步:配置NVIC,给中断选择一个合适的优先级

其实,其他的代码,函数,均为工具,这个流程就是外部中断的全部。会用这个流程就行
工具只需会用即可,不用知晓原理

1.AFIO函数

GPIO_PinRemapConfig 【重要】:用于进行引脚重映射,不要随便动SWD调试端口。
//注意参数 GPIO_Remap_SWJ_Disable 慎用!!
GPIO_AFIODeInit :复位AFIO外设,调用该函数会清除AFIO外设的全部配置。
GPIO_EventOutputConfig 【使用不多】:用于配置AFIO的事件输出功能。
GPIO_EventOutputCmd 【使用不多】:用于配置AFIO的事件输出功能。
GPIO_PinLockConfig 用来锁定GPIO配置,调用这个函数参数指定某个引脚,那这个引脚的配置就会被锁定,防止意外更改
GPIO_EXTILineConfig 【重要】:配置AFIO的数据选择寄存器,来选择想要的中断引脚。
复用端口初始化步骤:
(1)GPIO 端口时钟使能
(2)复用的外设时钟使能
(3)端口模式配置。
端口重映射步骤:
(1)GPIO 端口时钟使能
(2)复用的外设时钟使能
(3)使能 AFIO (复用IO) 时钟
(4)开启重映射函数。

举例:串口 1 复用的时候的引脚位 PA9,PA10,同时我们可以将 TX 和 RX 重新映射到管脚 PB6 和 PB7 上面去。
所以重映射我们同样要使能复用功能的时候讲解的 2 个时钟外,还要使能 AFIO 功能时钟,然后要调用重映射函数
请添加图片描述

举例:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	
//使能USART1,GPIOA时钟(初始化)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//(1)GPIO 端口时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//(2)复用的外设时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//(3)使能 AFIO (复用IO) 时钟
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);//(4)开启重映射函数。
//将串口的 TX 和 RX 重映射到管脚 PB6 和 PB7 上面了。

外部中断代码中,AFIO连接EXTI的函数(步骤三)
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//数据选择器

2.EXTI库函数

代码如下(示例):
EXTI_DeInit :将EXTI的配置清除,恢复成上电默认的状态。
EXTI_Init 【常用】:根据结构体的参数配置EXTI外设,常用于初始化EXTI。
EXTI_StructInit :把参数传递的结构体变量赋默认值。
注:上面这个三个函数,基本上所有的外设都有。
EXTI_GenerateSWInterrupt :用于软件触发外部中断,使得相应的中断线产生一次外部中断。只需要外部引脚触发外部中断,则不需要这个函数。
EXTI_GetFlagStatus :获取指定的标志位状态。用于主程序。
EXTI_ClearFlag :清除指定的标志位。用于主程序。
EXTI_GetITStatus :获取中断标志位。用于中断函数。
EXTI_ClearITPendingBit :清除中断挂起标志位。用于中断函数。
上面这四个函数都是对状态寄存器的读写,只不过后两个函数只能读写与中断有关的标志位,并对中断是否允许做出了判断;前两个函数只是一般的读写标志位,没有额外的处理,能
不能触发中断的标志位都能读取。

EXTI_InitTypeDef EXTI_InitStructure; //配置一整个
EXTI_InitStructure.EXTI_Line = EXTI_Line14;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
EXTI_Init(&EXTI_InitStructure);

3.NVIC库函数

NVIC_PriorityGroupConfig 【重要】:用于中断分组,每个工程只允许出现一次。
NVIC_Init 【重要】:根据结构体里面指定的参数初始化NVIC。其中 NVIC_InitTypeDef 包括:
NVIC_IRQChannel :中断通道,选择时看清芯片型号为stm32共有的中断通道以及触发中断的引脚进行选择
NVIC_SetVectorTable 【使用不多】:设置中断向量表。
NVIC_SystemLPConfig 【使用不多】:系统低功耗配置。

举例:,将某个需要外部中断的设备连接到STM32上,进行初始化

//EXIT初始化
//1. 开启GPIO、AFIO的外设时钟(EXTI和NVIC的时钟是一直打开的)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//2. 配置GPIO-PB14上拉输入
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//3. 配置AFIO(库函数在GPIO中)
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//数据选择器
//4. 配置NVIC
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line14;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
EXTI_Init(&EXTI_InitStructure);
//5. 配置NVIC(库函数在misc.h文件中)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断的优先级分组,每个工程只能出现一次!!
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);

中断函数

中断函数(一般放在主函数中)
uint16_t CountSensor_Get(void)
{
return CountSensor_Count;
}
//中断函数的名字从启动文件“stratup_stm32f10x_md”中来
//中断函数都是无参无返回值的
void EXTI15_10_IRQHandler(void)
{
//中断标志位判断
if(EXTI_GetITStatus(EXTI_Line14)==SET)//中断被触发
  {
  CountSensor_Count++;
  EXTI_ClearITPendingBit(EXTI_Line14);//清除中断标志位,中断标志位一定要手动清除
  }
}

上述代码看懂就可,能看懂,能想明白逻辑,就算会外部中断了,其他的都是熟练度了。
中断标志位一定要手动清除 //EXTI_ClearITPendingBit


总结

中断函数的名字从启动文件“stratup_stm32f10x_md”中来,并且中断函数都是无参无返回值的。

很浅很浅的知识,上班现在一直用不到这些代码,基本上要全忘了,所以用于复习。
我觉的,看懂中间的逻辑,看懂实例。然后在不看实例,光看原理图的情况下,参考标准库函数能写出来,基本上就够用了。

  • 26
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值