STM32(三):外部中断 (标准库函数)

这篇具有很好参考价值的文章主要介绍了STM32(三):外部中断 (标准库函数)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

上一篇文章已经介绍了如何用按键点灯,使用的是按键扫描的方式,实现了点灯的第二步。这一篇则介绍如何用外部中断的方式实现按键点灯的过程。

一、实验原理

1.外部中断的定义

中断想必大家都知道,通俗来说也就是你现在在做事情1,被打扰了先去做了事情2,事情2做完了回去继续做事情1。

而STM32的外部中断也是如此,只是它做的事情跟你做的不太一样罢了,而且对处理事情有更为严格的优先级关系。举个通俗的例子,它在做事情1,但是被事情2和事情3同时打扰了,事情2的优先级大于事情3,那么它会先去做事情2再去做事情3,都做完了才回归主线事情1。所以有利于提高cpu的利用率。

2.外部中断的介绍

嵌入式要学好必然要把图看好,那么先上个外部中断的流程框图:

STM32(三):外部中断 (标准库函数),STM32,stm32,嵌入式硬件,单片机

2.1 STM32的外部中断线

每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求。

 STM32的中断控制器支持19个外部中断/事件请求:

  • 线0~15:对应外部IO口的输入中断。
  • 线16:连接到PVD输出。
  • 线17:连接到RTC闹钟事件。
  • 线18:连接到USB唤醒事件

2.2 外部中断线与IO引脚对应关系  

每个IO口都可以对应作为中断,几个IO口为一组映射到一个中断线上,如GPIOx.0映射到EXTI0,GPIOx.1映射到EXTI1,...,GPIOx.15映射到EXTI15.

外部中断通用I/O映像

STM32(三):外部中断 (标准库函数),STM32,stm32,嵌入式硬件,单片机

2.3外部中断所需寄存器

STM32外部中断需要用到以下几个寄存器:

  1.  中断屏蔽寄存器(EXTI_IMR)
  2. 事件屏蔽寄存器(EXTI_EMR)
  3. 上升沿触发选择寄存器(EXTI_RTSR)
  4. 下降沿触发选择寄存器(EXTI_FTSR)
  5. 软件中断事件寄存器(EXTI_SWIER)
  6. 挂起寄存器(EXTI_PR) 

2.4外部中断与中断服务函数

IO口外部中断只有7个中断服务函数

  • EXTI0~EXTI4 分别对应一个中断服务函数
  • EXTI5~EXTI9 对应一个中断服务函数 
  • EXTI10~EXTI15 对应一个中断服务函数

STM32(三):外部中断 (标准库函数),STM32,stm32,嵌入式硬件,单片机

ps:这边值得注意的是EXTI5~EXTI9与EXTI10~EXTI15对应的都只有一个中断服务函数,所以要是出现在这范围出现多个线程的中断会有点问题,但在后面对这问题进行了解决。而且还有多个IO口出现同一线程该如何区分开的问题,也对其进行解决。

二、实验步骤

1.NVIC配置

1. 对NVIC初始化,用到 NVIC_InitTypeDef 结构体,其中四个成员:  

  • NVIC_IRQChannel参数来选择将要配置的中断向量;
  • NVIC_IRQChannelCmd参数来进行使能(ENABLE)或关闭(DISABLE)该中断;
  • NVIC_IRQChannelPreemptionPriority成员要配置中断向量的抢占优先级;
  • NVIC_IRQChannelSubPriority需要配置中断向量的子优先级(响应优先级);

2. NVIC只可配置16种中断向量的优先级:编号越小,优先级别越高;

3. 抢占优先级:是指打断其它中断,会出现嵌套中断;

4. 子优先级(响应优先级):先处理响应优先级高的中断; 

/* 选择中断优先级配置组为4个抢占式优先级和4个子优先级,可以参考misc.h文件了解相关设置 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 使能KEY1所在的外部中断通道 */
NVIC_InitStructure.NVIC_IRQChannel = KEY_IRQCHANNEL;
/* 设置抢占式优先级为2 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; 
/* 设置子优先级为3 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
/* 使能外部中断通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	
/* 初始化配置嵌套向量中断控制器 */
NVIC_Init(&NVIC_InitStructure); 

2.EXTI配置

