当前位置: 首页 > news >正文

【雅特力AT32】外部中断事件控制器EXINT(附源码解析)

基础概念弄懂了之后,对于实际开发中断初始化流程寄存器查阅是很重要的。

1.EXINT介绍

2.功能描述和配置流程

中断初始化流程☆

​ 1>选择中断源
​ 2>选择触发方式
​ 3>使能中断或事件
​ 4>产生软件触发
​ 中断清除流程
​ 其他注意点

3.EXINT寄存器描述
4.例程源码分析(初始化源码)

文末附上按键中断配置(基于AT32)、定时器中断配置(AT32、STM32)、ADC接收中断 代码及分析。

但是注意:AT32定时器中断是特定外设(比如定时器模块)自带的一种中断类型,通常不是挂在外部中断线上。


1. EXINT介绍

EXINT 共计有 25 条中断线 EXINT_LINE[28:0] (其中位 19、20、24、27 为保留位),每条中断线均支持通过边沿检测触发s来产生中断或事件。

EXINT 可以根据软件配置,独立的使能或禁止中断或事件,并采取不同的边沿检测方式(检测上升沿或检测下降沿或同时检测上升沿和下降沿)以及触发方式(边沿检测触发或软件触发或边沿检测和软件同时触发)响应触发源独立的产生中断或事件。

在这里插入图片描述

EXINT 控制器的主要特性:

	中断线0~15所映射的IO可以独立的配置
	每个中断线都有独立的触发方式选择
	每个中断都有独立的使能位
	每个事件都有独立的使能位
	共25个可独立产生和清除的软件触发
	每个中断都有独立的状态位
	每个中断都可以被独立的清除

2. 功能描述和配置流程

​ EXINT 共计有 25 条中断线 EXINT_LINE[28:0] (其中位 19、位 20、位 24、位 27 为保留位),可以通过边沿检测的方式分别检测来自 GPIO 的外部中断源以及包括 PVM 输出,ERTC 闹钟事件ERTC 入侵事件和时间戳事件ERTC 唤醒事件OTGFS 唤醒事件USART1/USART2/USART3 唤醒事件以及 I2C1 唤醒事件共九种芯片内部的中断源;

​ 其中来自 GPIO 的中断源可以通过软件编程配置 SCFG 中的复用外部中断配置寄存器 x(SCFG_EXINTCx)灵活的选择,需要注意的是这些输入源是互斥的,例如EXINT_LINE0 只能选择 PA0/PB0/PC0/PD0…中的某一个,而不能同时选择 PA0 和 PB0 作为输入源。

​ EXINT支持多种边沿检测方式,每条中断线可以通过软件编程配置极性配置寄存器1(EXINT_POLCFG1)和极性配置寄存器 2(EXINT_POLCFG2)独立的选择上升沿检测或下降沿检测或同时进行上升沿和下降沿检测,中断线上检测到的有效边沿触发可以用于产生事件或中断。

​ EXINT 支持独立的软件触发产生中断或事件,即除了来自中断线上的有效边沿外,用户可以通过软件编程配置软件触发寄存器(EXINT_SWTRG)对应位来产生对应的中断或事件。

​ EXINT 具备独立的中断和事件使能位,用户可以通过软件编程配置中断使能寄存器(EXINT_INTEN)和事件使能寄存器(EXINT_EVTEN)来使能或关闭对应的中断或事件,这意味着无论是通过边沿检测还是软件触发产生中断或事件,都需要提前使能对应的中断或事件。

​ EXINT 具备独立的中断状态位,用户可以通过中断状态寄存器(EXINT_INTSTS)读取对应的中断状态并通过对该寄存器相应位写 1 来清除已置位的状态标志。

中断初始化流程☆
1> 选择中断源

即配置复用外部中断配置寄存器 x(SCFG_EXINTCx)(如果需要使用 GPIO 作为中断源需要该步骤)。

2> 选择触发方式

即配置极性配置寄存器 1(EXINT_POLCFG1)和极性配置寄存器 2(EXINT_POLCFG2)。

3> 使能中断或事件

即配置中断使能寄存器(EXINT_INTEN)和事件使能寄存器(EXINT_EVTEN)。

4> 产生软件触发

即配置软件触发寄存器(EXINT_SWTRG)产生软件触发(此步骤仅适用于需软件触发产

生中断的应用)。

中断清除流程

清除标志,即对中断状态寄存器(EXINT_INTSTS)对应位写 1 来清除已产生的中断,同时该操作会同步清除软件触发寄存器(EXINT_SWTRG)中的对应位

