stm32——外部中断EXTI

news2024/11/14 13:25:08

        上回书说到定时器的级联,今天来谈谈外部中断EXTI。我使用的是STM32F103C8T6的学习板。仅供大家参考。

        什么是中断呢?中断是指计算机在执行程序的过程中,当出现某些异常情况或特殊事件(例如外部设备请求、定时时间到达、程序错误等)时,计算机暂停当前正在执行的程序,转而去处理这些异常情况或特殊事件的机制。也就是只要你触发了中断,只有等把中断的事件处理完了,才能去运行其他的程序。stm32的中断非常强大,每个外设都可以产生中断,这里呢,我就单纯的说说外部中断按键的方式如何去控制小灯的亮灭。也就是我们常说的独立按键怎么用。继续往下看。

        EXTI(External Interrupt/event controller) 是外部中断/事件控制器,管理了控制器的20个中断/事件线。每个中断/事件线都对应一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

EXTI功能框图

        

中断/事件线

        EXTI一共有20个中断/事件线。每个GPIO口都可以被设置成输入线,占用EXTI0~EXTI15,也就是PX0,就对应着EXTI0,一一对应。

        我们先来看看程序,首先是开启外部中断的时候,我们需要用到两个时钟GPIOC端口(对应外部中断的端口)和AFIO端口(EXTI所需要的端口)。

void RCC_Configuration(void)
{
  	/* 时钟开启 */
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
}

        接下来,配置GPIO口,NVIC中断以及EXTI初始化。这里我使用的是GPIOC的line13作为它的外部中断,对应单片机上的KEY2按键,通过控制GPIOA上PIN3的LED3小灯来观测现象。



void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
}


void EXIT_Configuration(void)
{
	 EXTI_InitTypeDef EXTI_InitStructure;
	 GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);

  	EXTI_InitStructure.EXTI_Line = EXTI_Line13;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);
}



void NVIC_Configuration(void)
{								
	NVIC_InitTypeDef NVIC_InitStructure;
	 
#ifdef  VECT_TAB_RAM  
  		
 		NVIC_SetVectorTable(NVIC_VectTab_RAM , 0x0); 
#else 	
  		
  		NVIC_SetVectorTable(NVIC_VectTab_FLASH , 0x0);   
#endif

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

        配置是配置完了接下来就是中断函数。大家可以打开自己的启动文件,来看看对应中断函数的命名,0到4是每个都有自身的一个中断函数。5~9是共用中断EXTI9_5_IRQHandler(),10~15是共用一个中断函数EXTI15_10_IRQHandler。因为我用的是GPIOC的13引脚,我使用的中断就是EXTI15_10_IRQHandler。这里要注意使用对应的GPIO口要用上GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);这个语句。否则无法看到对应的现象。接下来是中断程序。

void EXTI15_10_IRQHandler(void)
{
	
	if(EXTI_GetITStatus(EXTI_Line13) != RESET) 
     {
        GPIO_WriteBit(GPIOA, GPIO_Pin_3,(BitAction)((1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_3))));
        EXTI_ClearITPendingBit(EXTI_Line13); 
     }

}

        大家看看现象吧,应该是D3受到KEY2按键的控制。使灯发生亮灭的操作。

        谈到中断,这里就要考虑到中断优先级的问题,有两个优先级的概念,分别是抢占式优先级和响应优先级,每个中断源都需要被指定这两种优先级。具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系。当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据它们的响应优先级高低来决定先处理哪一个;如果它们的抢占式优先级和响应优先级都相等,则根据它们在中断表中的排位顺序决定先处理哪一个。优先级是从0开始是最高的优先级,优先级越大越低。大家可以结合串口通信,设置EXTI0、EXTI1、EXTI2这三个外部中断来看看。

        这里就不过多说了给个简单的代码,中断配置和中断函数。请看代码。

void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    // 如果定义了 VECT_TAB_RAM 宏
    #ifdef  VECT_TAB_RAM  
        // 将中断向量表设置为位于 RAM 中,并设置偏移量为 0
        NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 
    // 否则
    #else  
        // 将中断向量表设置为位于 FLASH 中,并设置偏移量为 0
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
    #endif

    // 设置中断优先级分组为 2
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    // 配置 EXTI0 中断
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    // 设置抢占优先级为 2
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    // 设置响应优先级为 0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    // 使能该中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    // 初始化 EXTI0 中断
    NVIC_Init(&NVIC_InitStructure);

    // 配置 EXTI1 中断
    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
    // 设置抢占优先级为 1
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    // 设置响应优先级为 0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    // 使能该中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    // 初始化 EXTI1 中断
    NVIC_Init(&NVIC_InitStructure);

    // 配置 EXTI2 中断
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
    // 设置抢占优先级为 0
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    // 设置响应优先级为 0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    // 使能该中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    // 初始化 EXTI2 中断
    NVIC_Init(&NVIC_InitStructure);
}

        中断函数