EXTI的配置步骤如下所示:

 ①使能EXTIx线的IO时钟和复用时钟(AFIO)

 ②配置EXTI中断线与I/O的映射关系

 ③EXTI的I/O口线引脚和工作模式的配置

 ④配置EXTIx线的中断优先级

 ⑤EXTI 中断线工作模式配置

/* 为启用IO引脚中断功能需要使能复用功能时钟 */
KEY1_RCC_CLOCKCMD(KEY1_RCC_CLOCKGPIO | KEY1_RCC_CLOCKAFIO,ENABLE);
/* 选择PE7作为中断输入源 */
GPIO_EXTILineConfig(KEY1_GPIO_PORTSOURCE,KEY1_GPIO_PINSOURCE);
/* KEY1对应的断线 */
EXTI_InitStructure.EXTI_Line=KEY1_EXITLINE;
/* 外部中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
/* 上升沿触发方式 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
/* 根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 */
EXTI_Init(&EXTI_InitStructure);

其中AFIO的作用是信号传输媒介或者说是信号搬运工,EXTI的时钟是由AFIO提供的,所以需要开启。而AFIO时钟在APB2总线上的原因是端口重映射之后,映射的新引脚都是GPIO的引脚,GPIOx又是APB2的外设,使用APB2给其提供时钟非常合适。

参考:AFIO时钟误区及其用法解析-CSDN博客

3.中断函数

/* 中断服务函数,用于产生中断动作 */
EXTIx_IRQHandler();
/* 中断判断函数,用于判断中断动作 */
EXTI_GetITStatus()
/* 中断清除函数,用于清除中断动作	*/
EXTI_ClearITPendingBit()

上面说过由于EXTI5~EXTI9与EXTI10~EXTI15分别对于中断服务函数EXTI9_5_IRQHandler和EXTI15_10_IRQHandler,所以要是出现在这范围出现多个线程的中断,可能会出现问题,则需要进行对线程判断的处理,以及对IO口判断的处理。

void KEY_IRQHANDLER(void)
{
	/* 处理Line7的中断 */
    if(EXTI_GetITStatus(EXTI_Line7) != RESET)
    {
        /* 处理GPIOA的PIN7的中断,若没有多个IO占用Line7可以注释 */
        if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_7) == Bit_SET) // 检查引脚状态
        {
            //事件
        }
        
        /* 处理EXTI_Line7的中断 */
        EXTI_ClearITPendingBit(EXTI_Line7); 
    }

    // 重复上述逻辑,检查其他线(如EXTI_Line5, EXTI_Line6,...)
}

三、实操代码

程序分为3个文件:bsp_key.c、bsp_key.h、main.c

1.bsp_key.c

这边值得注意的是KEY的引脚线序,对下方代码进行选取,我都为大家列好情况了,看下注释即可。

/* 包含头文件 ----------------------------------------------------------------*/
#include "bsp/key/bsp_key.h"


/**
  * 函数功能: 配置KEY作为中断引脚并使能中断
  * 输入参数:无
  * 返 回 值: 无
  * 说    明:配置KEY为上升沿中断,当按下按键时就有一个从低电平变为高
  *           电平过程。
  */
void KEY1_EXIT_Config(void)
{
  /* 定义IO硬件初始化结构体变量 */
  GPIO_InitTypeDef GPIO_InitStructure;
  /* 定义外部中断线初始化结构体变量 */
  EXTI_InitTypeDef EXTI_InitStructure;
  /* 定义嵌套向量中断控制器初始化结构体变量 */
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 为启用IO引脚中断功能需要使能复用功能时钟 */
  KEY1_RCC_CLOCKCMD(KEY1_RCC_CLOCKGPIO | KEY1_RCC_CLOCKAFIO,ENABLE);
  
  /* 设定KEY1对应引脚IO编号 */
  GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;  
  /* 设定KEY1对应引脚IO最大操作速度 :GPIO_Speed_50MHz */
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  /* 设定KEY1对应引脚IO为浮空输入模式 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  /* 初始化KEY1对应引脚IO */
  GPIO_Init(KEY1_GPIO, &GPIO_InitStructure);

  /* 选择PE7作为中断输入源 */
  GPIO_EXTILineConfig(KEY1_GPIO_PORTSOURCE,KEY1_GPIO_PINSOURCE);
  
  /* KEY1对应的断线 */
  EXTI_InitStructure.EXTI_Line=KEY1_EXITLINE;
  /* 外部中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  /* 上升沿触发方式 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  /* 使能中断 */
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  /* 根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 */
  EXTI_Init(&EXTI_InitStructure);
  
  /* 选择中断优先级配置组为4个抢占式优先级和4个子优先级,可以参考misc.h文件了解相关设置 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 使能KEY1所在的外部中断通道 */
  NVIC_InitStructure.NVIC_IRQChannel = KEY_IRQCHANNEL;
  /* 设置抢占式优先级为2 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; 
  /* 设置子优先级为3 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
  /* 使能外部中断通道 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	
  /* 初始化配置嵌套向量中断控制器 */
  NVIC_Init(&NVIC_InitStructure); 
}