其他注意点

若需要更改中断源配置,应先关闭中断使能寄存器和事件使能寄存器后,再重新开始中断初始化流程的配置。


3. EXINT寄存器描述

下表列出了 EXINT 寄存器的映像和复位值。

必须以字(32 位)的方式操作这些外设寄存器。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 例程源码分析(初始化源码)
按键中断
/*** @brief  configure button exint* @param  none* @retval none*/
void button_exint_init(void)
{exint_init_type exint_init_struct;crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOA, SCFG_PINS_SOURCE0);exint_default_para_init(&exint_init_struct);exint_init_struct.line_enable = TRUE;exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;exint_init_struct.line_select = EXINT_LINE_0;exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;exint_init(&exint_init_struct);nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);nvic_irq_enable(EXINT0_IRQn, 0, 0);
}
软件触发方式触发 ADC

在这里插入图片描述

/*** @brief  exint configuration.* @param  none* @retval none*/
static void exint_config(void)
{gpio_init_type gpio_initstructure;						//配置GPIO初始化结构体变量exint_init_type exint_init_struct;						//配置外部中断初始化结构体变量crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);		//启用外部中断所需的时钟crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);	//启用相关GPIO端口的时钟crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);	//启用相关GPIO端口的时钟gpio_default_para_init(&gpio_initstructure);				//默认初始化GPIO配置参数结构体/* config exint line 11 and line 15 */gpio_initstructure.gpio_pull           = GPIO_PULL_DOWN;	//下拉电阻gpio_initstructure.gpio_mode           = GPIO_MODE_INPUT;	//输入模式gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;//强驱动gpio_initstructure.gpio_pins           = GPIO_PINS_11;gpio_init(GPIOC, &gpio_initstructure);gpio_initstructure.gpio_pull           = GPIO_PULL_DOWN;gpio_initstructure.gpio_mode           = GPIO_MODE_INPUT;gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_initstructure.gpio_pins           = GPIO_PINS_15;gpio_init(GPIOA, &gpio_initstructure);/* 配置外部中断线,指定要使用的GPIO端口和引脚 */scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOC, SCFG_PINS_SOURCE11);	scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOA, SCFG_PINS_SOURCE15);exint_default_para_init(&exint_init_struct);		//初始化外部中断配置参数结构体exint_init_struct.line_enable = TRUE;				//使能外部中断线exint_init_struct.line_mode = EXINT_LINE_EVENT;	//设置触发模式为事件触发exint_init_struct.line_select = EXINT_LINE_11;	//选择外部中断线11作为配置的外部中断线exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;	//上升沿触发exint_init(&exint_init_struct);					//按照结构体配置初始化/*对外部中断线15进行配置时,会继承之前的触发设置,包括上升沿触发*/exint_init_struct.line_select = EXINT_LINE_15;	//选择外部中断线15作为配置的外部中断线exint_init(&exint_init_struct);					//按照结构体配置初始化
}//NVIC中断优先级在后续ADC和DMA初始化里面自行配置
定时器中断

这里讲一下:

定时器中断一般指定时器的计数器溢出中断;

其他常见的定时器中断类型包括:

1. 比较匹配中断:当定时器计数器的值匹配预设的比较值时,会产生比较匹配中断。这种中断可以用于实现定时器的 PWM(脉冲宽度调制)功能或者其他需要在特定计数值触发的操作。
2. 输入捕获中断:定时器可以用于捕获外部信号的时间信息,当输入信号发生边沿变化时,可以产生输入捕获中断。
3. 输出比较中断:定时器可以用于生成输出信号,当定时器计数器的值匹配预设的比较值时,可以产生输出比较中断。
4. PWM 中断:	 在使用定时器实现 PWM 输出时,可能会配置 PWM 输出比较中断,用于控制 PWM 的输出状态。
												/* stm32定时器初始化 + 中断使能 */
