关键函数:

  • NVIC_EnableIRQ(IRQn_Type IRQn):使能中断

例5-1:单按键中断方式实现led灯的亮灭

在上一讲LP-MSPM0G3507学习--04GPIO控制中实现了通过按键控制led灯的亮灭,可以看出程序效率不高,下面采用中断的方式实现,其中的配置大部分相同,除了将管脚buttoninterrupts设置为中断:

 需要注意的是触发极性(triggler polarity),有4种:

  •  diabled--可能是电平触发(此时应该是低电平触发,因为有上拉电阻了)
  • trigger on rising edge--上升沿触发
  • trigger on falling edge--下降沿触发
  • trigger on both Edg--双边沿触发

从电路中可以看出,PB21应该上拉电阻,且采用边沿触发时,中断触发方式应该设为下降沿触发

#include "ti_msp_dl_config.h"int main(void)
{SYSCFG_DL_init();NVIC_EnableIRQ(GPIOB_INT_IRQn);//开启按键引脚的GPIOB端口中断while (1) {}
}
void GROUP1_IRQHandler(void){//GPIO中断服务函数DL_GPIO_togglePins(LED_PORT,LED_LED1_PIN);
}

分析:

这里涉及到两个函数NVIC_EnableIRQ(),GROUP_IRQ_IRQHandler()

首先了解,NVIC,即嵌套矢量中断控制器,用来管理外设中断。有关的函数在ti\mspm0_sdk_2_05_01_00\source\third_party\CMSIS\Core\include\core_cm0plus.h中

另外,中断号定义在i\mspm0_sdk_2_05_01_00\source\ti\devicws\msp\mspmog350x.h中

查阅数据手册的时候,发现3507中只有两个外设中断组:INT_GROUP0、INT_GROUP1.本实验要用到的只有按键和LED,所以只有GPIO这一部分的中断,根据数据手册,可以知道GPIO的中断触发后,都是通过GRP1线将中断发布到总线,总线识别到之后就进入中断服务函数中执行内容。

GPIO引脚的中断服务函数(ISR)需在代码中直接定义,其位置和声明方式遵循以下核心规则:

1. 中断服务函数的定义位置

  • 直接在C文件中实现:GPIO中断属于INT_GROUP1组,因此中断服务函数必须命名为 GROUP1_IRQHandler,并在工程内的C文件(如main.c或自定义的ISR文件)中实现。
    示例代码:

     void GROUP1_IRQHandler(void) { // 中断处理逻辑 }


    无需头文件声明:此函数是ARM Cortex-M预定义的中断向量之一,由链接脚本自动关联到中断向量表,无需在头文件中显式声明9。


2. 函数内部处理逻辑

GROUP1_IRQHandler内,需通过以下步骤区分具体的中断源(如不同GPIO引脚):

  1. 查询中断索引(IIDX)
    使用DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)获取触发中断的外设索引。

  2. 判断GPIO端口
    通过switch-case匹配GPIO端口的IIDX宏(如GPIOA_INT_IIDXGPIOB_INT_IIDX)。

  3. 检查具体引脚状态
    若同一端口有多个引脚使能中断,需调用DL_GPIO_getEnabledInterruptStatus()并检查引脚位掩码

完整示例:

void GROUP1_IRQHandler(void) {switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {case DL_INTERRUPT_GROUP1_IIDX_GPIOA:  // GPIOA中断uint32_t status = DL_GPIO_getEnabledInterruptStatus(GPIOA);if (status & GPIO_PIN_12) {       // 检查PA12引脚DL_GPIO_togglePins(GPIO_LED_PORT, GPIO_LED_PIN);DL_GPIO_clearInterruptStatus(GPIOA, GPIO_PIN_12); // 清除标志}break;// 其他GPIO端口处理...}
}

3. 配置与使能中断

  • SysConfig图形化配置
    在CCS的SysConfig工具中需启用GPIO中断,设置触发边沿(如下降沿),并指定引脚。

  • 代码使能中断
    主函数中调用NVIC_EnableIRQ(GPIOx_INT_IRQN)(如GPIOA_INT_IRQn)激活NVIC中断。


4. 关键注意事项

  • 中断标志清除
    在ISR内必须清除中断标志,否则会重复触发。使用DL_GPIO_clearInterruptStatus()DL_Interrupt_clearFlag()

  • 变量声明
    跨中断共享的变量(如delay_time)需加volatile关键字防止优化错误。

  • 调试陷阱
    若未正确定义GROUP1_IRQHandler,程序可能跳转至默认错误处理(如死循环)。建议添加调试断点(__BKPT(0))辅助排查。

附:GPIO中断相关宏定义示例

宏名称作用示例值
GPIO_SWITCHES_GPIOA_INT_IRQNGPIOA中断号GPIOA_INT_IRQn
DL_INTERRUPT_GROUP1_IIDX_GPIOAGPIOA在GROUP1中的索引由SDK头文件定义
GPIO_SWITCHES_USER_SWITCH_1_PIN具体引脚宏DL_GPIO_PIN_12

附:其他的中断名: 

其他的一些中断名为(定义在C:\ti\mspm0_sdk_2_05_01_00\source\ti\devices\msp\m0p\startup_system_files\ticlang\startup_mspm0g350x_ticlang.c)中:

extern void GROUP0_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void GROUP1_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void TIMG8_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void UART3_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void ADC0_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void ADC1_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void CANFD0_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void DAC0_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void SPI0_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void SPI1_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void UART1_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void UART2_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void UART0_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void TIMG0_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void TIMG6_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void TIMA0_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void TIMA1_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void TIMG7_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void TIMG12_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void I2C0_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void I2C1_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void AES_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void RTC_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));
extern void DMA_IRQHandler(void)__attribute__((weak, alias("Default_Handler")));