void KEY2_EXIT_Config(void)
{
  /* 定义IO硬件初始化结构体变量 */
  GPIO_InitTypeDef GPIO_InitStructure;
  /* 定义外部中断线初始化结构体变量 */
  EXTI_InitTypeDef EXTI_InitStructure;
  /* 定义嵌套向量中断控制器初始化结构体变量 */
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 为启用IO引脚中断功能需要使能复用功能时钟 */
  KEY1_RCC_CLOCKCMD(KEY2_RCC_CLOCKGPIO | KEY2_RCC_CLOCKAFIO,ENABLE);
  
  /* 设定KEY2对应引脚IO编号 */
  GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;  
  /* 设定KEY2对应引脚IO最大操作速度 :GPIO_Speed_50MHz */
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  /* 设定KEY2对应引脚IO为浮空输入模式 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  /* 初始化KEY2对应引脚IO */
  GPIO_Init(KEY2_GPIO, &GPIO_InitStructure);

  /* 选择PE8作为中断输入源 */
  GPIO_EXTILineConfig(KEY2_GPIO_PORTSOURCE,KEY2_GPIO_PINSOURCE);
  
  /* KEY2对应的断线 */
  EXTI_InitStructure.EXTI_Line=KEY2_EXITLINE;
  /* 外部中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  /* 上升沿触发方式 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  /* 使能中断 */
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  /* 根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 */
  EXTI_Init(&EXTI_InitStructure);
  
  /* 选择中断优先级配置组为4个抢占式优先级和4个子优先级,可以参考misc.h文件了解相关设置 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 使能KEY2所在的外部中断通道 */
  NVIC_InitStructure.NVIC_IRQChannel = KEY_IRQCHANNEL;
  /* 设置抢占式优先级为0 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; 
  /* 设置子优先级为0 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
  /* 使能外部中断通道 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	
  /* 初始化配置嵌套向量中断控制器 */
  NVIC_Init(&NVIC_InitStructure); 
}

void KEY3_EXIT_Config(void)
{
  /* 定义IO硬件初始化结构体变量 */
  GPIO_InitTypeDef GPIO_InitStructure;
  /* 定义外部中断线初始化结构体变量 */
  EXTI_InitTypeDef EXTI_InitStructure;
  /* 定义嵌套向量中断控制器初始化结构体变量 */
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 为启用IO引脚中断功能需要使能复用功能时钟 */
  KEY1_RCC_CLOCKCMD(KEY3_RCC_CLOCKGPIO | KEY3_RCC_CLOCKAFIO,ENABLE);
  
  /* 设定KEY3对应引脚IO编号 */
  GPIO_InitStructure.GPIO_Pin = KEY3_GPIO_PIN;  
  /* 设定KEY3对应引脚IO最大操作速度 :GPIO_Speed_50MHz */
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  /* 设定KEY3对应引脚IO为浮空输入模式 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  /* 初始化KEY3对应引脚IO */
  GPIO_Init(KEY1_GPIO, &GPIO_InitStructure);

  /* 选择PE9作为中断输入源 */
  GPIO_EXTILineConfig(KEY3_GPIO_PORTSOURCE,KEY3_GPIO_PINSOURCE);
  
  /* KEY3对应的断线 */
  EXTI_InitStructure.EXTI_Line=KEY3_EXITLINE;
  /* 外部中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  /* 上升沿触发方式 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  /* 使能中断 */
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  /* 根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 */
  EXTI_Init(&EXTI_InitStructure);
  
  /* 选择中断优先级配置组为4个抢占式优先级和4个子优先级,可以参考misc.h文件了解相关设置 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 使能KEY3所在的外部中断通道 */
  NVIC_InitStructure.NVIC_IRQChannel = KEY_IRQCHANNEL;
  /* 设置抢占式优先级为1 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; 
  /* 设置子优先级为1 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
  /* 使能外部中断通道 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	
  /* 初始化配置嵌套向量中断控制器 */
  NVIC_Init(&NVIC_InitStructure); 
}