void Tim3_Int_Init(u16 arr,u16 psc)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器时钟TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStruct.TIM_Period = arr;TIM_TimeBaseInitStruct.TIM_Prescaler = psc;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);//初始化定时器TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//开启定时器中断NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;NVIC_Init(&NVIC_InitStruct);//配置NVICTIM_Cmd(TIM3,ENABLE);//使能定时器
}void TIM3_IRQHandler(void)
{if(TIM_GetITStatus(TIM3,TIM_IT_Update) == 1)//检查是否更新中断{TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除更新中断标志LED1 = !LED1;}}
										/* AT32定时器初始化 + 生成外部中断事件 */
void exint_line4_config(void);		//配置外部中断线4
static void tmr1_config(void);		//定时器1初始化//uint8_t i,num,num1 = 0;/*** @brief  exint line4 config. configure pa0 in interrupt mode* @param  None* @retval None*/
void exint_line4_config(void)
{exint_init_type exint_init_struct;crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);			//启用外设时钟exint_default_para_init(&exint_init_struct);					//初始化外部中断配置结构exint_init_struct.line_enable = TRUE;							//启用外部中断线exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;			//置外部中断模式为中断模式exint_init_struct.line_select = EXINT_LINE_4;					//选择外部中断线4exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;	//设置触发极性为上升沿触发exint_init(&exint_init_struct);		//初始化外部中断exint_flag_clear(EXINT_LINE_4);		//清除外部中断标志nvic_irq_enable(EXINT4_IRQn, 0, 1);	//使能外部中断4的 NVIC 中断
}/*** @brief  tmr1 configuration.* @param  none* @retval none* 配置定时器1,使其以1Hz的频率触发溢出中断,并在溢出时执行相应的中断处理程序*/
static void tmr1_config(void)
{crm_clocks_freq_type crm_clocks_freq_struct = {0};	//定义并初始化系统时钟频率结构体/* get system clock */crm_clocks_freq_get(&crm_clocks_freq_struct);			//获取系统时钟频率crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);	//启用定时器1的外设时钟/* (systemclock / (system_core_clock/10000)) / 10000 = 1Hz(1s) *//* 设置定时器1的基本参数,包括计数器的重载值和预分频器的值,以实现1Hz(1秒)的定时功能 */tmr_base_init(TMR1, 10000-1, system_core_clock/10000-1);	//初始化定时器基本参数:能推出 TMR1 的时钟源为系统时钟tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);						//设置定时器计数方向为向上计数tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1);			//设置定时器时钟源分频tmr_interrupt_enable(TMR1, TMR_OVF_INT, TRUE);			//使能定时器1的溢出中断nvic_irq_enable(TMR1_OVF_TMR10_IRQn, 0, 0);				//使能定时器1的 NVIC 中断
}/*** @brief  tmr1 interrupt handler* @param  none* @retval none当定时器溢出时切换LED灯状态并生成exint软件中断事件,外部中断线4触发时切换LED灯状态*/
void TMR1_OVF_TMR10_IRQHandler(void)
{//检查定时器溢出中断标志位是否被设置:定时中断if(tmr_interrupt_flag_get(TMR1,TMR_OVF_FLAG) != RESET)	{//生成exint软件中断事件(触发1s定时器中断):EXINT_LINE_4at32_led_toggle(LED2);//	  printf("1s counter: %d\r\n", num1++);exint_software_interrupt_event_generate(EXINT_LINE_4);tmr_flag_clear(TMR1,TMR_OVF_FLAG);}
}/*** @brief  exint4 interrupt handler* @param  none* @retval none*/
void EXINT4_IRQHandler(void)
{//检查外部中断标志位是否被设置if(exint_interrupt_flag_get(EXINT_LINE_4) != RESET){at32_led_toggle(LED3);at32_led_toggle(LED4);
//	if(i++ == 3)	//三秒一次中断
//	{
//		delay_us(5);
//		printf("3s counter: %d\r\n", num++);
//		i = 0;
//	}exint_flag_clear(EXINT_LINE_4);}
}

相关文章:

【雅特力AT32】外部中断事件控制器EXINT(附源码解析)

基础概念弄懂了之后,对于实际开发中断初始化流程和寄存器查阅是很重要的。 1.EXINT介绍 2.功能描述和配置流程 中断初始化流程☆ ​ 1>选择中断源 ​ 2>选择触发方式 ​ 3>使能中断或事件 ​ 4>产生软件触发 ​ 中断清除流程 ​ 其他注意点 3.EXINT寄存…...

Redis集群_cluster

cluster集群 cluster翻译就是集群,所以cluster集群也叫做redis集群相比于哨兵模式,cluster集群能支持扩容,并且无需额外的节点来监控状态,所以使用这种模式集群的系统会用的更多些redis cluster采用的是去中心化网络拓扑架构&…...

jdk相关介绍

JDK,全称Java Development Kit,是Java语言开发的基础工具包。它包含了Java运行时环境(JRE)以及用于开发Java应用程序的各种工具和库。JDK为Java程序员提供了编译、调试和运行Java应用程序所需的全部环境。 JDK的主要组成部分包括&…...

【GoMate框架案例】讯飞大模型RAG智能问答挑战赛top10 Baseline