/*******************************************************************************
* Function Name  : EXTI0_IRQHandler
* Description    : This function handles External interrupt Line 0 request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void EXTI0_IRQHandler(void)
{
	printf("\r\nEXIT0 IRQHandler enter.\r\n");
	
	EXTI_GenerateSWInterrupt(EXTI_Line1);
	
	printf("\r\nEXIT0 IRQHandler return.\r\n");
	
	EXTI_ClearFlag(EXTI_Line0);
}

/*******************************************************************************
* Function Name  : EXTI1_IRQHandler
* Description    : This function handles External interrupt Line 1 request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void EXTI1_IRQHandler(void)
{
	printf("\r\nEXIT1 IRQHandler enter.\r\n");
	
	EXTI_GenerateSWInterrupt(EXTI_Line2);
	
	printf("\r\nEXIT1 IRQHandler return.\r\n");
	
	EXTI_ClearFlag(EXTI_Line1);
}

/*******************************************************************************
* Function Name  : EXTI2_IRQHandler
* Description    : This function handles External interrupt Line 2 request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void EXTI2_IRQHandler(void)
{
	printf("\r\nEXIT2 IRQHandler enter.\r\n");
	
	printf("\r\nEXIT2 IRQHandler return.\r\n");
	
	EXTI_ClearFlag(EXTI_Line2);
}

        好了,今天就说这么多。

        欲知后事如何,且听下回分解。OVO......

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1922188.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

流程图怎么做?有三种制作方法

流程图怎么做?在日常生活和工作中,流程图作为一种直观展示步骤、流程或决策路径的工具,扮演着不可或缺的角色。它不仅能够帮助我们理清思路、规划任务,还能促进团队协作与沟通。那么,如何高效地绘制流程图呢&#xff1…

关于web、DNS、firewalld、SELinux综合实验

思路&#xff1a;最好先做DNS&#xff0c;然后再做web服务器 主&#xff1a; 1、写配置文件、/etc/hosts文件等&#xff0c;创建目录&#xff0c;写index.html文件等 [rootlocalhost ~]# cd /etc/httpd/conf.d [rootlocalhost conf.d]# cat vhost.conf <directory /dado…

python自动化之用flask库写一个登陆接口(代码示例)

用到的库&#xff1a; 1、flask&#xff08;写接口&#xff09; 2、cerberus&#xff08;校验数据&#xff09; 实现效果&#xff1a;输入账号和密码&#xff0c;校验数据类型是否是字符串&#xff0c;如果是&#xff0c;返回登陆成功&#xff1b;如果不是&#xff0c;返回数…

泛微E-Cology WorkflowServiceXml SQL注入漏洞复现

0x01 产品简介 泛微e-cology是一款由泛微网络科技开发的协同管理平台,支持人力资源、财务、行政等多功能管理和移动办公。 0x02 漏洞概述 2024年7月,泛微官方发布了新补丁,修复了一处SQL注入漏洞。经分析,攻击者无需认证即可利用该漏洞,建议受影响的客户尽快修复漏洞。…

pnpm9.5.0(catalog协议)

catalog(目录协议) 目录是工作区功能&#xff0c;用于将依赖版本范围定义为可重用常量&#xff0c;目录中定义的常量可以在package.json中使用&#xff0c; 结合 pnpm-workspace.yaml使用 定义pnpm-workspace.yaml packages&#xff1a;定义多仓库 packages:- packages/*cata…

CSS【详解】层叠 z-index (含 z-index 的层叠规则,不同样式的层叠效果)

仅对已定位的元素&#xff08; position:relative&#xff0c;position:absolute&#xff0c;position:fixed &#xff09;有效&#xff0c;默认值为0&#xff0c;可以为负值。 z-index 的层叠规则 z-index 值从小到大层叠 兄弟元素 z-index 值相同时&#xff0c;后面的元素在…

微信小程序毕业设计-高校校园交友系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

react-类组件2

setState 在开发中不能直接通过修改state的值来使界面发生变化&#xff0c;必须通过setState来修改才能使页面发生变化。 使用setState修改时&#xff0c;两次的修改结果会合并&#xff0c;在合并时会比较参数的变化&#xff0c;如果发生变化会覆盖原来的&#xff0c;然后再执…

一文读懂什么是GPU算力平台!

随着高性能计算&#xff08;HPC&#xff09;和人工智能&#xff08;AI&#xff09;技术飞速发展&#xff0c;GPU算力平台作为这些技术的重要支撑&#xff0c;正逐步成为各行各业数字化转型的核心驱动力。尚云sunclouds将带您深入了解GPU算力平台的基本概念、工作原理、优势以及…

阿里ChatSDK使用,开箱即用聊天框

介绍&#xff1a; 效果&#xff1a;智能助理 ChatSDK&#xff0c;是在ChatUI的基础上&#xff0c;结合阿里云智能客服的最佳实践&#xff0c;沉淀和总结出来的一个开箱即用的&#xff0c;可快速搭建智能对话机器人的框架。它简单易上手&#xff0c;通过简单的配置就能搭建出对…

【Linux网络】数据链路层【下】{MAC/MTU/ARP/ICMP/NAT/PING/代理服务器原理}

文章目录 1.逐步深入数据链路层1.1MAC帧1.2由集线器到交换机1.3认识MTU 2.ARP 地址解析协议/RARP逆地址解析协议3.DNS(Domain Name System)域名从输入url后到能看到网页 发生了什么【典中典】 4.ICMP协议&#xff1a;一个网络层协议有了TCP&#xff0c;为什么还要用ICMPICMP协议…

关于电脑的硬盘,你知道那些?

硬盘是一种主要用于存储数据的非易失性存储设备。它通过磁性存储技术在旋转的磁盘上读取和写入数据。硬盘通常安装在计算机内部&#xff0c;但也有外置硬盘供外部使用。 磁盘是什么&#xff1f;与硬盘有什么区别&#xff1f; 磁盘是一个更泛化的术语&#xff0c;可以指代任何使…

黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录 Day4

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我会…

DWG文件发布至IIS后无法下载和预览解决办法

问题描述 DWG文件发布至IIS后无法下载和预览 原因分析&#xff1a; iis里面需要添加扩展 解决方案&#xff1a; 在服务器端IS属性的HTTP头下的MIME内容中添加扩展名“.dwg” MIME类型填入application/acad

分布式锁理解

介绍分布式锁&#xff0c;我觉得从项目的背景入手把 在伙伴匹配系统中&#xff0c;我创建了一个定时任务&#xff0c;做为缓存预热的手段 这个具体原因在Redis-CSDN博客 接下来切入正题&#xff1a; 想象每个服务器都有一个定时任务&#xff0c;都要对数据库或者缓存进行操…

C语言作业5(学生管理系统C语言)

成学生管理系统 1> 使用菜单完成 2> 有学生的信息录入功能&#xff1a;输入学生个数&#xff0c;并将学生的姓名、分数录入 3> 查看学生信息&#xff1a;输出所有学生姓名以及对应的分数 4> 求出学习最好的学生信息&#xff1a;求最大值 5> 按姓名将所有学…

Hyper-V 性能监控工具

虚拟化是任何组织网络管理战略不可或缺的一部分&#xff0c;对于帮助提高网络效率和资源可用性至关重要。采用虚拟基础架构具有多种好处&#xff0c;例如最大限度地减少停机时间、降低运营成本和提高生产力。 在所有虚拟服务器中&#xff0c;Microsoft Hyper-V因其多功能性和可…

亚马逊测评如何实现不同账户拥有独立运行环境,提高成功率

测评之所以被认为是最快速有效的推广方式&#xff0c;是因为它能够迅速影响多个关键因素。通过测评&#xff0c;您能够快速提升关键词的转化率&#xff0c;从而获得更好的搜索排名。优质的评价有助于增加产品的权重和转化率&#xff0c;进一步提升排名。同时&#xff0c;增加的…

在Windows环境下安装pycharm

Python环境搭建 第一步下载安装python 等待安装完成 验证python是否安装成功 Python开发工具安装部署 JetBrains: Essential tools for software developers and teams PyCharm: the Python IDE for data science and web development 下载社区版本的PyCharm 双击打开下载好的…

花几千上万学习Java,真没必要!(一)

1、主流的操作系统&#xff1a; 目前主流的PC端操作系统包括Windows、Mac OS和Linux。其中Windows是由微软公司开发的操作系统&#xff0c;Mac OS是由苹果公司开发的操作系统&#xff0c;而Linux则是开放源代码的操作系统&#xff0c;它有很多的发行版&#xff1a;比如&#xf…