/**
  * 函数功能: 针对KEY多根线序为5-9的中断服务函数
  * 输入参数:无
  * 返 回 值: 无
  * 说    明:在stm32f103检测到上升沿信号后会自动进入对应的中断服务函数,我们可以在
  *           服务函数内实现一些处理。
  *			  多根线序为5-9的线
  */
void KEY_IRQHANDLER(void)
{

	if(EXTI_GetITStatus(EXTI_Line7) != RESET)
    {
		/* 延时一小段时间,消除抖动 */
	    Delay(10); 
        LED1_TOGGLE; 
		/* 处理EXTI_Line7的中断 */
        EXTI_ClearITPendingBit(EXTI_Line7); 
    }

    if(EXTI_GetITStatus(EXTI_Line8) != RESET)
    {
		Delay(10); 
        LED2_TOGGLE; 
		/* 处理EXTI_Line8的中断 */
        EXTI_ClearITPendingBit(EXTI_Line8); 
    }
	 if(EXTI_GetITStatus(EXTI_Line9) != RESET)
    {
		 Delay(10); 
		 LED3_TOGGLE; 
		/* 处理EXTI_Line9的中断 */
        EXTI_ClearITPendingBit(EXTI_Line9); 
	 }
    // 重复上述逻辑,检查其他线(如EXTI_Line5, EXTI_Line6)
}

/**
  * 函数功能: 针对KEY线序单独分开的中断服务函数
  * 输入参数:无
  * 返 回 值: 无
  * 说    明:在stm32f103检测到上升沿信号后会自动进入对应的中断服务函数,我们可以在
  *           服务函数内实现一些处理。
  *			  线序单独分开的线
  */
//void KEY1_IRQHANDLER(void)
//{
//  /* 确保是否产生了EXTI Line中断 */
//	if(EXTI_GetITStatus(KEY1_EXITLINE) != RESET)
//	{
//      Delay(10); 
//		/* LED1灯翻转	*/	
//		LED1_TOGGLE;
//     /* 清除中断标志位	*/
//	    EXTI_ClearITPendingBit(KEY1_EXITLINE);     
//	}
//}

//void KEY2_IRQHANDLER(void)
//{
//	if(EXTI_GetITStatus(KEY2_EXITLINE) != RESET)
//	{
//      Delay(10); 
//		LED2_TOGGLE;
//		EXTI_ClearITPendingBit(KEY2_EXITLINE);     
//	}
//}

//void KEY3_IRQHANDLER(void)
//{
//	if(EXTI_GetITStatus(KEY3_EXITLINE) != RESET)
//	{
//      Delay(10); 
//		LED3_TOGGLE;
//		EXTI_ClearITPendingBit(KEY3_EXITLINE);     
//	}
//}

2.bsp_key.h

这边值得注意的是KEY的引脚线序,对下方代码进行选取,我都为大家列好情况了,看下注释即可。

#ifndef __BSP_KEY_H__
#define __BSP_KEY_H__

/* 包含头文件 ----------------------------------------------------------------*/
#include <stm32f10x.h>
#include "bsp/delay/delay.h"
#include "bsp/led/bsp_led.h"

/* 类型定义 --------------------------------------------------------------*/
typedef enum
{
  KEY_UP   = 0,
  KEY_DOWN = 1,
  KEY_DOWN_LONG   = 2,
}KEYState_TypeDef;

/* 宏定义 --------------------------------------------------------------------*/
#define KEY1                          (uint8_t)0x01
#define KEY2                          (uint8_t)0x02
#define KEY3                          (uint8_t)0x04
#define IS_KEY_TYPEDEF(KEY)           (((KEY) == KEY1) || ((KEY) == KEY2) || ((KEY) == KEY3))

/* 宏定义 --------------------------------------------------------------------*/
#define KEY1_RCC_CLOCKCMD             RCC_APB2PeriphClockCmd
#define KEY1_RCC_CLOCKGPIO            RCC_APB2Periph_GPIOE
#define KEY1_GPIO_PIN                 GPIO_Pin_7
#define KEY1_GPIO                     GPIOE
#define KEY1_DOWN_LEVEL               0  /* 根据原理图设计,KEY1按下时引脚为低电平,所以这里设置为0 */
#define KEY1_RCC_CLOCKAFIO            RCC_APB2Periph_AFIO
#define KEY1_GPIO_PORTSOURCE          GPIO_PortSourceGPIOE
#define KEY1_GPIO_PINSOURCE           GPIO_PinSource7
#define KEY1_EXITLINE                 EXTI_Line7