【RAG框架】GoMate:RAG Framework within Reliable input,Trusted output 【项目链接】:https://github.com/gomate-community/GoMate 一、赛题背景 RAG(检索增强生成)是一种结合了检索模型和生成模型的技术,它通过检…...

2024/9/15 408“回头看”之应用层小总结(下)

域名系统DNS: 本地域名服务器 本地域名服务器起着代理的作用,会将报文转发到根域名服务器、顶级域名服务器、权限域名服务器。 递归查询: 迭代查询: 文件传送协议FTP: FTP客户和FTP服务器之间使用的是tcp连接。 控制连接使用21端口&…...

经纬恒润高压电池管理系统,助力新能源汽车飞速发展

随着新能源汽车行业的快速发展,电池管理系统作为关键技术之一,其重要性日益凸显。经纬恒润自主研发的高压电池管理系统(Battery Management System,BMS),凭借卓越的性能与先进的技术,在新能源汽…...

一文速通calcite结合flink理解SQL从文本变成执行计划详细过程

文章目录 你可以学到啥测试代码背景知识SQL转变流程图问题 你可以学到啥 SQL如何一步步变成执行计划的有哪些优化器,哪些优化规则calcite 和flink 如何结合的 测试代码 EnvironmentSettings settings EnvironmentSettings.inBatchMode(); TableEnvironment tabl…...

spring-TransactionTemplate 编程式事务

TransactionTemplate 是 Spring 框架提供的用于管理事务的一种方式。它提供了一种编程式的事务管理方法,允许开发者在代码中显式地控制事务的开始、提交或回滚。与使用 Transactional 注解相比,TransactionTemplate 提供了更多的灵活性和控制力。 为什么…...

中考全国45套(全国教育发达地区中考试卷)

文章目录 获取方式 为什么选择这份资源? 权威性与全面性:我们精心搜集了全国教育发达地区的最新中考试卷,确保每一套试卷都代表了该地区的教学水平和考试趋势。这不仅涵盖了丰富的知识点,还融入了各地独特的命题风格,让…...

嵌入式Linux学习笔记(5)-进程间常见通讯方式(c语言实现)

一、概述 进程间通信(IPC,InterProcess Communication)是指在多个进程之间进行数据传输和共享的机制。在操作系统中,进程是运行中的程序的实例,每个进程都有自己的内存空间和资源。 进程间通信可以用于在不同的进程之间…...

【移动端】菜单的自动展开与收回

前言 为了满足手机上菜单栏随用户移动,菜单的自动展示与隐藏,特此记录 基本原理 实现逻辑 window.addEventListener(‘scroll’, debouncedScrollHandler) – 监听文档视图滚动事件 document.querySelector(‘.header’) – 选择器匹配元素 创建show和h…...

Java获取Object中Value的方法

在Java中,获取对象(Object)中的值通常依赖于对象的类型以及我们希望访问的属性。由于Java是一种静态类型语言,直接从一个Object类型中访问属性是不可能的,因为Object是所有类的超类,但它本身不包含任何特定…...

集群聊天服务器项目【C++】(二)Json的简单使用

在上一章中,简单介绍了本项目的内容、技术栈、需求和目标等,详细介绍了环境配置,如果还没有配置成功,请参考我的上一篇博客环境配置 今天主要介绍Json库是什么以及简单的使用。 1.为什么要使用Json 我们在网络传输数据时&#…...

班迪录屏和这三款录屏工具,一键操作,太方便了!

嘿,小伙伴们!今天我要跟大家分享几款超棒的录屏工具,它们绝对是我们在工作和学习中不可或缺的好帮;这些工具功能强大且操作简单,下面就让我来详细介绍一下它们的使用体验和好用之处吧! 班迪录屏工具使用体…...

DAY60Bellman_ford 算法

队列优化算法 请找出从城市 1 到城市 n 的所有可能路径中,综合政府补贴后的最低运输成本。 如果能够从城市 1 到连通到城市 n, 请输出一个整数,表示运输成本。如果该整数是负数,则表示实现了盈利。如果从城市 1 没有路径可达城市…...

Dubbo SPI源码

文章目录 Dubbo SPI使用方式AOP功能源码剖析SPI注解1.获取加载器2.获取拓展实例对象3.创建拓展类的实例对象 Dubbo SPI Dubbo 的 SPI(Service Provider Interface)机制是一种强大的扩展机制,它允许开发者在运行时动态地替换或增加框架的功能。…...

《C++代码高度优化之双刃剑:避免过度优化引发的“暗雷”》

