前言
本次我们学习一下STM32关于使用EXTI外部引脚中断的实验展示,主要说明EXTI外部中断的作用,和一些额外的应用场景。本篇博客大部分是自己收集和整理,如有侵权请联系我删除。
本次实验板子使用的是正点原子精英版,芯片是STM32F103ZET6,需要资料可以@我拿取。
交流群:717237739
如果觉得有用点赞关注收藏三连,多谢支持
本博客内容原创,创作不易,转载请注明
————————————————
一 . EXTI 外部中断介绍
1.EXTI主要特性:
2.EXTI作用场景:
二 . EXTI 中断应用框图
在图 EXTI 功能框图中可以看到很多在信号线上打一个斜杠并标注“20”字样(“/20”),这个表示在EXTI控制器内部类似的信号线路有 20 个,这与 EXTI 总共有 20 个中断/事件线时一样的。
EXTI控制器的功能可分为两大部分,一个功能是产生中断,另一个功能是产生事件,这两个功能从硬件上就有所不同。
三. 外部中断/事件线路映像
1.外部中断框图介绍
STM32F1的每个IO都可以作为外部中断输入。
STM32F1的中断控制器支持20个外部中断/事件请求:
EXTI注意事项:
● EXTI线16连接到PVD输出: 电源电压监测,监测电源从电压过低恢复的时候操作。
2.中断服务函数的注意事项
1)是不是16个中断线就可以分配16个中断服务函数呢?
并不是,IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数
3.EXTI支持的触发方式
4. EXTI基本结构
四.EXTI函数和配置过程:
1.实现步骤:
2.结构体成员和参数:
标准库函数对每个外设都建立了一个初始化结构体,比如 EXTI_InitTypeDef,结构体成员用于设置外设工作参数,并由外设初始化配置函数,比如 EXTI_Init() 调用,这些设定参数将会设置外设相应的寄存器,达到配置外设工作环境的目的。
/**@brief EXTI 初始化结构体定义 */
typedef struct
{
uint32_t EXTI_Line; /*!< 中断/事件线 */
EXTIMode_TypeDef EXTI_Mode; /*!< EXTI 模式 */
EXTITrigger_TypeDef EXTI_Trigger; /*!< 触发类型f */
FunctionalState EXTI_LineCmd; /*!< EXTI 使能 */
}EXTI_InitTypeDef;
结构体每个成员参数:
1) EXTI_Line:EXTI 中断/事件线选择。
可选 EXTI0 至 EXTI19。
2) EXTI_Mode:EXTI 模式选择。
可选为产生中断 (EXTI_Mode_Interrupt) 或者产生事件(EXTI_Mode_Event)。
3) EXTI_Trigger:EXTI 边沿触发事件。
可选上升沿触发 (EXTI_Trigger_Rising)、下降沿触发 (EXTI_Trigger_Falling) 或者上升沿和下降沿都触发 ( EXTI_Trigger_Rising_Falling)。
4) EXTI_LineCmd:控制是否使能 EXTI 线。
可选使能 EXTI 线 (ENABLE) 或禁用 (DISABLE)。
2.程序代码:EXTI中断部分
1.AFIO复用IO口
1)AFIO主要用于引脚复用功能的选择和重定义
2)在STM32中,AFIO主要完成两个任务:复用功能引脚重映射、中断引脚选择
3)AFIO库函数
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
进行引脚重映射功能:可以将已经使用的引脚进行重映射,来达到使用该引脚的功能
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
可以选择配置AFIO的数据选择器,来选择我们需要的中断引脚
2.EXTI中断配置
1)初始化 IO 口为输入
代码部分:
//外部中断0服务程序
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
KEY_Init(); // 按键端口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
//GPIOE.3 中断线以及中断初始化配置 下降沿触发 //KEY1
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
EXTI_InitStructure.EXTI_Line=EXTI_Line3; //选择中断线3
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //软件触发
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
//GPIOE.4 中断线以及中断初始化配置 下降沿触发 //KEY0
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
EXTI_InitStructure.EXTI_Line=EXTI_Line4;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
//GPIOA.0 中断线以及中断初始化配置 上升沿触发 PA0 WK_UP
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line=EXTI_Line0; //选择中断线0
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键WK_UP所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //使能按键KEY1所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn; //使能按键KEY0所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}
//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
delay_ms(10);//消抖
if(WK_UP==1) //WK_UP按键
{
BEEP=!BEEP;
}
EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位
}
//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
delay_ms(10);//消抖
if(KEY1==0) //按键KEY1
{
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位
}
void EXTI4_IRQHandler(void)
{
delay_ms(10);//消抖
if(KEY0==0) //按键KEY0
{
LED0=!LED0;
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line4); //清除LINE4上的中断标志位
}
总结:
本篇博客介绍了EXTI外部中断的应用和机制,还有一些基础的注意事项,实现的开发板是正点原子的精英板,代码大同小异,理解了其实并不难,谢谢大家。大家如果对我的博客有疑问或者错误,可以@我修改,大家相互交流。
交流群:717237739
如果觉得有用点赞关注收藏三连,多谢支持
本博客内容原创,创作不易,转载请注明
点赞收藏关注博主,不定期分享单片机知识,互相学习交流。
————————————————