精华内容
下载资源
问答
  • 外部中断实验代码

    2013-04-15 21:19:15
    在单片机8251上实现的关于外部中断的C51程序,若有误漏请见谅O(∩_∩)O~
  • stm32外部中断实验

    2012-10-14 21:22:59
    stm32外部中断实验代码,适合初学者学习交流使用啊
  • 外部中断实验

    2020-12-06 15:54:37
    外部中断概述 1、 STM32的每个IO都可以作为外部中断输入。 2、 STM32的中断控制器支持19个外部中断/事件请求: 线0~15:对应外部IO口的输入中断。 线16:连接到PVD输出。 线17:连接到RTC闹钟事件。 线18:连接到...

    外部中断概述
    1、 STM32的每个IO都可以作为外部中断输入。
    2、 STM32的中断控制器支持19个外部中断/事件请求:

    • 线0~15:对应外部IO口的输入中断。
    • 线16:连接到PVD输出。
    • 线17:连接到RTC闹钟事件。
    • 线18:连接到USB唤醒事件。
    • 每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。

    思考: STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112),STM32F103RCT6(51),那么中断线怎么跟io口对应呢?请看下图:

    在这里插入图片描述
    由上图可知:
    GPIOx.0映射到EXTI0
    GPIOx.1映射到EXTI1

    GPIOx.15映射到EXTI15

    对于每个中断线,我们可以设置相应的触发方式(上升沿触发,下降沿触发,边沿触发)以及使能,同一时间只能有一个IO口映射到一条中断线,比如:GPIOA.0映射了EXTI0同一时间其他的GPIO就不能映射在EXTI0这条中断线上。

    是不是16个中断线就可以分配16个中断服务函数呢?
    IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数

    在这里插入图片描述

    从表中可以看出,外部中断线5到9分配一个中断向量,共用一个服务函数外部中断线10~15分配一个中断向量,共用一个中断服务函数。

    中断服务函数列表:

    • EXTI0_IRQHandler

    • EXTI1_IRQHandler

    • EXTI2_IRQHandler

    • EXTI3_IRQHandler

    • EXTI4_IRQHandler

    • EXTI9_5_IRQHandler

    • EXTI15_10_IRQHandler

    外部中断常用库函数:

    1void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
       //设置IO口与中断线的映射关系
    	exp:  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
    
    2void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
       //初始化中断线:触发方式等
    
    3、ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
      //判断中断线中断状态,是否发生
    
    4void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
      //清除中断线上的中断标志位
    

    EXTI_Init函数:

    void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)typedef struct
    {
      uint32_t EXTI_Line;   //指定要配置的中断线           
      EXTIMode_TypeDef EXTI_Mode;   //模式:事件 OR中断
      EXTITrigger_TypeDef EXTI_Trigger;//触发方式:上升沿/下降沿/双沿触发
      FunctionalState EXTI_LineCmd;  //使能 OR失能
    }EXTI_InitTypeDef;
    
     EXTI_InitStructure.EXTI_Line=EXTI_Line2;	 
     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
     EXTI_Init(&EXTI_InitStructure);
    

    外部中断的一般配置步骤:

    • 初始化IO口为输入。
    GPIO_Init();
    
    • 开启IO口复用时钟。
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    
    • 设置IO口与中断线的映射关系。
     void GPIO_EXTILineConfig();
    
    • 初始化线上中断,设置触发条件等。
       EXTI_Init();
    
    • 配置中断分组(NVIC),并使能中断。
      NVIC_Init();
    
    • 编写中断服务函数。
     EXTIx_IRQHandler();
    
    • 清除中断标志位
     EXTI_ClearITPendingBit();
    

    外部中断初始化和中断函数部分代码:

    void EXTIX_Init(void)
    {
    	GPIO_InitTypeDef GPIO_InitStrue;
    	EXTI_InitTypeDef EXTI_InitStrue;
    	NVIC_InitTypeDef NVIC_InitStrue;
    	
    	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IPU;
    	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
    	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
    	
    	GPIO_Init(GPIOE,&GPIO_InitStrue);//GPIO初始化
    	
    	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IPD;
    	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_0;
    	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
    	
    	GPIO_Init(GPIOA,&GPIO_InitStrue);//GPIO初始化
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启GPIO复用时钟
    	
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);//设置IO口与中断线的映射关系。
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);//设置IO口与中断线的映射关系。
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);//设置IO口与中断线的映射关系。
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//设置IO口与中断线的映射关系。
    	
    	EXTI_InitStrue.EXTI_Line=EXTI_Line0;
    	EXTI_InitStrue.EXTI_LineCmd=ENABLE;
    	EXTI_InitStrue.EXTI_Mode=EXTI_Mode_Interrupt;
    	EXTI_InitStrue.EXTI_Trigger=EXTI_Trigger_Rising;
    	EXTI_Init(&EXTI_InitStrue);//初始化线上中断,设置触发条件等。
    	
    	EXTI_InitStrue.EXTI_Line=EXTI_Line4;
    	EXTI_InitStrue.EXTI_LineCmd=ENABLE;
    	EXTI_InitStrue.EXTI_Mode=EXTI_Mode_Interrupt;
    	EXTI_InitStrue.EXTI_Trigger=EXTI_Trigger_Falling;
    	EXTI_Init(&EXTI_InitStrue);//初始化线上中断,设置触发条件等。
    	
    	EXTI_InitStrue.EXTI_Line=EXTI_Line2;
    	EXTI_InitStrue.EXTI_LineCmd=ENABLE;
    	EXTI_InitStrue.EXTI_Mode=EXTI_Mode_Interrupt;
    	EXTI_InitStrue.EXTI_Trigger=EXTI_Trigger_Falling;
    	EXTI_Init(&EXTI_InitStrue);//初始化线上中断,设置触发条件等。
    	
    	EXTI_InitStrue.EXTI_Line=EXTI_Line3;
    	EXTI_InitStrue.EXTI_LineCmd=ENABLE;
    	EXTI_InitStrue.EXTI_Mode=EXTI_Mode_Interrupt;
    	EXTI_InitStrue.EXTI_Trigger=EXTI_Trigger_Falling;
    	EXTI_Init(&EXTI_InitStrue);//初始化线上中断,设置触发条件等。
    	
    	NVIC_InitStrue.NVIC_IRQChannel=EXTI4_IRQn;//外部中断通道
    	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
    	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=2;
    	NVIC_InitStrue.NVIC_IRQChannelSubPriority=3;
    	NVIC_Init(&NVIC_InitStrue);//配置中断分组(NVIC),并使能中断。
    	
    	NVIC_InitStrue.NVIC_IRQChannel=EXTI3_IRQn;//外部中断通道
    	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
    	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=2;
    	NVIC_InitStrue.NVIC_IRQChannelSubPriority=2;
    	NVIC_Init(&NVIC_InitStrue);//配置中断分组(NVIC),并使能中断。
    	
    	NVIC_InitStrue.NVIC_IRQChannel=EXTI0_IRQn;//外部中断通道
    	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
    	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=2;
    	NVIC_InitStrue.NVIC_IRQChannelSubPriority=0;
    	NVIC_Init(&NVIC_InitStrue);//配置中断分组(NVIC),并使能中断。
    	
    	NVIC_InitStrue.NVIC_IRQChannel=EXTI2_IRQn;//外部中断通道
    	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
    	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=2;
    	NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;
    	NVIC_Init(&NVIC_InitStrue);//配置中断分组(NVIC),并使能中断。
    }
    
    void EXTI3_IRQHandler(void)
    {
    	delay_ms(100);
    	if(KEY1==0)
    	{
    		LED0=!LED0;
    		LED1=!LED1;
    	}
    	EXTI_ClearITPendingBit(EXTI_Line3);
    }
    
    void EXTI4_IRQHandler(void)
    {
    	delay_ms(100);
    	if(KEY0==0)
    	{
    		LED0=!LED0;
    		LED1=!LED1;
    	}
    	EXTI_ClearITPendingBit(EXTI_Line4);
    }
    
    void EXTI0_IRQHandler(void)
    {
    	delay_ms(100);
    	if(WK_UP==1)
    	{
    		LED0=!LED0;
    		LED1=!LED1;
    	}
    	EXTI_ClearITPendingBit(EXTI_Line0);
    }
    
    void EXTI2_IRQHandler(void)
    {
    	delay_ms(100);
    	if(KEY2==0)
    	{
    		LED0=!LED0;
    		LED1=!LED1;
    	}
    	EXTI_ClearITPendingBit(EXTI_Line2);
    }
    
    展开全文
  • 实验一 外部中断实验

    万次阅读 2019-01-18 11:01:23
    实验一 外部中断实验 一、实验要求 用单次脉冲申请中断,在中断处理程序中对输出信号进行反转。 二、实验目的 1、学习外部中断技术的基本使用方法。 2、学习中断处理程序的编程方法。 三、实验原理 当89C51的...

    实验一 外部中断实验

    一、实验要求

    用单次脉冲申请中断,在中断处理程序中对输出信号进行反转。

    、实验目的

    1、学习外部中断技术的基本使用方法。

    2、学习中断处理程序的编程方法。

    三、实验原理

    当89C51的CPU正在处理某件事情(如正在执行主程序)时,单片机外部或内部发生的某一事件(如外部设备产生的一个电平变化或脉冲跳沿的变化,或者是片内事件的发生,如计数器的计数溢出等)请求CPU迅速去处理,于是CPU暂时中止当前的工作,转到中断服务处理程序处理所发生的事件。中断服务处理完该事件后,再回到原来被终止的地方,继续原来的工作(如继续执行被中断的主程序),这称为中断。

    而外部中断是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时,单片机的中断系统将迫使CPU暂停正在执行的程序,转而去进行中断事件的处理;中断处理完毕后.又返回被中断的程序处,继续执行下去。

    四、实验内容

      单片机的INT0和INT1分别接了两个外部中断,当INT0引脚有中断时,点亮发光二极管D1,当INT1引脚有中断时,点亮发光二极管D2。SW1从高电平变为低电平时,点亮发光二极管D1;SW2从高电平变为低电平时,点亮发光二极管D2。调试程序,并运行。观察发光二极管点亮情况

    、实验程序框图

    、实验电路图

    七、实验程序

    ORG  0000H

    AJMP  MAIN

    ORG  0003H

    AJMP  SERVE

    ORG  0013H

    AJMP  SERVE1      

    MAIN:  ORL P1 ,#0FFH ;

    SETB IT0; 

    SETB EX0; 

    SETB IT1; 

    SETB EX1; 

    SETB EA;  

    AJMP $ ;

    SERVE: MOV A,#0F7H

    MOV P1,A

    RETI

    SERVE1: MOV A,#0EFH

    MOV P1,A

    RETI

    八、实验总结

    通过本次实验,我们学习了外部中断技术的基本使用方法,以及学习中断处理程序的编程方法,这为以后学习单片机的其他方面的内容打下了铺垫。

    展开全文
  • 51/52单片机外部中断实验程序 伟福试验箱专用
  • STM32F1外部中断实验

    2015-09-17 08:08:28
    STM32F1外部中断实验,库函数版本STM32F1外部中断实验,库函数版本
  • 文章目录基础实验10- EXTI外部中断实验一、实验代码二、EXTI外部中断 一、实验代码 int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration------------------------------------...

    基础实验10- EXTI外部中断实验

    实验目的:掌握EXTI的使用方法。
    实验现象:每按下一次USER按键,LD5灯显示反转一次。

    一、实验代码

    int main(void)
    {
        /* USER CODE BEGIN 1 */
        /* USER CODE END 1 */
        /* MCU Configuration--------------------------------------------------------*/
        /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
        HAL_Init();
        /* USER CODE BEGIN Init */
        /* USER CODE END Init */
        /* Configure the system clock */
        SystemClock_Config();
        /* USER CODE BEGIN SysInit */
        /* USER CODE END SysInit */
        /* Initialize all configured peripherals */
        MX_GPIO_Init();
        /* USER CODE BEGIN 2 */
        /* USER CODE END 2 */
        /* Infinite loop */
        /* USER CODE BEGIN WHILE */
        while (1)
        {
            /* USER CODE END WHILE */
            /* USER CODE BEGIN 3 */
        }
        /* USER CODE END 3 */
    }
    

    二、EXTI外部中断

    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    {
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);
    }
    

    当USER键按下后,触发外部中断,进入中断服务函数,中断服务函数调用该Callback函数。函数中将LD5的状态反转。

    展开全文
  • 13 . 外部中断实验

    2021-05-13 10:50:46
    外部中断实验 介绍了STM32F10x 的中断,就来学习下外部中断。要实现的功能与按键实验一样,即通过按键控制LED,只不过这里采用外部中断方式进行控制。 1. 外部中断介绍 EXTI 简介 STM32F10x 外部中断/事件控制器...

    外部中断实验

    介绍了STM32F10x 的中断,就来学习下外部中断。要实现的功能与按键实验一样,即通过按键控制LED,只不过这里采用外部中断方式进行控制。

    1. 外部中断介绍

    EXTI 简介
    STM32F10x 外部中断/事件控制器(EXTI)包含多达20 个用于产生事件/中断请求的边沿检测器。EXTI 的每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发),还可独立地被屏蔽。
    EXTI 结构框图
    在这里插入图片描述
    EXTI 框图包含了EXTI 最核心内容,掌握了此框图,对EXTI 就有一个全局的把握,在编程的时候思路就非常清晰。从图中可以看到,总计有EXTI中断线20根,有很多信号线上都有标号9 样的“20”字样,这个表示在控制器内部类似的信号线路有20 个,这与STM32F10x 的EXTI 总共有20 个中断/事件线是吻合的。因此我们只需要理解其中一个的原理,其他的19个线路原理都是一样的。
    EXTI 分为两大部分功能,一个产生中断,另一个产生事件,这两个功能从硬件上就有所差别,这个在框图中也有体现。从图中标号3 的位置处就分出了两条线路,一条是3-4-5 用于产生中断,另一条是3-6-7-8 用于产生事件。下面我们就来介绍下这两条线路:
    (1)首先看下产生中断的这条线路(1-2-3-4-5)
    1.标号1 为输入线,EXTI 控制器有20 个中断/事件输入线,这些输入线可以通过寄存器设置为任意一个GPIO,也可以是一些外设的事件,这部分内容我们会在后面专门讲解。输入线一般是存在电平变化的信号。
    2.边沿检测电路,EXTI 可以对触发方式进行选择,通过上升沿触发选择寄存器和下降沿触发选择寄存器对应位的设置来控制信号触发。边沿检测电路以输入线作为信号输入端,如果检测到有边沿跳变就输出有效信号1 给红色框3 电路,否则输出无效信号0。而上升沿和下降沿触发选择这两个寄存器可以控制需要检测哪些类型的电平跳变过程,可以是只有上升沿触发、只有下降沿触发或者上升沿和下降沿都触发。
    3.其实就是一个或门电路,一端输入信号线由标号2 提供,一端由软件中断事件寄存器提供,只要有一个为有效信号1,标号3 电路则输出有效信号1,否则为无效信号0。软件中断事件寄存器允许我们使用软件来启动中断/事件线,这个在某些地方非常有用。
    4.其实就是一个与门电路,一端输入信号线由标号3 电路输出提供,一端由中断屏蔽寄存器提供,只有当两者都为有效信号1,标号4 电路才会输出有效信号1,否则输出无效。这样我们就可以简单的控制中断屏蔽寄存器来实现是否产生中断的目的。当我们把中断屏蔽寄存器设置为1 时,标号4 输出就取决于标号3 电路的输出。标号3 电路输出的信号会被保存到挂起寄存器内,如果确定标号3 电路输出为1 就会把挂起寄存器对应位置1。

    5.将挂起寄存器内容输入到NVIC 内,从而实现系统中断事件的控制。
    (2)最后我们再来看下产生事件这条线路(1-2-3-6-7-8),前面1-2-3都是一样的,只是在3 的输出后产生分歧。
    6.其实就是一个与门电路,一端来至标号3 电路的输出信号,一端来至事件屏蔽寄存器,只有两者都为有效电平1,标号6 输出才有效。当事件屏蔽寄存器设置为0 时,不管标号3 电路输出为1 还是0,标号6 电路输出均为0。当事件屏蔽寄存器设置为1 时,标号6 电路输出取决于标号3 电路输出,这样就可以简单的控制事件屏蔽寄存器来实现是否产生事件的目的。
    7.脉冲发生器电路,其输入端只与标号6 电路输出有关,标号6 输出有效,脉冲发生器才会输出一个脉冲信号。
    8.脉冲信号,由标号7 脉冲发生器产生,是事件线路的终端,此脉冲信号可供其他外设电路使用,比如定时器、ADC 等。这样的脉冲信号通常用来触发定时器、ADC 等开始转换。

    从上面EXTI 框图可以看出,中断线路最终会输入到NVIC 控制器中,从而会运行中断服务函数,实现中断内功能,这个是软件级的。而事件线路最后产生的脉冲信号会流向其他的外设电路,是硬件级的。在EXTI 框图最顶端可以看到,其外设接口时钟是由PCLK2,即APB2 提供,所以在后面使能EXTI 时钟的时候一定要注意。

    外部中断/事件线映射
    STM32F10x 的EXTI 具有20 个中断/事件线,对应连接的外设说明如下表所示:
    在这里插入图片描述
    从上表可知,STM32F10x 的EXTI 供外部IO 口使用的中断线有16 根,但是我们使用的STM32F103 芯片却远远不止16 个IO 口, 那么STM32F103 芯片怎么解决这个问题的呢?因为STM32F103 芯片每个GPIO 端口(GPIOx)均有16 个管脚,因此把每个端口的16 个IO 对应那16 根中断线EXTI0-EXTI15 。
    比如:
    GPIOx.0-GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线EXTI0-EXTI15,这样一来每个中断线就对应了最多7 个IO 口,比如:GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。但是中断线每次只能连接一个在IO 口上,这样就需要通过AFIO 的外部中断配置寄存器1 的EXTIx[3:0]位来决定对应的中断线映射到哪个GPIO 端口上,对于中断线映射到GPIO 端口上的配置函数在stm32f10x_gpio.c 和stm32f10x_gpio.h 中,所以使用到外部中断时要把这个文件加入到工程中。EXTI 的GPIO 映射图如图所示:
    在这里插入图片描述
    EXTI 配置步骤
    接下来我们介绍下如何使用库函数对外部中断进行配置。这个也是在编写程序中必须要了解的。具体步骤如下:(EXTI 相关库函数在stm32f10x_exti.c 和stm32f10x_exti.h 文件中)
    (1)使能IO 口时钟,配置IO 口模式为输入
    由于本章使用开发板上4 个按键IO 口作为外部中断输入线,因此需要使能对应的IO 口时钟及配置IO 口模式,在按键实验章节中,我们就介绍过要把对应IO 口设置为输入模式,这部分配置与按键实验一样。
    (2)开启AFIO 时钟,设置IO 口与中断线的映射关系
    接下来我们需要将GPIO 映射到对应的中断线上,只要使用到外部中断,就必须先使能AFIO 时钟,前面已经说了它是挂接在APB2 总线上的,所以使能AFIO时钟库函数为:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    

    然后,我们就可以把GPIO 映射到对应的中断线上,配置GPIO 与中断线映射的库函数如下:

    void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_tGPIO_PinSource);
    

    比如我们将中断线0 映射到GPIOA 端口,那么就需要如下配置:

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    

    这时候GPIOA.0 管脚就与中断线0 连接起来,其他端口中断线的映射类似。
    (3)配置中断分组(NVIC),使能中断我们知道EXTI 产生中断线路最终是流向NVIC 控制器的,由NVIC 调用中断服务函数,因此我们需要对NVIC 进行配置。NVIC 的配置在上一章介绍STM32 中断的时候已经讲过,这里就不重复,不清楚的朋友可以回过头看下。配置NVIC范例如下:

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//EXTI0 中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; // 子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器
    

    (4)初始化EXTI,选择触发方式
    配置好NVIC 后,我们还需要对中断线上的中断初始化,EXTI 初始化库函数,如下:

    void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
    

    函数形参是有一个结构体EXTI_InitTypeDef 类型的指针变量,EXTI_InitTypeDef 结构体成员变量如下:

    typedef struct
    {
    uint32_t EXTI_Line; //中断/事件线
    EXTIMode_TypeDef EXTI_Mode; //EXTI 模式
    EXTITrigger_TypeDef EXTI_Trigger; //EXTI 触发方式
    FunctionalState EXTI_LineCmd; //中断线使能或失能
    }EXTI_InitTypeDef;
    

    下面就来介绍下结构体内成员的意义:
    EXTI_Line:EXTI 中断/事件线选择,可配置参数为EXTI0-EXTI20,可参考上表。
    EXTI_Mode:EXTI 模式选择,可以配置为中断模式EXTI_Mode_Interrupt 和事件模式EXTI_Mode_Event。
    EXTI_Trigger : 触发方式选择, 可以配置为上升沿触发EXTI_Trigger_Rising、下降沿触发EXTI_Trigger_Falling、上升沿和下降沿触发EXTI_Trigger_Rising_Falling。
    EXTI_LineCmd:中断线使能或者失能,配置ENABLE 为使能,DISABLE 为失能,我们这里要使用外部中断,所以需使能。
    (5)编写EXTI 中断服务函数
    所有中断函数都在STM32F1 启动文件中,不知道中断函数名的可以打开启动文件查找。这里我们使用到的是外部中断,其函数名如下:
    EXTI0_IRQHandler
    EXTI1_IRQHandler
    EXTI2_IRQHandler
    EXTI3_IRQHandler
    EXTI4_IRQHandler
    EXTI9_5_IRQHandler
    EXTI15_10_IRQHandler
    从函数名可以看到,前面0-4 个中断线都是独立的函数,中断线5-9 共用一个函数EXTI9_5_IRQHandler , 中断线10-15 也共用一个函数EXTI15_10_IRQHandler,所以要在编写对应中断服务函数时要注意。

    硬件设计

    硬件电路依然使用开发板上的4 个按键,其电路如图所示:
    在这里插入图片描述
    在这里插入图片描述
    当按键按下时,对应的IO 口电平会发生变化,这时只要配置好对应端口的外部中断触发方式就可以触发中断。

    软件设计

    要实现外部中断方式控制LED,程序框架如下:
    (1)初始化对应端口的EXTI
    (2)编写EXTI 中断函数
    (3)编写主函数
    在前面介绍EXTI 配置步骤时,就已经讲解如何初始化EXTI。

    EXTI 初始化函数
    要使用外部中断,我们必须先对它进行配置。EXTI 初始化代码如下:

    /****************************************************************
    ***************
    * 函数名: My_EXTI_Init
    * 函数功能: 外部中断初始化
    * 输入: 无
    * 输出: 无
    *****************************************************************
    **************/
    void My_EXTI_Init(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);//选择GPIO 管脚用作外部中断线路
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3);//选择GPIO 管脚用作外部中断线路
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4);//选择GPIO 管脚用作外部中断线路
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//选择GPIO 管脚用作外部中断线路
    
    //EXTI0 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//EXTI0 中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;// 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器
    
    //EXTI2 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//EXTI2 中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;// 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =2; //子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器
    
    //EXTI3 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//EXTI3 中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;// 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器
    
    //EXTI4 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//EXTI4 中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;// 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器
    
    EXTI_InitStructure.EXTI_Line=EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd=ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    
    EXTI_InitStructure.EXTI_Line=EXTI_Line2|EXTI_Line3|EXTI_Line4;
    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd=ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    }
    

    在My_EXTI_Init()函数中,首先使能AFIO 时钟,并将4 个按键端口映射到对应中断线上,4 个按键连接端口是PA0、PE2、PE3、PE4。然后配置相应的NVIC并使能对应中断通道,由于4 个按键的IO 口占用了4 个中断线,属于不同的中断通道,需要分别对其配置,从NVIC 配置代码中可以看到4 个中断通道的响应优先级为0-3,所以NVIC 被分成了2 组,分组代码放在了主函数,只有一条语句:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组分2 组。
    

    最后就是对EXTI 初始化,通过配置EXTI_InitStructure 结构体成员值实现EXTI 的配置,从代码中可以看到,中断线0(EXTI_Line0)被配置为上升沿触发,中断线2-4 被配置为下降沿触发,这是因为我们的按键K_UP 是高电平有效,而其他3 个按键是低电平有效,这个在按键实验中已经介绍过。其实如果你会配置一个中断线的EXTI,那么其他中断线都是类似的。

    EXTI 中断函数

    初始化EXTI 后,中断就已经开启了,当任意按键按下后会触发一次中断,这时程序就会进入中断服务函数执行,所以我们还需要编写对应的EXTI 中断函数,这里我们以PA0 管脚的K_UP 按键进行讲解,其他的按键的中断函数类似,具体代码如下:

    /****************************************************************
    ***************
    * 函数名: EXTI0_IRQHandler
    * 函数功能: 外部中断0 函数
    * 输入: 无
    * 输出: 无
    *****************************************************************
    **************/
    void EXTI0_IRQHandler(void)
    {
    if(EXTI_GetITStatus(EXTI_Line0)==1)
    {
    delay_ms(10);
    if(K_UP==1)
    {
    led2=0;
    }
    }
    EXTI_ClearITPendingBit(EXTI_Line0);
    }
    

    因为PA0 管脚对应的中断线是EXTI0,所以其中断函数为EXTI0_IRQHandler,这个从名字来看就很好理解。进入中断函数后,为了确保中断是否真的发生,我们还会对其中断标志位状态进行判断,获取EXTI 中断标志位状态函数如下:

    EXTI_GetITStatus(EXTI_Line0);
    

    函数参数EXTI_Line0 是所要判断的中断线, 可以为EXTI_Line0-EXTI_Line20。如果EXTI 中断线有中断发生,函数返回SET,否则返回RESET。SET 也可以用1 表示,RESET 可以用0 表示。在结束中断服务函数前,我们还会清除中断标志位,函数如下:

    EXTI_ClearITPendingBit(EXTI_Line0);

    在库函数内,还提供了两个函数用来判断外部中断状态以及清除外部状态标志位的函数EXTI_GetFlagStatus 和EXTI_ClearFlag,他们的作用和前面两个函数的作用类似。只是在EXTI_GetITStatus 函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而EXTI_GetFlagStatus 直接用来判断状态标志位。在中断函数内,还调用了delay_ms 函数,用于软件消抖,如果K_UP 确实按下了,就点亮D2 指示灯。

    主函数
    编写好EXTI 初始化和中断服务函数后,接下来就可以编写主函数了,代码如下:

    /****************************************************************
    ***************
    * 函数名: main
    * 函数功能: 主函数
    * 输入: 无
    * 输出: 无
    *****************************************************************
    **************/
    int main()
    {
    u8 i;
    SysTick_Init(72);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组分2 组
    LED_Init();
    KEY_Init();
    My_EXTI_Init(); //外部中断初始化
    while(1)
    {
    i++;
    if(i%20==0)
    {
    led1=!led1;
    }
    delay_ms(10);
    }
    }
    

    主函数实现的功能很简单, 首先对NVIC 进行分组, 这里我们调用NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)函数,将NVIC 分为2 组即抢占优先级和响应优先级都占2 位,本套教程所有中断分组都采用这种设置,后面就不做重复。再对使用到的硬件端口时钟和IO 口初始化,然后调用我们前面编写的EXTI 的初始化函数,最后进入while 循环语句,不断让D1 指示间隔200ms
    闪烁。有的朋友就会问,在主函数中怎么没有看到按键对LED 的控制呢?因为我们在My_EXTI_Init()函数内就已经把按键管脚映射到中断线上,并配置了相应的触发方式,当有按键按下,即会进入对应中断服务函数执行相应的功能程序,LED的控制就在中断函数内完成的。

    展开全文
  • HAL库外部中断实验

    2020-02-20 19:56:22
    使能了三个按键及两个LED,通过外部中断的方式可以对两个LED进行点亮,翻转和熄灭操作,基于STM32CubeMX,HAL库开发,经测试可用,基础教程配套实验
  • 51单片机实验例程视频和PPT-外部中断实验.zip(外部中断PPT、视频1-外部中断程序原理)。
  • 单片机外部中断实验

    千次阅读 2020-05-31 00:28:22
    设定外部信号发生器每2s钟,产生一个下降沿,作为外部中断源,中断处理完成led灯的闪烁一次,以及控制步进电机旋转一圈。
  • 本文主要介绍了外部中断实验(急救车与交通灯)。
  • 实验5:外部中断实验

    千次阅读 2020-01-18 10:52:26
    EXTI,外部中断/事件控制器。管理了控制器的23个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿检测。 EXTI可以实现对每个中断/事件线进行单独配置,可以单独配置为...
  • STM32外部中断实验

    千次阅读 2019-10-10 19:59:58
    STM32外部中断简介   首先,stm32每个IO口都可以作为作为外部中断的中断输入口STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。 STM32F103的 ...
  • AVR单片机 实验二 数码管显示与外部中断实验 1 实验目的 掌握动态扫描与外部中断原理,以实现多位数码管显示及单一按键控制的应用。 2 实验内容 (1) 实现4位数码管的动态扫描。 (2) 设定外部中断,实现按下按键累加...
  • STM32CubeMX—外部中断实验

    千次阅读 多人点赞 2019-07-24 19:04:04
    STM32CubeMx 外部中断实验 一、实验说明 实验平台:STM32F103RCT6(正点原子mini 板) 实验内容:使用 按键(PC5) 触发外部中断 控制LED灯(PA8)的亮灭。(按一下亮,再按一下灭) 二、实验操作 1、基础配置 sys中,...
  • zigbee CC2530 系列教程 5 外部中断实验

    千次阅读 2020-01-16 16:25:31
    4.4外部中断实验 4.4.1实验目的 了解使用外部中断的方法,在中断处理函数中切换LED的状态。 4.4.2 实验讲解 首先根据开发板硬件原理图确定LED与CC2530芯片的连接引脚,如图4-4所示。 图4-4开发板LED和按键原理...
  • STM32F103ZET6之外部中断实验 文章目录STM32F103ZET6之外部中断实验前言一、原理图二、外部中断配置步骤二、程序源码1.exti.h2.exti.c3.main.c三、实验结果总结 前言 对于STM32的学习可分为3个版本。1.寄存器...
  • ARM基本接口之外部中断实验

    千次阅读 2018-05-26 18:05:30
    实验名称:ARM基本接口之外部中断实验实验目的: 1. 了解中断的作用; 2. 掌握嵌入式系统中断的处理流程; 3. 掌握ARM外部中断编程。 实验内容(含步骤):1. 总体步骤:先编译,启动目标机,待显示2440后,进行...
  • STM32外部中断实验-EXTI

    2020-10-19 13:51:42
    STM32 外部中断简介 STM32 的每个 IO 都可以作为外部中断 的中断输入口,这点也是 STM32 的强大之处。STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽...
  • STM32-外部中断实验

    2019-01-14 10:39:51
    原地址:http://www.openedv.com/posts/list/21.htm 这一节,我们将向大家介绍如何使用STM32的外部输入中断。...本节分为如下几个部分: 3.4.1 STM32外部中断简介 3.4.2 硬件设计 3.4.3 软件设计 3.4.4 ...
  • 基于Keil MDK环境开发。在开发板上测试过,可以实现中断的嵌套,完整项目文件,完整源码。~~~~
  • 外部中断实验1、 实验目的 了解外部中断原理 学会单片机外部中断的用法; 2、 实验设备 装有 Linux系统的电脑,已装好SDCC交叉编译环境,并带有Python烧写工具; 51单片机开发板 1 个,USB 数据线 1 根。 3、 实验...
  • 实验过程实验目的实验内容1、定时器2、计数器方法1方法二外部中断实验使用使用c语言在Keil uVision 4软件编程,使用Proteus软件模拟单片机运行,掌握单片机使用定时器、计数器和外部中断的方法。51单片机设置晶振...
  • 一、外部中断介绍 在前面文章中,我们对中断的概念进行了介绍。STC89C516单片机内部有6个中断源,它们分别为: INT0—外部中断0,由P32端口线引入,低电平或下降沿触发中断。 INT1—外部中断1,由P33端口线引入...
  • CC2530基础实验—— 外部中断实验

    千次阅读 2018-07-06 14:09:01
    一、任务要求使用SW1按键作为外部中断输入来控制流水灯效果的启停,即实验板通电后两个发光二极管以下述方式工作:①通电后LED1和LED2都熄灭。 ②延时一段时间后LED1点亮。 ③延时一段时间后LED2点亮,此时LED1和...
  • Arduino笔记-外部中断实验(震动传感器实时亮灯)

    千次阅读 多人点赞 2020-04-02 22:11:12
    外部中断:达到实时响应处理事件的效果。 目前Ardinuo UNO引脚只有2个,一个是2号口,一个是3号口 在Ardinuo中中断函数,返回值为空,不能有参数 程序运行截图如下: 当感应到震动后: 这里来看下震动...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,115
精华内容 6,046
关键字:

外部中断实验代码