/* 根据线序来,需要用到则取消注释并修改*/
//#define KEY1_IRQCHANNEL               EXTI1_IRQn     
//#define KEY1_IRQHANDLER               EXTI1_IRQHandler

#define KEY2_RCC_CLOCKCMD             RCC_APB2PeriphClockCmd
#define KEY2_RCC_CLOCKGPIO            RCC_APB2Periph_GPIOE
#define KEY2_GPIO_PIN                 GPIO_Pin_8
#define KEY2_GPIO                     GPIOE
#define KEY2_DOWN_LEVEL               0  /* 根据原理图设计,KEY2按下时引脚为低电平,所以这里设置为0 */
#define KEY2_RCC_CLOCKAFIO            RCC_APB2Periph_AFIO
#define KEY2_GPIO_PORTSOURCE          GPIO_PortSourceGPIOE
#define KEY2_GPIO_PINSOURCE           GPIO_PinSource8
#define KEY2_EXITLINE                 EXTI_Line8

/* 根据线序来,需要用到则取消注释并修改*/
//#define KEY2_IRQCHANNEL               EXTI2_IRQn      
//#define KEY2_IRQHANDLER               EXTI2_IRQHandler

#define KEY3_RCC_CLOCKCMD             RCC_APB2PeriphClockCmd
#define KEY3_RCC_CLOCKGPIO            RCC_APB2Periph_GPIOE
#define KEY3_GPIO_PIN                 GPIO_Pin_9
#define KEY3_GPIO                     GPIOE
#define KEY3_DOWN_LEVEL               0  /* 根据原理图设计,KEY3按下时引脚为低电平,所以这里设置为0 */
#define KEY3_RCC_CLOCKAFIO            RCC_APB2Periph_AFIO
#define KEY3_GPIO_PORTSOURCE          GPIO_PortSourceGPIOE
#define KEY3_GPIO_PINSOURCE           GPIO_PinSource9
#define KEY3_EXITLINE                 EXTI_Line9

/* 根据线序来,需要用到则取消注释并修改*/
//#define KEY3_IRQCHANNEL               EXTI3_IRQn      
//#define KEY3_IRQHANDLER               EXTI3_IRQHandler

/* KEY多根线序为5-9,不用则注释 */
#define KEY_IRQCHANNEL               EXTI9_5_IRQn 
#define KEY_IRQHANDLER               EXTI9_5_IRQHandler


#define IRQ_DISABLE                   __set_PRIMASK(1)		/* 关闭总中断 */  
#define IRQ_ENABLE                    __set_PRIMASK(0)		/* 开放总中断 */ 

/* 扩展变量 ------------------------------------------------------------------*/
/* 函数声明 ------------------------------------------------------------------*/
void KEY_GPIO_Init(void);
KEYState_TypeDef KEYx_StateSet(GPIO_TypeDef* KEYx_GPIO, uint16_t KEYx_GPIO_PIN, uint8_t KEYx_DOWN_LEVEL);
KEYState_TypeDef KEYx_Choice(int KEYIndex);
void KEY_LED(void);

void KEY1_EXIT_Config(void);
void KEY2_EXIT_Config(void);
void KEY3_EXIT_Config(void);
#endif  // __BSP_KEY_H__

3.main.c

这边值得注意的while函数里面什么都不用加,较为简单,运行就完事儿了!


/* 包含头文件 ----------------------------------------------------------------*/
#include "stm32f10x.h"
#include "bsp/led/bsp_led.h"
#include "bsp/key/bsp_key.h"
#include "bsp/delay/delay.h"


/* 函数体 --------------------------------------------------------------------*/

/**
  * 函数功能: 主函数.
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */
int main(void)
{
	LED_GPIO_Init();
	KEY1_EXIT_Config();
	KEY2_EXIT_Config();
	KEY3_EXIT_Config();

  while (1)
  {
    //什么都不加
  }
}

四、实验效果

外部中断-点灯

结束语