在 C编程的世界里,追求高效性能的代码是每个开发者的目标之一。高度优化的 C代码可以带来显著的性能提升,让程序在运行速度、内存占用等方面表现出色。然而,正如一把双刃剑,过度优化可能会引入难以察觉的错误,给程序带…...

javascript网页设计案例

设计一个具有良好用户体验的 JavaScript 网页涉及多个方面,如用户界面(UI)、用户体验(UX)、交互设计等。以下是一些示例案例,展示了如何使用 JavaScript 创建功能丰富且吸引人的网页设计。 1. 响应式导航菜…...

初阶数据结构【TOP】- 11.普通二叉树的介绍 - 1. (细致,保姆~~!)

文章目录 前言一、普通二叉树的链式结构二、 造树三、普通二叉树的遍历四、遍历完整代码五、总结 前言 本篇文章笔者将会对普通二叉树部分进行细致的讲解 , 本篇主要包括以下内容: 二叉树链式结构的介绍 ,二叉树的遍历. 笔者会一步一步分析带学者领略递归的美好~~ 一、普通二叉…...

【pyenv】pyenv安装版本超时的解决方案

目录 1、现象 2、分析现象 3、手动下载所需版本 4、存放到指定路径 5、重新安装 6、pip失败(做个记录,未找到原因) 7、方法二修改环境变量方法 7.1 设置环境变量 7.2 更新 7.3 安装即可 8、方法三修改XML文件 前言:研…...

【新片场-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…...

新160个crackme - 057-bbbs-crackme04

运行分析 因软件版本老旧,需使用windows XP虚拟机运行有个SystemID,值为12345678需破解User ID和Password PE分析 yC壳,32位 OD手动脱壳 使用windows XP虚拟机,将程序拖入OD按一下F8,ESP变红,根据ESP定律设…...

车机中 Android Audio 音频常见问题分析方法实践小结

文章目录 前言1. 无声2. 断音3. 杂音4. 延迟播放5. 焦点问题6. 无声问题(连上 BT )其他完善中…… 前言 本文主要总结了一下车机开发中遇到的 Audio 有关的问题,同时参考网上的一案例,由于Audio 模块出现音频问题的场景很多,对每一个出现的问…...

湘大 OJ 代码仓库

有时候不需要上传一些题解,想要上传一些纯代码就行,傻傻把代码上传到文章里面,感觉效率不是很高,还是建立一个代码仓库比较方便 需要会使用魔法可能才能访问,github代码仓库地址...

Ruoyi Cloud K8s 部署

本文视频版本:https://www.bilibili.com/video/BV1xF4Se3Esv 参考 https://blog.csdn.net/Equent/article/details/137779505 https://blog.csdn.net/weixin_48711696/article/details/138117392 https://zhuanlan.zhihu.com/p/470647732 https://gitee.com/y_project/Ruo…...

OpenGL Texture C++ Camera Filter滤镜

基于OpenGL Texture纹理的强大功能,在片段着色器(Shader)中编写GLSL代码,对YUV的数据进行数据转换从而实现视频编辑软件中的相机滤镜功能。 接上一篇OpenGL Texture C 预览Camera视频的功能实现,本篇来实现Camera滤镜效…...

基于Sobel算法的边缘检测设计与实现

1、边缘检测 针对的时灰度图像,顾名思义,检测图像的边缘,是针对图像像素点的一种计算,目的时标识数字图像中灰度变化明显的点,图像的边缘检测,在保留了图像的重要结构信息的同时,剔除了可以认为…...

java:练习

编写一个 Java 程序,计算并输出从 1 到用户指定的数字 n 中,所有“幸运数字”。幸运数字的定义如下:条件 1:数字的所有位数(如个位、十位)加起来的和是 7 的倍数。条件 2:数字本身是一个质数&am…...

大数据中一些常用的集群启停命令

文章目录 一、HDFS二、MapReduce && YARN三、Hive 一、HDFS 格式化namenode # 确保以hadoop用户执行 su - hadoop # 格式化namenode hadoop namenode -format启动 # 一键启动hdfs集群 start-dfs.sh # 一键关闭hdfs集群 stop-dfs.sh# 如果遇到命令未找到的错误&#…...

Golang、Python、C语言、Java的圆桌会议

一天,Golang、C语言、Java 和 Python 四位老朋友坐在编程领域的“圆桌会议”上,讨论如何一起完成一个任务:实现一个简单的高并发服务器,用于处理成千上万的请求。大家各抒己见,而 Golang 则是这次会议的主角。 1. Pyth…...