STM32外部中断函数
在外部中端的 exti.h 文件中
#ifndef _EXTI_H
#define _EXTI_H
#include "stm32f10x.h"
void EXTIX_Init(void);
#endif
在外部中端的 exti.c 文件中
#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
#include "beep.h"
//外部中断 0 服务程序
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
KEY_Init(); //①按键端口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //②使能 AFIO 时钟
//GPIOE.3 中断线以及中断初始化配置,下降沿触发
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);//③
EXTI_InitStructure.EXTI_Line=EXTI_Line3;
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_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //使能按键外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//⑤初始化 NVIC
}
//⑥外部中断 3 服务程序
void EXTI3_IRQHandler(void)
{
delay_ms(10);//消抖
if(KEY1==0) //按键 KEY1
{
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE3 上的中断标志位
//产生中断后,必须要清楚标志位,以便下一次中断的进行。
}
接下来我们看看 main.c 里面里面的内容:
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "exti.h"
#include "beep.h"
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置 NVIC 中断分组 2
uart_init(.115200); //串口初始化波特率为 115200
LED_Init(); //初始化与 LED 连接的硬件接口
BEEP_Init(); //初始化蜂鸣器端口
KEY_Init(); //初始化与按键连接的硬件接口
EXTIX_Init(); //外部中断初始化
LED0=0; //点亮 LED0
while(1)
{
printf("OK\r\n");//打印 OK
delay_ms(1000);
}
}
上面的是代码执行操作,这里解释一下,要做一个外部中断函数,
需要准备哪些。
1:初始化IO口为输入
GPIO_Init();
KEY_Init(); //在KEY_Init(); 中初始化输入的IO口了
2:开启IO口复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
3:设置IO口与中断线的的映射关系
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
4:初始化线上中断,设置触发条件等
NVIC_Init(&NVIC_InitStructure);//⑤初始化 NVIC
//中断优先级的设置
//设置中断通道
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
//设置抢占优先级为2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
//设置子优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
//使能IRQ通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//在主函数中main.c里面设置分组为2
//两个抢占优先级两个响应优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
5:编写中断分组(NVIC),并使能中断。
EXTI_Init(&EXTI_InitStructure);
//配置IO口与中断线的映射关系
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
//指定配置的中断线3
EXTI_InitStructure.EXTI_Line=EXTI_Line3;
//模式事件或者中断,这里采用中断
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//触发方式有上升沿/下降沿/双边沿。这里采用下降沿触发。
//解释一下为什么采用下降沿触发,PE3与地相连,就是低电平有效
//所以采用下降沿触发
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
//使能中断
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
6:编写中断服务函数。
7:清除中断标志位。
//中断服务函数
void EXTI3_IRQHandler(void)
{
delay_ms(10);//消抖
if(KEY1==0) //按键 KEY1
{
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE3 上的中断标志位
//产生中断后,必须要清楚标志位,以便下一次中断的进行。
}
主函数main.c
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "exti.h"
#include "beep.h"
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //初始化与LED连接的硬件接口
BEEP_Init(); //初始化蜂鸣器端口
KEY_Init(); //初始化与按键连接的硬件接口
EXTIX_Init(); //外部中断初始化
LED0=0; //点亮LED0
while(1)
{
printf("OK\r\n");
delay_ms(1000);
}
}
来源:CSDN
作者:vx adc9710
链接:https://blog.csdn.net/qq_43853213/article/details/104694617