本文以STM32VET6为例讲解了用外部中断控制按键点灯的实现方法,并解决了几个可能会在实际中遇到的问题,并在代码中也给出相应注释。希望对大家有所帮助!如果还有什么问题,欢迎评论区留言,谢谢!文章来源地址https://www.toymoban.com/news/detail-857368.html

到了这里,关于STM32(三):外部中断 (标准库函数)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32(三):外部中断 (标准库函数)

    前言 上一篇文章已经介绍了如何用按键点灯,使用的是按键扫描的方式,实现了点灯的第二步。这一篇则介绍如何用外部中断的方式实现按键点灯的过程。 中断想必大家都知道,通俗来说也就是你现在在做事情1,被打扰了先去做了事情2,事情2做完了回去继续做事情1。 而

    2024年04月25日
    浏览(37)
  • 嵌入式学习笔记——STM32的USART收发字符串及串口中断

    上一篇中,介绍了串口收发相关的寄存器,通过代码实现了一个字节的收发,本文接着上面的内容,通过功能函数实现字符串的收发,然后引入中断解决收发过程中while()死等的问题。 根据昨天的字符发送函数,只需要稍作修改即可实现发送函数了,一个字符串的结尾会有一

    2024年02月03日
    浏览(79)
  • 嵌入式开发--STM32用DMA+IDLE中断方式串口接收不定长数据

    之前讲过用 利用IDLE空闲中断来接收不定长数据 ,但是没有用到DMA,其实用DMA会更加的高效,MCU也可以腾出更多的性能去处理应该做的事情。 IDLE顾名思义,就是空闲的意思,即当监测到串口空闲超过1个串口的数据帧时,会使状态寄存器(SR或ISR)的IDLE位置位,如果此时控制

    2024年04月17日
    浏览(64)
  • 嵌入式-Stm32-江科大基于标准库的GPIO通用输入输出口

    (推荐先看文章:《 嵌入式-32单片机-GPIO推挽输出和开漏输出》) 下文图都是从参考手册借阅:STM32F10xxx(中文),大概页数是110/775左右 GPIO (General Purpose Input Output)通用输入输出口 可配置为8种输入输出模式 引脚电平:0V~3.3V,部分引脚可容忍5V(有FT标识) 输出模式 下可控

    2024年01月17日
    浏览(63)
  • 嵌入式-Stm32-江科大基于标准库的GPIO的八种模式

    (推荐先看文章:《 嵌入式-32单片机-GPIO推挽输出和开漏输出》) 下文图都是从参考手册借阅:STM32F10xxx(中文),大概页数是110/775左右 GPIO (General Purpose Input Output)通用输入输出口 可配置为8种输入输出模式 引脚电平:0V~3.3V,部分引脚可容忍5V(有FT标识) 输出模式 下可控

    2024年01月20日
    浏览(52)
  • 嵌入式-Stm32-江科大基于标准库的GPIO4个小实验

    核心:本文共4个小实验: 第一个:LED灯闪烁 第二个:LED流水灯 第三个:按键控制LED 第四个:光敏传感器控制蜂鸣器 1.1 LED、蜂鸣器、面包板 LED:发光二极管,正向通电点亮,反向通电不亮。 有源蜂鸣器(本实验):内部自带振荡源,将正负极接上直流电压即可持续发声,频

    2024年01月21日
    浏览(64)
  • 【嵌入式学习笔记】嵌入式入门2——中断(外部中断)

    打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断 作用1: 实时控制在确定时间内对相应事件作出响应 ——定时器中断 作用2: 故障处理检测到故障,需要第一时间处理 ——外部中断 作用3: 数据传输不确定数据何时会来 ——串口中断

    2024年02月08日
    浏览(74)
  • STM32标准库——(5)EXTI外部中断

    中断 :在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行 中断优先级 :当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加

    2024年02月20日
    浏览(42)
  • 【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据) 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类

    2024年02月15日
    浏览(87)
  • stm32嵌入式实验考核

    STM32 实验考核题目 1. 利用 STM32 小板实现:控制外接 LED 灯每隔 3 秒钟亮暗变换,同 时在 PC 机上显示 MCU 的计时时间,MCU 的初始时间由 PC 机 方设置。 2. 利用 STM32 小板实现:利用导线外接 GPIO 口模拟 2 个按键输入, 根据输入组合的四种情况,分别控制三色灯四种流水灯效果

    2024年02月03日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包