第四章、NVIC: 外部中断_串口中断
1、按键按下后,GPIO 会产生一个上升/下降沿,G030内部是如何触发外部中断的呢?
配置GPIO引脚:
首先,需要将特定的GPIO引脚配置为输入模式,并设置为外部中断源。这通常通过配置寄存器来完成。
选择触发方式:
在G030中,可以选择上升沿、下降沿或双边沿触发外部中断。这个设置通常在外部中断控制寄存器(如EXTI寄存器)中进行配置。
中断使能:
需要使能对应的外部中断线,以便在GPIO引脚状态变化时能够触发中断。这通常涉及到设置中断使能寄存器。
中断向量表:
当外部中断被触发时,处理器会根据中断向量表跳转到相应的中断服务程序(ISR)。
中断处理:
在ISR中,可以执行特定的操作,例如读取按键状态、切换LED状态等。ISR执行完毕后,处理器会恢复到中断发生前的状态。
常见问题1、基本概念:异常和中断 ? (处理器的内外部)
2、中断意义和作用 ?
3、中断处理过程 ?
4、NVIC 定义?位置 ?
5、中断向量表 ?在哪儿定义 ?
## 2、中断向量表 是一个存储器区域,其中包含了所有中断服务程序(ISR)的入口地址。当中断发生时,处理器会根据中断类型查找对应的入口地址,并跳转到该地址执行相应的ISR。定义位置:
在STM32等微控制器中,中断向量表通常在启动文件(startup file)中定义。启动文件是编译后生成的二进制文件的一部分,通常包含以下内容:
中断向量表的起始地址:通常位于内存的固定地址(如0x00000000)。
中断向量的具体实现:每个中断向量对应一个ISR的地址。
中断向量表示例:
void (* const g_pfnVectors[])(void) attribute ((section(“.isr_vector”))) = {
(void (*)(void))((uint32_t)&_estack), // 栈顶地址
Reset_Handler, // 复位中断
NMI_Handler, // NMI中断
HardFault_Handler, // 硬故障中断
// ... 其他中断向量};
NVIC 工作原理 ?
NVIC 中断优先级及其分组 ? ( 比较原则:抢占 -> 响应 -> 自然 )
3、中断嵌套 ?为什么会发生的嵌套 ?
**优先级机制:**不同中断源可以设置不同的优先级。当一个高优先级的中断在低优先级中断的服务程序执行期间发生时,系统会中断当前的服务程序,转而执行高优先级的中断服务程序。
**中断使能:**在某些微控制器中,ISR可以在执行期间允许其他中断的响应,这样就可能导致中断嵌套。
**硬件设计:**某些微控制器的硬件设计允许中断嵌套,以提高系统的响应能力。
4、外部中断 定义( GPIO 上升沿 下降沿 )
外部中断是指由外部设备或信号触发的中断请求,通常用于响应外部事件,如按键、传感器信号、通信接口等。外部中断允许微控制器在特定事件发生时立即中断当前程序的执行,转而执行相应的中断服务程序(ISR),以处理这些事件。
EXTI工作原理 ? GPIO -> AFIO -> EXTI
5、EXTI支持的触发方式
上升沿触发(Rising Edge Trigger):
当信号从低电平变为高电平时触发中断。
下降沿触发(Falling Edge Trigger):
当信号从高电平变为低电平时触发中断。
双边沿触发(Both Edge Trigger):
当信号在上升沿或下降沿变化时都触发中断。
软件触发(Software Trigger):
通过软件手动触发中断,通常用于调试或特定应用场景。
6、AFIO定义及其工作原理
AFIO(Alternate Function I/O)是STM32微控制器中的一个外设,用于配置和管理引脚的替代功能。它允许用户将某些引脚配置为特定的功能,如外部中断、定时器输入、串口通信等,而不仅仅是普通的GPIO功能。
工作原理:
引脚复用:STM32的每个引脚可以被配置为多种功能。AFIO负责管理这些引脚的复用,确保在不同的外设之间正确分配引脚。
外部中断配置:AFIO可以配置外部中断的触发源。通过设置特定的寄存器,用户可以选择哪个引脚作为外部中断的输入,并指定其触发方式(上升沿、下降沿或双边沿)。
引脚映射:AFIO提供了引脚映射功能,允许用户将外设功能映射到不同的引脚上。这对于设计灵活的电路非常重要,尤其是在资源有限的情况下。
寄存器配置:AFIO的配置通常涉及设置特定的寄存器,如AFIO_MAPR寄存器,用于选择引脚的替代功能。
示例代码:
// 启用AFIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// 配置外部中断线
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); // 将PA0配置为外部中断源
// 配置EXTI触发方式
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line0; // 选择外部中断线0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能外部中断
EXTI_Init(&EXTI_InitStructure);
7、外部中断整体执行流程
中断源配置:
配置外部中断源(如GPIO引脚)以检测特定的事件(如上升沿、下降沿或双边沿)。
设置中断优先级和触发方式。
中断使能:
使能外部中断控制器(如EXTI)和相应的中断线。
确保中断在NVIC(嵌套向量中断控制器)中被使能。
事件触发:
当外部事件发生(如按键按下或释放)时,外部中断被触发。
触发信号会被送到中断控制器。
中断请求:
中断控制器生成中断请求(IRQ),并将其发送到NVIC。
NVIC根据中断优先级决定是否响应该中断。
中断处理:
如果当前没有高优先级中断在执行,NVIC会暂停当前执行的程序,保存上下文。
跳转到相应的中断服务程序(ISR)。
ISR执行:
在ISR中,执行中断处理逻辑,例如读取传感器数据、切换LED状态等。
清除中断标志位,以便下次中断能够被正确触发。
恢复上下文:
ISR执行完毕后,恢复之前保存的上下文。
恢复后,继续执行被中断的程序。
8、NVIC学习
1.NVIC
挂载在AHB下的外设
全称:嵌套向量中断控制器 中断,讲究实时性
异常:由cpu内部发生的错误(不可控),nvic中指的是某个引脚发生上升沿或者下降沿的跳变(触发时机)
中断:由外设引发的错误(可控)
NVIC的中断优先级由优先级寄存器的4位(0-15决定)
抢占优先级高于响应优先级高于自然优先级(抢占和响应,数值小,级别高)
2.AFIO外设
主要用于配置和管理引脚的替代功能
主要功能:
引脚复用:通过 AFIO,可以将多个外设的功能映射到同一组引脚上,从而节省引脚资源。
中断管理:AFIO 还可以用于配置外部中断的触发方式,例如上升沿、下降沿或双边沿触发。
JTAG/SWD 配置:AFIO 允许用户选择是否启用 JTAG 或 SWD 调试接口,以便在开发过程中进行调试。
寄存器:
AFIO 的配置通常涉及到几个寄存器:
AFIO_MAPR:用于配置引脚的复用功能和中断的触发方式。
AFIO_EXTICR:用于配置外部中断的引脚映射。
使用场景:
多功能引脚:在设计中需要使用多个外设时,AFIO 可以帮助实现引脚的灵活配置。
外部中断:在需要响应外部事件时,AFIO 可以配置中断引脚的触发方式。
配置示例:
在 STM32 的开发中,使用 HAL 库或直接操作寄存器来配置 AFIO。例如,配置某个引脚为 USART的TX引脚,通常需要设置相应的AFIO_MAPR寄存器。
与门:都为1才是1 或门:有一个为1就是1
3.EXTI中断流程
PA0-GPIO-AFIO-EXTI-NVIC-CPU
复用输入->引脚复用(将不同分分组但引脚号相同的划分为一组,引出一根外部中断线exti0)EXTI这儿检测上升沿或者下降沿是否发生,或门这儿是判断软件触发还是硬件触发,与门,触发出现,中断线屏蔽,接着是挂起寄存器,起到了缓冲的作用,再到NVIC,起到了打开或者关闭我们的外部中断线的作用,让不让外部中断线进去,为外部中断线赋予抢占或者/响应优先级。
PA0引脚触发外部中断的流程详细说明:
用于接收外部信号的PA0引脚,在使用外部中断时,PA0被配置为输入模式,以便检测外部信号的变化。然后是对GPIO进行配置,通过配置寄存器,可以将PA0设置为输入模式,并选择上拉或下拉电阻,以确保在没有外部信号时引脚的状态是确定的。接着通过AFIO配置 PA0的中断功能。具体来说,就是将PA0的中断线(EXTI Line)与GPIO引脚关联,以便在引脚状态变化时触发中断。
EXTI负责监测GPIO引脚的状态变化,并生成中断请求。对于PA0,EXTI控制器会监测其状态变化(上升沿、下降沿或双边沿),并在状态变化时生成中断请求。
在这里,主要是边沿检测电路,上升沿触发选择寄存器检测到上升沿,接着遇到或门进入下一步,然后中断屏蔽寄存器和这个输出的都是1,接下来的与门也是1,经过挂起请求寄存器,输出至NVIC中断控制器;
一旦NVIC确定要响应中断,它会将CPU的执行流转移到与PA0相关联的中断服务例程。此时,CPU会暂停当前的任务,执行中断服务例程中的代码,以处理外部中断事件。中断服务例程执行完毕后,CPU会恢复到中断发生前的状态,继续执行之前的任务。
4.EXTI
使能和优先级
Hal库中,中断的一般流程:
①中断向量表提供中断服务函数;
②所有外设都有一个总的中断处理函数;
③各种回调函数(weak)
④若要使用回调函数,必须重新声明
EXIO_1_hander 统一处理所有外部中断
EXTI 4_15_hander 统一的外部中断处理函数
Exti的外部中断代码:
中断向量表中提供的外部中断服务函数(这是中断的入口)
外部中断统一处理入口函数:
xxx_Rising_callback(weak)
xxx_fallng_callback(weak)
再根据要求重写相关的回调函数
exti0_1_handler(){
统一的处理函数()
}
9、DMA
全称:Direct Memory Access,即直接存储器访问。
DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。
1.DMA传输方式
DMA的作用就是实现数据的直接传输,而去掉了传统数据传输需要CPU寄存器参与的环节,主要涉及四种情况的数据传输,但本质上是一样的,都是从内存的某一区域传输到内存的另一区域(外设的数据寄存器本质上就是内存的一个存储单元)。
四种情况的数据传输如下:
外设到内存
内存到外设
内存到内存
外设到外设
DMA传输有专门的传输通道;
DMA传输参数:
首先需要①数据的源地址,②数据传输位置的目标地址;③传输数据多少的数据传输量,④进行多少次传输的传输模式;
只要剩余传输数据量不是0,而且DMA是启动状态,就会发生数据传输;
2.DMA的主要特征
每个通道都有专门的硬件DMA请求,每个通道都同样支持软件触发,这些功能通过软件来配置;
在同一个DMA模块上面,多个请求之间的优先权可以用软件编程来设置(四级:很高、高、中等和低)优先权设置相等的时候,由硬件进行决定(请求0优先于请求1);
独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐;
支持循环的缓冲器管理;
每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求;
存储器和存储器间的传输、外设和存储器、存储器和外设之间的传输;
闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标;
可编程的数据传输数目:最大为65535。
大容量的STM32芯片有2个DMA控制器;DMA1有7个通道,DMA有5个通道,每个通道都可以配置一些外设地址
3.DMA工作系统框图
上方的框图,我们可以看到STM32内核,存储器,外设及DMA的连接,这些硬件最终通过各种各样的线连接到总线矩阵中,硬件结构之间的数据转移都经过总线矩阵的协调,使各个外设和谐的使用总线来传输数据。
如果没有DMA,CPU传输数据还要以内核作为中转站,比如要将ADC采集的数据转移到到SRAM中,这个过程是这样的:
内核通过DCode经过总线矩阵协调,从获取AHB存储的外设ADC采集的数据,
然后内核再通过DCode经过总线矩阵协调把数据存放到内存SRAM中。
有DMA的话,
DMA传输时外设对DMA控制器发出请求。
DMA控制器收到请求,触发DMA工作。
DMA控制器从AHB外设获取ADC采集的数据,存储到DMA通道中
DMA控制器的DMA总线与总线矩阵协调,使用AHB把外设ADC采集的数据经由DMA通道存放到SRAM中,这个数据的传输过程中,完全不需要内核的参与,也就是不需要CPU的参与;
专业介绍:在发生一个事件后,外设向DMA控制器发送一个请求信号。DMA控制器根据通道的优先权处理请求。当DMA控制器开始访问发出请求的外设时,DMA控制器立即发送给它一个应答信号。当从DMA控制器得到应答信号时,外设立即释放它的请求。一旦外设释放了这个请求,DMA控制器同时撤销应答信号。DMA传输结束,如果有更多的请求时,外设可以启动下一个周期。
总之,每次DMA传送由3个操作组成:
从外设数据寄存器或者从当前外设/存储器地址寄存器指示的存储器地址取数据,第一次传输时的开始地址是DMA_CPARx或DMA_CMARx寄存器指定的外设基地址或存储器单元;
存数据到外设数据寄存器或者当前外设/存储器地址寄存器指示的存储器地址,第一次传输时的开始地址是DMA_CPARx或DMA_CMARx寄存器指定的外设基地址或存储器单元;
执行一次DMA_CNDTRx寄存器的递减操作,该寄存器包含未完成的操作数目。
4.DMA传输方式
1是正常模式;2是循环传输模式
其中还有一个仲裁器:作用是确定各个DMA传输的优先级
仲裁器根据通道的请求的优先级来启动外设/存储器的访问
5.DMA配置部分
分为DMA寄存器以及DMA库函数:
DMA寄存器:
DMA配置参数包括:通道地址、优先级、数据传输方向、存储器/外设数据宽度、存储器/外设地址是否增量、循环模式、数据传输量。
DMA库函数配置过程:
使能DMA时钟:RCC_AHBPeriphClockCmd();
初始化DMA通道:DMA_Init();
//设置通道;传输地址;传输方向;传输数据的数目;传输数据宽度;传输模式;优先级;是否开启存储器到存储器。
使能外设DMA;
以串口为例:使能串口DMA发送,串口DMA使能函数。调用函数:USART_DMACmd();
使能DMA通道传输;函数:DMA_Cmd();
查询DMA传输状态。函数:DMA_GetFlagStatus();
获取当前剩余数据量大小 函数: DMA_GetCurrDataCounter(DMA1_Channel4);
结合UART的运用: UART DMA传输
DMA就是一个搬运工,可以将数据从一个位置搬运到另一个位置。
以UART为例,如果要接收数据,会触发UART中断,然后CPU介入,在中断中通过CPU将UART输入寄存器的值读出来,存放到内存中;
而DMA方式,产生UART中断后,DMA直接参与,把UART输入寄存器的值搬运到内存中,CPU只需要在去检查内存的值就好了,这样提高了CPU的效率。
10、实验
1、外部中断实验
HAL_GPIO_EXTI_Falling_Callback()
HAL_GPIO_EXTI_Rising_Callback()
2、串口接受中断实验
HAL_UART_Receive_IT()
HAL_UART_RxCpltCallback()
HAL_UART_Transmit_IT()
HAL_UART_TxCpltCallback()
3、串口空闲中断实验
HAL_UARTEx_ReceiveToIdle_IT()
HAL_UARTEx_RxEventCallback()
- 串口空闲中断_DMA实验
HAL_UARTEx_ReceiveToIdle_DMA()
HAL_UARTEx_RxEventCallback()
“color:#4874CB;”> HAL_UARTEx_ReceiveToIdle_IT()
HAL_UARTEx_RxEventCallback()
[外链图片转存中…(img-E7QBIJMm-1726724546681)]
[外链图片转存中…(img-8ZY8M85c-1726724546681)]
[外链图片转存中…(img-UR1P6Zfe-1726724546682)]
- 串口空闲中断_DMA实验
HAL_UARTEx_ReceiveToIdle_DMA()
HAL_UARTEx_RxEventCallback()