基于STM32的多组外部中断(EXTI)的优化策略与应用

news2025/1/17 0:27:39

在某些嵌入式应用中,可能需要同时处理多个外部中断事件。STM32系列微控制器提供了多组外部中断线(EXTI Line),可以同时配置和使用多个GPIO引脚作为外部中断触发器。为了有效管理和处理多组外部中断,我们可以采取一些优化策略和技术。

以下是基于STM32的多组外部中断的优化策略和应用的概述,并提供了一些关键代码示例:

策略1:GPIO和优先级管理

在使用多组外部中断时,首先需要合理规划和管理GPIO引脚的分配。可以使用不同的GPIO组或端口用于不同的外部中断,以避免冲突和干扰。

其次,需要合理配置中断优先级,确保较高优先级的中断能够快速响应和处理。优先级的配置涉及到中断控制器(NVIC)以及中断优先级分组的设置。

示例代码:

```c
// 配置GPIO引脚用于外部中断1
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; // 选择引脚A0作为外部中断触发器1
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);

// 配置GPIO引脚用于外部中断2
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; // 选择引脚B5作为外部中断触发器2
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);

...

// 配置并使能外部中断1
EXTI_InitTypeDef EXTI_InitStruct;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); // 外部中断1映射到GPIOA.0
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);

// 配置并使能外部中断2
EXTI_InitTypeDef EXTI_InitStruct2;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource5); // 外部中断2映射到GPIOB.5
EXTI_InitStruct2.EXTI_Line = EXTI_Line5;
EXTI_InitStruct2.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct2.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct2.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct2);

...

// 配置中断优先级和使能
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct1;
NVIC_InitStruct1.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct1.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct1.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct1.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct1);

NVIC_InitTypeDef NVIC_InitStruct2;
NVIC_InitStruct2.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStruct2.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct2.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct2.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct2);
```

策略2:共享资源和并发处理

当使用多组外部中断时,可能会涉及到共享资源和并发处理的情况。例如,可能同时需要访问共享的外设寄存器或数据结构。在这种情况下,需要合理处理共享资源的控制和同步,以避免竞争条件和数据不一致。

常见的做法是使用互斥锁/信号量或其他同步机制来保护共享资源。在中断服务函数中,尽量减少对共享资源的直接访问,可以通过将中断事件信息传递给任务(通过队列或标志等方式),在任务中处理共享资源。

策略3:中断服务函数的优化

在处理多组外部中断时,中断服务函数的优化也非常重要。中断服务函数应尽可能地简洁、高效,并尽量避免长时间占用中断线。

示例代码:

```c
void EXTI0_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        // 处理外部中断1事件
        // ...

        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

void EXTI9_5_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line5) != RESET)
    {
        // 处理外部中断2事件
        // ...

        EXTI_ClearITPendingBit(EXTI_Line5);
    }
}
```

总结:

在基于STM32的多组外部中断的应用中,需要合理管理GPIO和中断优先级,以充分利用多组外部中断线。同时,需要处理共享资源的同步和并发访问,以避免竞争条件和数据不一致。另外,编写高效的中断服务函数也是关键,要尽量减少中断响应时间和中断占用时间。

嵌入式物联网的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而错失高薪offer。不过别担心,我为大家整理了一份150多G的学习资源,基本上涵盖了嵌入式物联网学习的所有内容。点击这里,0元领取学习资源,让你的学习之路更加顺畅!记得点赞、关注、收藏、转发哦。 

​ 点击链接扫码进入嵌入式交流群 ​https://fss.mpay8.cn/article/dmrjinh2C6fjejm

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

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

相关文章

[CISCN 2023 初赛]ezbyte

从字符串找到%100s,发现下面有个yes 跟踪yes 、 yes之前有个jmp 看上面的代码,要想跳转到含有yes这一块,需要r13等于r12 xor r13,r13说明r13是0,但是找不到r12的操作代码 实际着这个关键的操作r12的加密逻辑&…

STM32外部中断(EXTI)与RTOS多任务处理的协同设计

当在STM32上使用外部中断(EXTI)与RTOS(Real-Time Operating System,实时操作系统)进行多任务处理时,需要设计合适的协同机制,以确保可靠的中断处理和任务调度。在下面的概述中,我将介…

微机原理_12