中断号定义在ti\mspm0_sdk_2_05_01_00\source\ti\devices\msp\m0p\mspm0g350x.h

typedef enum IRQn
{NonMaskableInt_IRQn         = -14,    /* 2  Non Maskable Interrupt */HardFault_IRQn              = -13,    /* 3  Hard Fault Interrupt */SVCall_IRQn                 = -5,     /* 11 SV Call Interrupt */PendSV_IRQn                 = -2,     /* 14 Pend SV Interrupt */SysTick_IRQn                = -1,     /* 15 System Tick Interrupt */SYSCTL_INT_IRQn             = 0,      /* 16 SYSCTL_INT Interrupt */WWDT1_INT_IRQn              = 0,      /* 16 WWDT1_INT Interrupt */WWDT0_INT_IRQn              = 0,      /* 16 WWDT0_INT Interrupt */FLASHCTL_INT_IRQn           = 0,      /* 16 FLASHCTL_INT Interrupt */DEBUGSS_INT_IRQn            = 0,      /* 16 DEBUGSS_INT Interrupt */GPIOB_INT_IRQn              = 1,      /* 17 GPIOB_INT Interrupt */GPIOA_INT_IRQn              = 1,      /* 17 GPIOA_INT Interrupt */TRNG_INT_IRQn               = 1,      /* 17 TRNG_INT Interrupt */COMP0_INT_IRQn              = 1,      /* 17 COMP0_INT Interrupt */COMP1_INT_IRQn              = 1,      /* 17 COMP1_INT Interrupt */COMP2_INT_IRQn              = 1,      /* 17 COMP2_INT Interrupt */TIMG8_INT_IRQn              = 2,      /* 18 TIMG8_INT Interrupt */UART3_INT_IRQn              = 3,      /* 19 UART3_INT Interrupt */ADC0_INT_IRQn               = 4,      /* 20 ADC0_INT Interrupt */ADC1_INT_IRQn               = 5,      /* 21 ADC1_INT Interrupt */CANFD0_INT_IRQn             = 6,      /* 22 CANFD0_INT Interrupt */DAC0_INT_IRQn               = 7,      /* 23 DAC0_INT Interrupt */SPI0_INT_IRQn               = 9,      /* 25 SPI0_INT Interrupt */SPI1_INT_IRQn               = 10,     /* 26 SPI1_INT Interrupt */UART1_INT_IRQn              = 13,     /* 29 UART1_INT Interrupt */UART2_INT_IRQn              = 14,     /* 30 UART2_INT Interrupt */UART0_INT_IRQn              = 15,     /* 31 UART0_INT Interrupt */TIMG0_INT_IRQn              = 16,     /* 32 TIMG0_INT Interrupt */TIMG6_INT_IRQn              = 17,     /* 33 TIMG6_INT Interrupt */TIMA0_INT_IRQn              = 18,     /* 34 TIMA0_INT Interrupt */TIMA1_INT_IRQn              = 19,     /* 35 TIMA1_INT Interrupt */TIMG7_INT_IRQn              = 20,     /* 36 TIMG7_INT Interrupt */TIMG12_INT_IRQn             = 21,     /* 37 TIMG12_INT Interrupt */I2C0_INT_IRQn               = 24,     /* 40 I2C0_INT Interrupt */I2C1_INT_IRQn               = 25,     /* 41 I2C1_INT Interrupt */AES_INT_IRQn                = 28,     /* 44 AES_INT Interrupt */RTC_INT_IRQn                = 30,     /* 46 RTC_INT Interrupt */DMA_INT_IRQn                = 31,     /* 47 DMA_INT Interrupt */
} IRQn_Type;

例5-2:双按键中断方式实现led灯的亮灭

实现按键S1按键点亮LED1,按键S2熄灭LED1

首先还是配置管脚,从电路原理图中可以看出S1按下为高电平,释放为低电平,所以S1即PA18设定为输入,内部连接下拉电阻,中断触发方式为上升沿;S2按下为低电平,释放为高电平,即PB21设定为输入,内部连接上拉电阻,中断触发方式为下降沿;led1设定为输出,初始值为高,即led初始为熄灭。

#include "ti_msp_dl_config.h"int main(void)
{SYSCFG_DL_init();NVIC_EnableIRQ(GPIOA_INT_IRQn);//开启按键引脚的GPIOA端口中断NVIC_EnableIRQ(GPIOB_INT_IRQn);//开启按键引脚的GPIOB端口中断while (1) {}
}
void GROUP1_IRQHandler(void) {uint32_t status=0; switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {case DL_INTERRUPT_GROUP1_IIDX_GPIOA:  // 处理GPIOA中断status= DL_GPIO_getEnabledInterruptStatus(Buttons_S1_PORT,Buttons_S1_PIN);if (status & Buttons_S1_PIN) {        // 检查PA18引脚DL_GPIO_clearPins(LED_PORT, LED_LED1_PIN);//亮灯DL_GPIO_clearInterruptStatus(Buttons_S1_PORT, Buttons_S1_PIN); // 清除标志}break;case DL_INTERRUPT_GROUP1_IIDX_GPIOB:  // 处理GPIOB中断status= DL_GPIO_getEnabledInterruptStatus(Buttons_S2_PORT,Buttons_S2_PIN);if (status & Buttons_S2_PIN) {        // 检查PB21引脚DL_GPIO_setPins(LED_PORT, LED_LED1_PIN);//熄灯DL_GPIO_clearInterruptStatus(Buttons_S2_PORT, Buttons_S2_PIN); // 清除标志}break;            default:    // 处理其他中断// 完成处理break;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac系统安装、启动Jenkins,创建pytest接口自动化任务

先安装Homebrew:mac系统安装brew-CSDN博客 1、安装Jenkins # 可以安装长期支持版本 brew install jenkins-lts# 或者最新版本(我安了这个) brew install jenkins 可查看Jenkins安装位置: # 最新版本 brew --prefix jenkins 2、…

设置第三方窗口置顶(SetWindowPos方法,vb.net)

起源在日常办公、游戏时,我们经常需要一些窗口处于置顶状态,而这些窗口往往是网页端(浏览器)、办公软件(wps、office等),这些需要置顶的窗口往往自身没有明显的置顶开关,因此&#x…

Docker-下载和安装

一、Linux版 1.安装docker (1)更新软件包索引 sudo apt update (2)安装必要的依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common (3)添加 Docker 官方 GP…

电脑DLL错误修复dll微软运行库工具修复dll缺失找不到dll等问题,dll免费修复工具

解决DLL文件缺失问题:我的使用体验与建议 在使用电脑的过程中,我们常常会遇到软件或系统报错,例如“无法找到指定模块”或“缺少某.dll文件”等提示。DLL(动态链接库)是Windows系统中不可或缺的组件,为应用…

HTTPS的工作原理及DNS的工作过程

HTTPSHTTP协议安全上存在以下三个风险:完整性 可用性 保密性窃听风险,比如通信链路上可以获取通信内容,用户号容易没。篡改风险,比如强制植入垃圾广告,视觉污染,用户眼容易瞎。冒充风险,比如冒充…

VisualXML全新升级 | 新增BusLoad计算

VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。该软件支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此…

李天意考研数学精讲课学习笔记(课堂版)

视频链接:【考研数学精讲课李天意】基础强化真题,概念精讲与解题技巧(适用数学一/二/三)_哔哩哔哩_bilibili 讲义:夸克网盘分享 高数6 不定积分

闲庭信步使用图像验证平台加速FPGA的开发:第二十三课——图像直方图和灰度图像叠加的FPGA实现

(本系列只需要modelsim即可完成数字图像的处理,每个工程都搭建了全自动化的仿真环境,只需要双击top_tb.bat文件就可以完成整个的仿真,大大降低了初学者的门槛!!!!如需要该系列的工程…

C++并发编程-14. 利用栅栏实现同步

前文我们通过原子操作实战实现了无锁队列,今天完善一下无锁的原子操作剩余的知识,包括Relaese和Acquire内存序在什么情况下是存在危险的,以及我们可以利用栅栏机制实现同步等等。 线程可见顺序 我们提到过除了memory_order_seq_cst顺序&#…

如何选择旅游科技行业云ERP?Oracle NetSuite助力汇智国际数智化升级

2025年4月21日,汇智国际旅游发展有限公司(以下简称汇智国际)携手 Oracle NetSuite与Hitpoint Cloud ,共同参与了汇智国际 Oracle NetSuite 云ERP 项目启动会。 本次会议标志着汇智国际在数字化转型道路上迈出了坚实而关键的一步&…

深度学习零基础入门(3)-图像与神经网络

好久不见~我又回来了 这一节我们来讲一讲图像在计算机中的本质,以及全连接神经网络的缺陷,进而引出卷积神经网络一、图像在计算机中的本质 不知道你有没有学过数据结构,在讲这一部分的时候对数组进行了扩展,讲到了广义表和压缩矩阵…

http性能测试命令ab

在 Linux系统中, ab( ApacheBench)是一个用于 测试HTTP服务器性能的 工具。它是 Apache HTTP服务器项目的 一部分,专门设计用来模拟 多个用户对 服务器发起 并发请求,从而 评估服务器的 负载能力和 响应时间其中&#…

从0开始学习R语言--Day50--ROC曲线

对于已经拟合好的生存模型,我们一般会直接用ROC去评判一下整体的水平,因为很多时候阈值都是我们人为根据实际情况去设定的,这种微调的细节都是在整体模型的拟合程度确定下来后再做的工作。ROC曲线可以提供给我们模型对于二分类变量的区分能力…

从Hyperliquid到AILiquid:一场从极致性能到策略智能的迭代

在Hyperliquid以极致性能引爆链上衍生品交易热潮之后,DeFi市场正迎来新一轮的范式转变。作为AI原生的下一代交易平台,AILiquid正式上线并引发市场广泛关注。该平台不仅保留了高频低延迟的交易体验,更通过AI撮合引擎与链上风险控制系统&#x…

磁悬浮轴承转子不平衡质量控制:陷波滤波器深度解析

在磁悬浮轴承高速旋转的世界里,不平衡质量如同一个无形的幽灵,引发危险的同步振动,而陷波滤波器,正是精准捕获并消除这个幽灵的“电磁猎手”。本文将深入剖析其核心原理与实战设计。引言:同步振动的致命诱惑磁悬浮轴承…

Oracle 数据库常见等待事件参数详解

在 Oracle 数据库的性能诊断与优化中,等待事件是重要的分析依据,而理解等待事件的参数则是深入排查问题的基础。本文将结合 Oracle 官方文档,对数据库中常见的等待事件参数进行详细解析,帮助数据库管理员和开发人员更好地解读等待…

STM32中的CAN总线详解:从原理到实战

前言:为什么CAN总线是嵌入式通信的"硬通货"? 在嵌入式通信领域,CAN(Controller Area Network)总线凭借其高可靠性、实时性和多节点通信能力,成为汽车电子、工业控制、智能设备等领域的"标配…

【鸿蒙HarmonyOS】鸿蒙app开发入门到实战教程(二):封装自定义可复用组件

组件的可复用性,对我们开发的app质量影响很大,看看鸿蒙中如何封装这种组件 实现效果代码实现 局部封装 Builder titleBuilder(title:string 默认标题) {// Builder装饰此函数,使其能以链式调用的方式配置并构建Text组件Row(){Text(title).fo…

Volo-HTTP 0.4.0发布:正式支持 HTTP/2,客户端易用性大幅提升!

🤖 VOLO简介 Volo 是由字节跳动服务框架团队开源的一款高性能、易用的 Rust RPC 框架。 Volo 框架自身开销极低,并提供了命令行工具与灵活的中间件设计,让开发者可以轻松上手,享受 Rust 带来的开发乐趣。 本文介绍自 Volo-HTTP 0…

HTTP相关知识

文章目录一、基础特性与规范二、页面元素与布局三、交互与表单四、网络通信基础流程(以浏览器访问网页为例)五、配套技术与工具六、知识关联图(简化版)一、基础特性与规范 技术定位:HTML 是前端技术栈的核心标记语言&…