一、单项选择题(本大题共15小题,每小题3分,共45分。在每小题给出的四个备选项中,选出一个正确的答案。〕 十进制正数56的 8位二进制补码是()。 A. 00011001 B. 10100110 C. 10011001 D. 00100110 若栈顶的物理地址为20100H,当执行完指令PUSH…

Day34力扣打卡

打卡记录 合并石头的最低成本(区间DP) 链接 与多边形的三角形问题相同,将大问题化小问题,再用中间节点不断地寻找最值。 class Solution:def mergeStones(self, stones: List[int], k: int) -> int:n len(stones)if (n - 1…

2023年中职“网络安全“—Web 渗透测试②

2023年中职“网络安全“—Web 渗透测试② Web 渗透测试任务环境说明:1.访问http://靶机IP/web1/,获取flag值,Flag格式为flag{xxx};2.访问http://靶机IP/web2/,获取flag值,Flag格式为flag{xxx};3.访问http://靶机IP/web…

安卓环境搭建及运行安卓应用

1 jdk安装 安卓项目也是java开发的,运行在虚拟器上,安装jdk及运行的时候,就会带上虚拟器 jdk前面已经讲过,不在讲解 2 下载安装androj studio https://developer.android.google.cn/studio?hlzh-cn 下载下来,双击…

选硬币该用动态规划

选硬币&#xff1a; 现有面值分别为1角1分&#xff0c;5分&#xff0c;1分的硬币&#xff0c;请给出找1角5分钱的最佳方案。 #include <iostream> #include <vector>std::vector<int> findChange(int amount) {std::vector<int> coins {11, 5, 1}; /…

【每日一题】—— C. Yarik and Array(Codeforces Round 909 (Div. 3))(贪心)

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…

【实用技巧】更改ArduinoIDE默认库文件位置,解放C盘,将Arduino15中的库文件移动到其他磁盘

本文主要介绍更改Arduino IDE &#xff08;含2.0以上版本&#xff09;默认库文件位置的方法。 原创文章&#xff0c;转载请注明出处&#xff1a; 【实用技巧】解放系统盘&#xff0c;更改ArduinoIDE默认库文件位置&#xff0c;将Arduino15中的库文件移动到其他磁盘-CSDN博客文…

Python (十) 元组

元组 元组与列表类似&#xff0c;不同之处在于元组的元素不能修改。 元组使用小括号 ( )&#xff0c;列表使用方括号 [ ]。 元组创建只需要在括号中添加元素&#xff0c;并使用逗号隔开即可。 访问 tup1 (hello,Java,Python,123,456) print(type(tup1)) print(tup1[1])#输出 …

计算机网络的体系结构

目录 一. 计算机体系结构的形成二. 协议与层次划分2.1 数据传输过程2.2 什么是网络协议2.3 网络协议的三要素2.4 协议有两种形式2.4 各层协议2.5 什么是复用和分用 \quad 一. 计算机体系结构的形成 \quad 计算机网络是一个非常复杂的系统, 相互通信的两个计算机系统必须高度协调…

搜索二叉树(二叉搜索树)的实现(递归与非递归)

一、搜索二叉树的概念 搜索二叉树又称二叉排序树&#xff0c;二叉搜索树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点…

Vue3 源码解读系列(五)——响应式

响应式 响应式的本质是当数据变化后会自动执行某个函数。 映射到组件的实现就是&#xff0c;当数据变化后&#xff0c;会自动触发组件的重新渲染。 响应式的两个核心流程&#xff1a; 依赖收集派发通知 Vue2 Vue2 中只有 data 中定义的数据才是响应式的&#xff0c;因为 d…

从底层认识哈希表【C++】

目录 一. unordered系列关联式容器 二. unordered_map的文档介绍 接口使用 三. 底层实现 &#xff08;1&#xff09;哈希概念 例&#xff1a; &#xff08;2&#xff09;哈希冲突 &#xff08;3&#xff09;冲突解决 1.闭散列​​​​​​​ 闭散列框架 插入 查找 删除 2.开散…

中国净初级生产力年度合成产品NPP(MYD17A3H.006)

中国净初级生产力年度合成产品NPP&#xff08;MYD17A3H.006&#xff09;由航天宏图实验室提供&#xff0c;根据NASA MODIS数据&#xff08;MYD17A3H.006&#xff09;通过航天宏图 Smoother计算得到的平滑后NPP产品&#xff0c;解决了影像云雾覆盖、像元异常值等问题。对处理后的…

黑群晖断电导致存储空间已损毁修复记录

黑群晖断电2次&#xff0c;担心的事情还是发生了&#xff0c;登录后提示存储空间已损毁...... 开干&#xff01;&#xff01; 修复方式&#xff1a; 1.使用SSH登录到群晖&#xff0c;查看相关信息 # 登录后先获取最高权限 rootDiskStation:~# sudo -i # 检测存储池状态 root…

2、LeetCode之两数相加

给你两个非空的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照逆序的方式存储的&#xff0c;并且每个节点只能存储一位数字。请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。你可以假设除了数字0之外&#xff0c;这两个数都不会以0开头。 输入&am…

循环队列(出队、入队、判空、长度、遍历、取头)(数据结构与算法)

循环队列 涉及到移动、赋值原队列参数的函数参数列表如front&#xff0c;rear&#xff0c;都最好别用&引用&#xff0c;否则会修改原队列中的地址和数值如&#xff1a;SqQueue &Q 使用SqQueue Q作参数列表时&#xff0c;函数引入的只是一份副本&#xff0c;不会修改原队…