STM32各模块学习之中断

合集下载

stm32 usart idle中断原理

stm32 usart idle中断原理

stm32 usart idle中断原理STM32是一款广泛应用于嵌入式系统的微控制器,它具有丰富的外设资源,其中包括USART(Universal Synchronous/Asynchronous Receiver/Transmitter)模块。

USART模块是STM32的重要组成部分,它能够实现串行通信,其中的Idle中断是USART模块的一个重要功能。

本文将详细介绍STM32 USART模块的Idle中断原理。

我们先来了解一下USART模块的基本功能。

USART模块是一种通用的串行通信接口,它可以实现全双工通信,支持同步和异步两种通信模式。

在STM32中,USART模块通常用于与外部设备进行通信,如传感器、无线模块等。

USART模块具有多种工作模式,包括异步模式、同步模式和单线模式等。

在USART模块中,Idle中断是一种特殊的中断方式。

当USART接收到一帧数据后,如果在接收数据的过程中一段时间没有接收到新的数据,USART模块会认为这段时间是数据的结束,此时就会产生Idle中断。

Idle中断的产生可以作为接收完成的标志,可以在中断服务函数中进行相关的处理操作。

那么,Idle中断是如何实现的呢?在USART模块内部,有一个专门用于检测空闲状态的电路,该电路会监测串口接收线上的电平状态。

当串口接收线上的电平保持不变一段时间时,USART模块就会判断为接收到了一帧完整的数据。

这段时间就是我们所说的“空闲时间”。

当USART模块检测到空闲时间超过一定阈值时,就会产生Idle中断。

在STM32中,可以通过配置USART的相关寄存器来使能和配置Idle中断。

首先,我们需要使能USART的空闲检测功能,可以通过设置CR1寄存器中的IDLEIE位来实现。

然后,我们需要在NVIC 中使能USART的中断,可以通过设置ISER寄存器中对应的位来实现。

当USART接收到一帧数据后,如果在接收过程中超过了一定的空闲时间,USART模块就会产生Idle中断,此时会触发中断服务函数。

stm32空闲中断原理

stm32空闲中断原理

stm32空闲中断原理STM32空闲中断原理解析概述在STM32单片机的应用开发中,空闲中断是一种非常重要的中断方式。

它允许在系统空闲时执行特定的处理函数,提高了系统的效率和响应性。

本文将从浅入深,逐步解释STM32空闲中断的原理和应用。

什么是空闲中断空闲中断,即空闲时中断,在STM32中是指当处理器空闲且没有其他中断服务请求时触发的一种中断。

它是一种基于处理器空闲时间的中断方式,不需要外部触发或特定事件的发生。

空闲中断的原理STM32的空闲中断是通过处理器中的一个特殊寄存器实现的,该寄存器监测处理器的空闲状态。

当处理器处于空闲状态时,触发空闲中断,并执行用户定义的中断服务函数。

空闲中断的配置步骤1: 中断初始化在使用空闲中断之前,需要先进行中断的初始化。

这包括配置中断向量表、中断优先级和中断服务函数等。

步骤2: 编写中断服务函数中断服务函数是空闲中断触发时执行的代码。

它可以是一段自定义的C代码,用于处理特定的任务或操作。

步骤3: 启用空闲中断使用特定的寄存器配置,启用空闲中断功能。

在这里,需要将空闲中断使能位设置为”1”,使能处理器检测空闲状态。

空闲中断的应用场景空闲中断可以应用于多个领域和应用中,主要包括以下几个方面:- 数据处理:通过空闲中断处理数据,提高数据处理的效率。

- 状态检测:通过空闲中断检测特定的系统状态,如电量低、网络连接等。

- 系统维护:在系统空闲时执行一些系统维护任务,例如清理内存、更新数据等。

总结STM32的空闲中断为系统开发者提供了一种高效且灵活的中断方式,可以在处理器空闲时执行特定的任务。

本文简要介绍了空闲中断的原理和配置步骤,并给出了一些应用场景。

希望读者通过本文的介绍,对STM32空闲中断有更深入的了解,能够在实际开发中应用自如。

以上就是对STM32空闲中断原理的解析,希望对读者有所帮助。

stm32中断函数和回调函数

stm32中断函数和回调函数

STM32的中断函数和回调函数是两种不同的函数类型,它们在嵌入式系统中有着广泛的应用。

1. 中断函数:
中断函数通常用于处理实时事件或外部信号。

当某个事件发生时,中断控制器会打断正在执行的程序,跳转到中断处理函数中执行相应的操作。

在STM32中,中断处理函数通常被定义为ISR (Interrupt Service Routine)。

ISR应该尽可能地简短快速,避免在中断处理函数中进行复杂的计算或逻辑处理。

中断函数的定义通常如下:
```c
void ISR() interrupt 1 // 1表示中断号
{
// 中断处理代码
}
```
其中,`interrupt`后面的数字表示中断号,用于区分不同的中断。

2. 回调函数:
回调函数是一种通用的事件处理机制。

它通常用于将某个函数作为参数传递给另一个函数,当事件发生时,调用传递的函数进行相应的处理。

回调函数通常被定义为一个指针类型,指向一个具有特定参数和返回值的函数。

回调函数的定义通常如下:
```c
typedef void (*Callback)(int event); // 定义回调函数类型
void function(Callback callback) // 传递回调函数作为参数{
// 执行一些操作
// 当事件发生时,调用callback函数进行处理
callback(event);
}
```
其中,`Callback`是一个指向函数的指针类型,`event`是传递给回调函数的参数。

在`function`函数中,可以调用传递的回调函数进行事件处理。

STM32学习笔记之三_定时器中断

STM32学习笔记之三_定时器中断
void RCC_Configuration(void) { /*将外设 RCC 寄存器重设为缺省值 */ RCC_DeInit(); /*设置外部高速晶振(HSE)*/ RCC_HSEConfig(RCC_HSE_ON); /*等待 HSE 起振*/ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) { /*设置 AHB 时钟(HCLK)*/ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* 设置高速 AHB 时钟(PCLK2)*/ RCC_PCLK2Config(RCC_HCLK_Div1); //RCC_HCLK_Div1—APB2 时钟 = HCLK= AHB 时钟 /*设置低速 AHB 时钟(PCLK1)*/ RCC_PCLK1Config(RCC_HCLK_Div2); /*设置 FLASH 存储器延时时钟周期数*/ FLASH_SetLatency(FLASH_Latency_2); /*选择 FLASH 预取指缓存的模式*/ //FLASH_Latency_2 2 延时周期 //RCC_HCLK_Div2—APB1 时钟=HCLK/2= AHB 时钟/2 //RCC_SYSCLK_Div1—AHB 时钟 = 系统时钟 //SUCCESS:HSE 晶振稳定且就绪 //RCC_HSE_ON——HSE 晶振打开(ON)
RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG | RCC_APB2Periph_AFIO, ENABLE); } 使用 HSE 时钟,程序设置时钟参数流程: 1、将 RCC 寄存器重新设置为默认值 RCC_DeInit 2、打开外部高速时钟晶振 HSE RCC_HSEConfig(RCC_HSE_ON); 3、 等待外部高速时钟晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp(); 4、设置 AHB 时钟 RCC_HCLKConfig; 5、设置高速 AHB 时钟 RCC_PCLK2Config; 6、设置低速速 AHB 时钟 RCC_PCLK1Config 7、设置 PLL RCC_PLLConfig 8、打开 PLL RCC_PLLCmd(ENABLE); 9、 等待 PLL 工作 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) 10、设置系统时钟 RCC_SYSCLKConfig 11、判断是否 PLL 是系统时钟 while(RCC_GetSYSCLKSource() != 0x08) 12、 打开要使用的外设时钟 RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd () 下面是 TM32 软件固件库的程序中对 RCC 的配置函数(使用外部 8MHz 晶振) /************************************************************************** * Function Name : RCC_Configuration * Description : RCC 配置(使用外部 8MHz 晶振) * Input : 无 * Output : 无 * Return : 无 **************************************************************************/

STM32F103学习笔记(五) 外部中断

STM32F103学习笔记(五) 外部中断

STM32F103学习笔记(五)外部中断首先是外部中断基本的概念:STM32 的每个IO 都可以作为外部中断的中断输入口,这点也是STM32 的强大之处。

STM32F103 的中断控制器支持19 个外部中断/事件请求。

每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。

STM32F103 的19 个外部中断为:线0~15:对应外部IO 口的输入中断。

线16:连接到PVD 输出。

线17:连接到RTC 闹钟事件。

线18:连接到USB 唤醒事件。

线16~18还没有学到只看了线0~15。

每个中断线对应着7个GPIO口,形成映射关系,以线0 为例:它对应了GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。

而中断线每次只能连接到1 个IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个GPIO 上了。

下面我们看看GPIO 跟中断线的映射关系图:根据映射关系,就开始配置按键对应GPIO口和中断的映射了:[csharp] view plain copy <pre name="code" class="csharp"><prename="code" class="html">void EXTIX_Init(void){ EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure; KEY_Init(); // 按键端口初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,EN ABLE); //使能复用功能时钟//GPIOE.2 中断线以及中断初始化配置下降沿触发GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_Pi nSource2);EXTI_InitStructure.EXTI_Line=EXTI_Line2; //KEY2 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器//GPIOE.3 中断线以及中断初始化配置下降沿触发//KEY1GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_Pi nSource3);EXTI_InitStructure.EXTI_Line=EXTI_Line3;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器//GPIOE.4 中断线以及中断初始化配置下降沿触发//KEY0GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_Pi nSource4);EXTI_InitStructure.EXTI_Line=EXTI_Line4;EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器//GPIOA.0 中断线以及中断初始化配置上升沿触发PA0 WK_UPGPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_Pi nSource0);EXTI_InitStructure.EXTI_Line=EXTI_Line0;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//使能按键WK_UP所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//使能按键KEY2所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//使能按键KEY1所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//使能按键KEY0所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器} //外部中断0服务程序voidEXTI0_IRQHandler(void) { delay_ms(10);//消抖if(KEY3==1) //WK_UP按键{ BEEP=!BEEP; } EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位} //外部中断2服务程序voidEXTI2_IRQHandler(void) { delay_ms(10);//消抖if(KEY2==0) //按键KEY2{ LED0=!LED0; }EXTI_ClearITPendingBit(EXTI_Line2); //清除LINE2上的中断标志位} //外部中断3服务程序voidEXTI3_IRQHandler(void) { delay_ms(10);//消抖if(KEY1==0) //按键KEY1{ LED1=!LED1; }EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位} void EXTI4_IRQHandler(void){ delay_ms(10);//消抖if(KEY0==0) //按键KEY0 { LED0=!LED0;LED1=!LED1; }EXTI_ClearITPendingBit(EXTI_Line4); //清除LINE4上的中断标志位} [html] view plain copy。

STM32的中断理解

STM32的中断理解

STM32的中断理解
STM32的中断理解:首先是MSP和PSP堆栈指针。

MSP是主堆栈,PSP是线程堆栈。

MSP可以用于线程模式下,也可以用于中断模式下。

而PSP只能在线程模式下使用
2.当系统复位以后默认使用的是MSP指针。

3.中断执行的过程:首先是入栈利用线程模式下的指针(入栈属于线程模式)。

然后调用向量表找到中断程序入口,开始进入中断程序,中断服务程序后。

调用BX LR会中断返回,在中断返回时会自动出栈LR,PC,等寄存器。

如果不修改CONTORL【1】则主程序中用的还是MSP指针。

如果修改后则用的PSP
这样下一次就可以自动切换了。

4 LR和PC:PC里面存放的是当前指令的地址。

LR是连接寄存器。

当发生中断或调用子程序时,此时当前的PC指令的下一条会被保存到LR。

当中断返回即可用LR返回到断点处(但是此时必须把LR的内容放到PC中,否则因为PC的地址不是LR中的地址,所以不会调到那个位置运行)。

还有就是把LR的值放到PC中。

PC自动从这个地址开始读代码。

5.PC里面的地址是多少,程序就是从这个地址开始运行。

STM32Cube学习之五:定时器中断

STM32Cube学习之五:定时器中断

STM32Cube学习之五:定时器中断假设已经安装好STM32CubeMX和STM32CubeF4支持包。

Step1.打开STM32CubeMX,点击“New Project”,选择芯片型号,STM32F407ZETx。

Step2.在Pinout界面下配置PF9,PF10为输出模式,并输入用户标签LED0,LED1。

Step3.配置TIM1,使用内部时钟源。

Step4.配置时钟树,在此使用默认值,16MHz。

Step5.配置TIM1参数和GPIO的参数。

在configuration界面中点击TIM1按钮,可以进入参数配置界面。

在Parameter Settings页配置预分频系数为15999,计数周期(自动加载值)为999,定时器溢出频率就是16MHz/(15999+1)/(999+1) = 1Hz。

在NVIC页面使能TIM1的更新中断。

在configuration界面中点击GPIO按钮,配置GPIO的上拉电阻。

在此GPIO配置默认即可。

Step6.生成源代码。

点击生成源代码按钮。

在设置界面中输入工程名,保存路径,工程IDE类型,点OK即可。

生成代码完成后可直接打开工程。

弹出如下对话框时,如果已经安装了F4的支持包,则点击OK关闭。

如果没有安装,则点击界面中的/...链接,找到芯片的支持包,然后安装。

关闭后面的界面。

点击“是”,然后选择芯片型号。

可以在搜索框中输入关键字,加快选择速度。

Step7.添加功能代码。

在main文件/* USER CODE BEGIN 4 */和/* USER CODE END 4 */注释之间加入下面代码。

在main函数的while(1)之前启动TIM1并使能其中断功能。

至此,完成整个工程。

编译下载,现象就是LED0和LED1同步循环闪烁,亮1秒灭1秒。

特别说明:CubeMX生成的MDK工程已经包含了配置中用到的外设相关文件,如下图:打开stm32f4xx_hal_tim.c,并点击右键,选择相应条目即可打开stm32f4xx_hal_tim.h文件,在HAL_开头的函数中,找到使能定时器中断的函数,如下图:定时器周期中断回调函数,在1304行。

STM32学习记录12 中断向量表

STM32学习记录12 中断向量表

STM32 学习记录12 中断向量表从stm32f10x.s 可以看到,已经定义好了一大堆的中断响应函数,这就是中断向量表,标号__Vectors,表示中断向量表入口地址,例如:AREA RESET, DATA, READONLY ;定义只读数据段,实际上是在CODE 区(假设STM32 从FLASH 启动,则此中断向量表起始地址即为0x8000000)EXPORT__VectorsIMPORT OS_CPU_SysTickHandler IMPORTOS_CPU_PendSVHandler__Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler这个向量表的编写是有讲究的,跟硬件一一对应不能乱写的,CPU 找入口地址就靠它了,bin 文件开头就是他们的地址,参考手册RM0008 的10.1.2 节可以看到排列。

我们再结合CORTEX-M3 的特性,他上电后根据boot 引脚来决定PC 位置,比如boot 设置为flash 启动,则启动后PC 跳到0x08000000。

此时CPU 会先取2 个地址,第一个是栈顶地址,第二个是复位异常地址,故有了上面的写法,这样就跳到reset_handler。

那么这个reset_handler 的实际地址是多少.?下面的一堆例如Nmi_handler 地址又是多少呢?发生中断是怎么跑到这个地址的呢?下面挨个讲解。

stm32f103c8t6外部中断原理

stm32f103c8t6外部中断原理

一、概述在嵌入式系统中,外部中断是一种常见的事件触发机制,它能够使处理器在执行程序的过程中,及时地响应外部事件的发生,从而提高系统的实时性和稳定性。

在基于STM32F103C8T6芯片的嵌入式系统开发中,外部中断的使用具有重要的意义。

本文将介绍STM32F103C8T6外部中断的原理及其应用。

二、STM32F103C8T6外部中断的原理1. 外部中断概述外部中断是指处理器接收到外部输入信号后,及时地中断当前的程序执行,转而执行事先定义好的中断服务程序。

在STM32F103C8T6芯片中,具有多个外部中断引脚以及相关的中断控制寄存器,可以方便地实现外部中断功能。

2. 中断控制器STM32F103C8T6芯片的中断控制器包含若干中断控制寄存器,用于配置外部中断的触发条件、优先级、使能状态等。

通过对中断控制寄存器的配置,可以灵活地控制外部中断的响应行为。

3. NVICSTM32F103C8T6芯片内部集成了Nested Vectored Interrupt Controller(NVIC),负责管理和调度所有的中断源。

在实现外部中断功能时,需要通过NVIC对外部中断源进行优先级和使能的设置。

4. 外部中断触发条件在STM32F103C8T6芯片中,外部中断可以以上升沿、下降沿、上升沿和下降沿、低电平或者高电平触发。

在配置外部中断时,需要根据实际应用需求选择合适的触发条件,并进行相应的配置。

5. 外部中断服务程序一旦外部中断触发条件满足,处理器将立即响应中断,并跳转到预先定义好的外部中断服务程序中执行。

外部中断服务程序通常用于处理外部事件的逻辑,例如状态更新、数据采集、报警处理等。

三、STM32F103C8T6外部中断的应用1. 外部按键控制在很多嵌入式系统中,外部按键常常作为用户与系统交互的途径。

通过STM32F103C8T6的外部中断功能,可以轻松地实现外部按键的检测和响应,从而实现用户界面的交互控制。

(stm32f103学习总结)—stm32定时器中断

(stm32f103学习总结)—stm32定时器中断

(stm32f103学习总结)—stm32定时器中断⼀、定时器介绍 STM32F1的定时器⾮常多,由2个基本定时器(TIM6、TIM7)、4个通 ⽤定时器(TIM2-TIM5)和2个⾼级定时器(TIM1、TIM8)组成。

基本定 时器的功能最为简单,类似于51单⽚机内定时器。

通⽤定时器是在基本 定时器的基础上扩展⽽来,增加了输⼊捕获与输出⽐较等功能。

⾼级定 时器⼜是在通⽤定时器基础上扩展⽽来,增加了可编程死区互补输出、 重复计数器、带刹车(断路)功能,这些功能主要针对⼯业电机控制⽅⾯1.1 通⽤定时器简介 STM32F1的通⽤定时器包含⼀个 16 位⾃动重载计数器(CNT),该计 数器由可编程预分频器(PSC)驱动。

STM32F1的通⽤定时器可⽤于多种 ⽤途,包括测量输⼊信号的脉冲宽度(输⼊捕获)或者⽣成输出波形(输出 ⽐较和PWM)等。

使⽤定时器预分频器和 RCC 时钟控制器预分频器,脉 冲长度和波形周期可以在⼏个微秒到⼏个毫秒间调整。

STM32F1 的每个 通⽤定时器都是完全独⽴的,没有互相共享的任何资源。

STM32F1的通⽤定时器TIMx (TIM2-TIM5 )具有如下功能:(1)16 位向上、向下、向上/向下⾃动装载计数器(TIMx_CNT)。

(2)16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535之间的任意数值。

(3)4个独⽴通道(TIMx_CH1-4),这些通道可以⽤来作为: A.输⼊捕获 B.输出⽐较 C. PWM ⽣成(边缘或中间对齐模式) D.单脉冲模式输出(4)可使⽤外部信号(TIMx_ETR)控制定时器,且可实现多个定时器互连(可以⽤1个定时器控制另外⼀个定时器)的同步电路。

(5)发⽣如下事件时产⽣中断/DMA请求: A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) B.触发事件(计数器启动、停⽌、初始化或者由内部/外部触发计数) C.输⼊捕获 D.输出⽐较(6)⽀持针对定位的增量(正交)编码器和霍尔传感器电路(7)触发输⼊作为外部时钟或者按周期的电流管理1.2 通⽤定时器结构框图我们把通⽤定时器结构框图分成 5 个⼦模块,按照顺序依次进⾏简单介绍。

STM32CubeMX实战教程(三)——外部中断(中断及HAL_Delay函数避坑)

STM32CubeMX实战教程(三)——外部中断(中断及HAL_Delay函数避坑)

STM32CubeMX实战教程(三)——外部中断(中断及HAL_Delay函数避坑)在STM32CubeMX实战教程中,我们已经学习了如何使用GPIO来控制LED的亮灭。

在这篇文章中,我们将进一步学习如何使用外部中断来实现更复杂的功能。

外部中断可以使我们的微控制器能够在输入发生变化时立即做出响应。

这对于需要实时性的应用非常重要,比如按钮的按下或松开的检测。

外部中断类似于计数器,不断地检测输入引脚的变化,并在变化时触发中断。

在STM32CubeMX中配置外部中断非常简单。

我们只需要选择外部输入引脚作为中断源,然后为中断配置触发方式即可。

触发方式可以是上升沿、下降沿或双边沿触发。

但要注意的是,当使用外部中断时,我们应该避免在中断服务子程序(ISR)中使用延时函数,如HAL_Delay。

这是因为在ISR中调用延时函数会导致中断响应时间增加,从而影响其他中断的响应和整个系统的实时性。

所以在ISR中,我们只能执行最核心、最迅速的操作。

为了避免在ISR中使用延时函数,我们可以使用定时器中断来实现延时。

定时器中断是一种定期触发的中断,在ISR中我们可以通过判断定时器的计数值来实现一定时间的延时。

下面是一个使用外部中断的示例代码:```c#include "stm32f4xx_hal.h"GPIO_InitTypeDef GPIO_InitStruct;EXTI_HandleTypeDef hexti;void SysTick_Handler(void)HAL_IncTick(;HAL_SYSTICK_IRQHandler(;void EXTI_IRQHandler(void)HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) //在这里执行最核心、最迅速的操作int main(void)HAL_Init(;SystemClock_Config(;__HAL_RCC_GPIOA_CLK_ENABLE(;__HAL_RCC_SYSCFG_CLK_ENABLE(;GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_PULLDOWN;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);HAL_NVIC_EnableIRQ(EXTI0_IRQn);while (1)//在这里执行其他操作}```在这个示例中,我们使用PA0引脚,即用户按钮作为外部中断源。

stm32f103c8t6中断原理

stm32f103c8t6中断原理

stm32f103c8t6中断原理一、概述STM32F103C8T6是一款基于ARMCortex-M3核心的STM32系列微控制器。

它具有丰富的外设和强大的性能,广泛应用于各种嵌入式系统。

中断是STM32微控制器中非常重要的概念,用于处理硬件事件,使得处理器能够及时响应和处理这些事件,提高系统的实时性和响应速度。

二、中断系统架构STM32F103C8T6的中断系统由硬件和软件两部分组成。

硬件部分包括中断控制器、外设中断请求源、全局中断标志位等;软件部分包括中断优先级管理、中断处理函数等。

中断控制器负责管理各个外设的中断请求,并将这些请求分配给相应的中断优先级。

外设中断请求源包括定时器、串口、ADC等,它们会在特定事件发生时产生中断请求。

全局中断标志位用于指示是否有中断事件发生,这些标志位由处理器轮询或软件查询。

三、中断优先级管理STM32F103C8T6的中断优先级管理采用嵌套模式,即一个中断可以被嵌套在另一个中断的触发序列中。

处理器会根据中断优先级和嵌套级别来决定先处理哪个中断。

STM32的中断优先级范围为0-7,其中0为最高优先级,7为最低优先级。

可以通过软件配置寄存器来设置各个中断的优先级。

四、中断处理过程当有中断事件发生时,处理器会自动跳转到相应的中断处理函数执行。

中断处理函数通常会完成一些必要的清理工作,如清除相关标志位、释放锁定的资源等,然后返回到正常的主程序继续执行。

在处理完一个中断后,处理器会自动回到正常的主程序执行,而不会出现死循环或延迟。

五、特殊中断STM32F103C8T6微控制器还支持一些特殊的中断,如系统复位中断、系统心跳中断等。

这些中断通常用于系统状态监测和异常处理,确保系统的稳定性和可靠性。

六、总结STM32F103C8T6的中断原理涉及到硬件和软件两个方面的知识,包括中断系统架构、中断优先级管理、中断处理过程以及特殊中断等。

理解中断原理对于使用STM32微控制器进行嵌入式系统开发非常重要,可以帮助开发者更好地利用其强大的硬件资源,提高系统的实时性和响应速度。

stm32中断(NVIC与EXTI)

stm32中断(NVIC与EXTI)

stm32中断(NVIC与EXTI) D部有4个从优先级(00 01 10 11)。

1.中断输入与悬起当中断输入脚被置为有效后,该中断就被“悬起”。

所谓“悬起”,也就是等待、就绪的意思。

即使后来中断源撤消了中断请求,已经被标记成悬起的中断也被记录下来。

当某中断的服务程序开始执行时,就称此中断进入了“活跃”状态,并且其悬起位会被硬件自动清除。

在一个中断活跃后,直到其服务例程执行完毕,并且返回后,才能对该中断的新请求予以响应。

当NVIC响应一个中断时,会自动完成以下三项工作,以便安全、准确地跳转到相应的中断服务程序:入栈:把8个寄存器的值压入栈。

当响应中断时,如果当前的代码正在使用PSP,则压入PSP(进程堆栈),否则就压入MSP(主堆栈)。

一旦进入了服务例程,就一直使用主堆栈。

在自动入栈的过程中,将寄存器写入堆栈的顺序与时间顺序无关,CM3会保证正确的寄存器被保存到正确的位置。

取向量:当数据总线(系统总线)进行入栈操作时,指令总线(I-Code总线)正在从向量表中找出正确的中断向量与对应的服务程序入口地址。

更新寄存器。

注意:①如果在某个中断得到响应之前,其悬起状态被清除了,则中断被取消。

②新请求在得到响应时,由硬件自动清零其悬起标志位。

③如果中断源咬住请求信号不放,该中断就会在其上次服务例程返回后再次被置为悬起状态。

④如果某个中断在得到响应之前,其请求信号以若干的脉冲的方式呈现,则被视为只有一次中断请求⑤如果在服务例程执行时,中断请求释放了,但是在服务例程返回前又重新被置为有效,则NVIC会记住此动作,重新悬起该中断。

2.中断返回当中断完成,返回主程序时,NVIC自动完成以下两步:①出栈:先前压入栈中的寄存器在这里恢复。

内部的出栈顺序与入栈时的相对应,堆栈指针的值也改回先前的值。

②更新NVIC 寄存器:伴随着中断的返回,它的活动位也被硬件清除。

对于外部中断,倘若中断输入再次被置为有效,则悬起位也将再次置位,新一次的中断响应序列也会再次开始。

(stm32f103学习总结)—stm32外部中断

(stm32f103学习总结)—stm32外部中断

(stm32f103学习总结)—stm32外部中断⼀、外部中断介绍1.1 EXTI简介 EXTI简介 STM32F10x外部中断/事件控制器(EXTI)包含多达 20 个⽤于产⽣事 件/中断请求的边沿检测器。

EXTI的每根输⼊线都可单独进⾏配置,以选 择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或 边沿触发),还可独⽴地被屏蔽。

(stm32f103有19个)1.2 EXTI结构框图1.3 外部中断/事件线映射 STM32F10x的EXTI具有20个中断/事件线,如下:(stm32f103有19个以太⽹唤醒事件没有;stm32f107有20个) STM32F10x 的 EXTI 供外部 IO ⼝使⽤的中断线有 16 根,但是我们使⽤的 STM32F103 芯⽚却远远不⽌ 16 个 IO ⼝,那么 STM32F103 芯⽚怎么解决这个问题的呢? 因为 STM32F103 芯⽚每个 GPIO 端⼝均有 16 个管脚,因此把每个端⼝的 16 个 IO 对应那 16 根中断线 EXTI0-EXTI15 。

⽐如:GPIOx.0-GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 EXTI0-EXTI15,这样⼀来每个中断线就对应了最多 7 个 IO ⼝,⽐如:GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0。

但是中断线每次只能连接⼀个在 IO ⼝上,这样就需要通过 AFIO 的外部中断配置寄存器 1 的 EXTIx[3:0]位来决定对应的中断线映射到哪个GPIO 端⼝上,对于中断线映射到 GPIO 端⼝上的配置函数在stm32f10x_gpio.c 和 stm32f10x_gpio.h 中,所以使⽤到外部中断时要把这个⽂件加⼊到⼯程中,在创建库函数模板的时候我们默认已经添加。

EXTI 的 GPIO 映射图如图 18.1.3 所⽰:⼆、外部中断配置步骤 要使⽤外部中断我们就需要先配置它,通常都需经过这⼏步:(1)使能IO ⼝时钟,配置IO ⼝模式为输⼊(2)开启 AFIO 时钟,设置 IO ⼝与中断线的映射关系RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启AFIO 时钟void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource); //设置IO ⼝与中断线的映射关系即哪个io ⼝哪⼀个管脚作为中断输⼊线GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //这⾥以配置GPIOA ⼝ GPIOA 的第0管脚作为中断输⼊线(3)配置中断分组(NVIC ),使能中断(4)初始化EXTI ,选择触发⽅式(5)编写EXTI 中断服务函数(中断函数固件库中已经定义必须使⽤下列函数名不能⾃⼰定义)EXTI0_IRQHandlerEXTI1_IRQHandlerEXTI2_IRQHandlerEXTI3_IRQHandlerEXTI4_IRQHandlerEXTI9_5_IRQHandlerEXTI15_10_IRQHandler三、编写外部中断控制程序 要实现外部中断⽅式控制LED ,程序框架如下:(1)初始化对应端⼝的EXTI (第三部分中的1-4⼩步)1 void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);2 typedef struct3 {4 uint32_t EXTI_Line; //中断/事件线5 EXTIMode_TypeDef EXTI_Mode; //EXTI 模式6 EXTITrigger_TypeDef EXTI_Trigger; //EXTI 触发⽅式7 FunctionalState EXTI_LineCmd; //中断线使能或失能8 }EXTI_InitTypeDef ;(2)编写EXTI中断函数(3)编写主函数1/*******************************************************************************2* 函数名 : My_EXTI_Init3* 函数功能 : 外部中断初始化4* 输⼊ : ⽆5* 输出 : ⽆6*******************************************************************************/7void My_EXTI_Init(void)8{9 NVIC_InitTypeDef NVIC_InitStructure;10 EXTI_InitTypeDef EXTI_InitStructure;1112 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //AFIO使能13 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//选择GPIO管脚⽤作外部中断线路14//EXTI0 NVIC 配置15 NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//EXTI0中断通道16 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级17 NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //⼦优先级18 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能19 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器20//初始化EXTI 配置21 EXTI_InitStructure.EXTI_Line=EXTI_Line0;22 EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;23 EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;24 EXTI_InitStructure.EXTI_LineCmd=ENABLE;25 EXTI_Init(&EXTI_InitStructure);26}1/*******************************************************************************2* 函数名 : EXTI0_IRQHandler3* 函数功能 : 外部中断0函数4* 输⼊ : ⽆5* 输出 : ⽆6*******************************************************************************/7void EXTI0_IRQHandler(void)8{9 if(EXTI_GetITStatus(EXTI_Line3)==1) //判断EXTI中断标志位状态函数10 {11 //填写中断中需要完成的程序12 }13 EXTI_ClearITPendingBit(EXTI_Line3); //在结束中断服务函数前,清楚中断标志位1415 }。

stm32寄存器版学习笔记定时计数器中断

stm32寄存器版学习笔记定时计数器中断

stm32寄存器版学习笔记定时计数器中断STM32共有8个定时计数器,⾼级定时器: TIME1 TIME8是通⽤定时器:TIME2~TIME5基本定时器: TIME6和TIME7以TIME3通⽤定时器为例总结定时计数器的基本⽤法⼀:TIM3时钟使能APB1外设时钟使能寄存器(RCC_APB1ENR)Eg:RCC->APB1ENR|=1<<1; //使能TIM3时钟⼆:设置TIM3_ARR和TIM3_PSC的值通过这两个寄存器来设置⾃动重装的值以及分频系数⾃动重装载寄存器(TIMx_ARR)预分频器(TIMx_PSC)三:设置TIM3_DIER允许更新中断中断使能寄存器(TIMx_DIER)Eg: TIM3->DIER|=1<<0; //允许更新中断四:允许TIM3⼯作控制寄存器1(TIMx_CR1)CEN:使能计数器位0 0:禁⽌计数器; 1:使能计数器Eg: TIM3->CR1|=0x01; //使能定时器3 或 TIM3->CR1|=1<<0;五:TIM3中断分组设置直接调⽤MY_NVIC_Init()函数Eg:MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,⼦优先级3,组2六:编写中断服务函数状态寄存器(TIMx_SR)Eg: if(TIM3->SR&0X0001)//溢出中断Eg: //定时器3中断服务程序 void TIM3_IRQHandler(void) //TIM3_Int_Init(5000,7199); //10Khz的计数频率,计数到5000为500ms//500ms中断⼀次 { if(TIM3->SR&0X0001) //溢出中断 { //add your code } TIM3->SR&=~(1<<0); //清除中断标志位 }六:关于溢出事件的计算因为Stm32_Clock_Init函数⾥⾯已经初始化APB1的时钟为2分频,所以APB1的时钟是32MHz(系统时钟72MHz)。

STM32中断法USART串口简单使用

STM32中断法USART串口简单使用

STM32中断法USART串口简单使用
1.初始化USART外设:首先需要在STM32的寄存器中对USART进行初始化。

具体的步骤包括:选择时钟源、配置波特率、设置数据长度、设置停止位、设置校验位等。

这些设置都可以在USART的控制寄存器中进行。

2.配置串口引脚:需要将USART的引脚与STM32的GPIO引脚进行连接。

具体的配置方法包括将GPIO引脚设置为复用功能,并且选择对应的USART信号。

3.编写中断服务函数:为了使用中断方式接收和发送数据,需要编写中断服务函数。

中断服务函数通常由硬件自动调用,当USART接收到数据或发送数据完成时触发。

在中断服务函数中,我们可以读取接收到的数据或者发送下一个数据。

4.使能中断:要使能USART的串口接收中断,需要在USART的控制寄存器中设置相应的位。

通常有RXNE和TC中断位,分别表示接收缓冲区非空和发送完成。

5.启动USART:启动USART外设,使其处于工作状态。

可以在相应的控制寄存器中设置TE(发送使能)和RE(接收使能)位。

6.外部中断配置:在STM32中,需要在NVIC寄存器中配置和使能USART接收中断的优先级。

这样才能通过中断向量表触发中断。

通过上述步骤,可以完成USART串口的简单使用,实现数据的接收和发送。

在编写中断服务函数时,可以根据实际需求进行数据处理,例如打印接收的数据或根据接收到的数据触发其他功能。

STM32 硬件IIC中断使用方法

STM32 硬件IIC中断使用方法

STM32 硬件IIC中断使用方法--中北大学:马政贵本文详细描述了STM32硬件IIC的中断使用方法,包含流程图和对应代码,以及调试过程中的问题记录和分析解决。

之前,一直听说STM32的硬件IIC有问题,加之以前写好的模拟IIC模块用着一直没问题,就没有去使用STM32的硬件IIC。

后面项目中需要实时读取三个传感器的数据,三个传感器并在一起共用一个IIC口,通过地址进行区分通信,一个传感器要读取8字节数据。

采用模拟IIC方式,很多时间都浪费在高低电平的等待时间上,导致其他任务时间很紧迫。

于是想到使用硬件IIC的中断方式,来提升效率。

查看了下库自带的例程,使用的是查询方式,使用了大量的while来等待状态标志完成。

移植过来,虽然可以跑通,但使用的是查询方式,效率本质上和模拟IIC是一样的。

于是自己便把手册里的IIC模块看了一遍,自己根据手册来写硬件IIC的中断模式。

上图是传感器的通讯时序,属于标准的IIC通信,这里不做进一步展开,详细可以参看IIC总线规范。

应用中,MCU做主机,传感器做从机。

MCU先工作在主发送器模式,然后工作在主接收器模式。

在默认状态下,MCU接口工作于从模式。

接口在生成起始条件后自动地从从模式切换到主模式;当仲裁丢失或产生停止信号时,则从主模式切换到从模式。

在应用手册中,详细给出了IIC主模式的操作要求及顺序:这里需要注意的是怎样结束通信,然后重启通信,以便获取下一个传感器的数据。

应用手册根据情况分为了三种,我这里使用的是第一种方式,也就是把IIC的中断优先级设置为最高。

下面我以流程图的方式,把整个过程表示出来,然后再据此给出相应的代码,代码在中断中以状态机的方式进行。

先进行IIC管脚GPIO的配置:接着进行IIC的配置(中断先不使能,在初始化完传感器之后再使能。

我这里把IIC的事件中断优先级设置为最高,若不是,IIC的结束操作需参照应用手册中相应的情况进行):中断中的状态机如下:void I2C2_EV_IRQHandler(void){switch(IIC2_State){case 0:if(I2C_GetINTStatus(I2C2, I2C_INT_STARTF)){I2C_ClearITPendingBit(I2C2, I2C_INT_STARTF);(void)(I2C2->STS1);I2C_Send7bitAddress(I2C2, ALS31300_ADR[IIC_Device], I2C_Direction_Transmit);IIC2_State++;}else{I2C2->STS1 = 0;}break;case 1:if(I2C_GetINTStatus(I2C2, I2C_INT_ADDRF)){I2C_ClearITPendingBit(I2C2, I2C_INT_ADDRF);(void)(I2C2->STS1);(void)(I2C2->STS2);I2C_SendData(I2C2, 0x28);IIC2_State++;}else{I2C2->STS1 = 0;}break;case 2:if(I2C_GetINTStatus(I2C2, I2C_INT_TDE)){I2C_ClearITPendingBit(I2C2, I2C_INT_TDE);I2C_ClearITPendingBit(I2C2, I2C_INT_BTFF);(void)(I2C2->STS1);I2C_GenerateSTART(I2C2, ENABLE); /* Send STRAT condition a second time */IIC2_State++;}else{I2C2->STS1 = 0;}break;case 3:if(I2C_GetINTStatus(I2C2, I2C_INT_STARTF)){I2C_ClearITPendingBit(I2C2, I2C_INT_STARTF);(void)(I2C2->STS1);I2C_Send7bitAddress(I2C2, ALS31300_ADR[IIC_Device],I2C_Direction_Receive);IIC2_State++;}else{I2C2->STS1 = 0;}break;case 4:if(I2C_GetINTStatus(I2C2, I2C_INT_ADDRF)){I2C_ClearITPendingBit(I2C2, I2C_INT_ADDRF);(void)(I2C2->STS1);(void)(I2C2->STS2);IIC2_State++;}else{I2C2->STS1 = 0;}break;case 5:if(I2C_GetINTStatus(I2C2, I2C_INT_RDNE)){I2C_ClearITPendingBit(I2C2, I2C_INT_RDNE);(void)(I2C2->STS1);ALS31300_Reg_Data[IIC_Device][IIC_Rec_Num] = I2C_ReceiveData(I2C2);IIC_Rec_Num++;if(IIC_Rec_Num >= 6){IIC2_State++;}}else{I2C2->STS1 = 0;}break;case 6:if(I2C_GetINTStatus(I2C2, I2C_INT_RDNE)){I2C_ClearITPendingBit(I2C2, I2C_INT_RDNE);(void)(I2C2->STS1);ALS31300_Reg_Data[IIC_Device][IIC_Rec_Num] = I2C_ReceiveData(I2C2);I2C_AcknowledgeConfig(I2C2, DISABLE);I2C_GenerateSTOP(I2C2, ENABLE);IIC_Rec_Num++;IIC2_State++;}else{I2C2->STS1 = 0;}break;case 7:if(I2C_GetINTStatus(I2C2, I2C_INT_RDNE)){I2C_ClearITPendingBit(I2C2, I2C_INT_RDNE);(void)(I2C2->STS1);ALS31300_Reg_Data[IIC_Device][IIC_Rec_Num] =I2C_ReceiveData(I2C2);IIC_Device++;if(IIC_Device >= 3){IIC_Device = 0;IIC_Rec_OK = 1;}I2C_AcknowledgeConfig(I2C2, ENABLE);I2C_GenerateSTART(I2C2, ENABLE);IIC_Rec_Num = 0;IIC2_State = 0;}else{I2C2->STS1 = 0;}break;default:I2C2->STS1 = 0;break;}}初始化之后,产生开始信号之后,使能中断,此后就一直在中断的状态机中往复进行了:#define IIC_TIMEOUT 1000IIC2_GPIO_Config();IIC2_Config();time_count = IIC_TIMEOUT;while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSYF)){time_count--;if(0 == time_count){IIC_Wrong_Count++;return;}}I2C_AcknowledgeConfig(I2C2, ENABLE);I2C_GenerateSTART(I2C2, ENABLE);//初始化之后再开中断,只在读操作中使用中断I2C_INTConfig(I2C2, I2C_INT_EVT | I2C_INT_BUF | I2C_INT_ERR, ENABLE);编译调试,咦,状态机一直停留在0状态,也就是卡在总线一直BUSY。

学习6__STM32--SPI外设之中断收发---

学习6__STM32--SPI外设之中断收发---

学习6__STM32--SPI外设之中断收发---<⽬标> STM32双机 SPI中断收发通信<描述> # STM32双机配置为⼀主⼀从模式 # 采⽤主机中断发送,从机中断接收 # 收发机制采⽤不间断收发(发送为空就发送,接收⾮空就接收,中间⽆其他操作打断) # 就是单字节发送与接收<问题> 从机接收端会出现,接收到的数据可能是原始发送数据也会是错误数据,出现这种现象的条件是发送主机复位、发送主机重新上电、随时间变化(物理碰触等)都会产⽣错误数据,⽽复位接收从机、重新上电接收从机会纠正数据<分析> # STM32双机未共地导致 共地后问题依旧 # STM32未使⽤NSS引脚导致 使⽤后问题依旧 # ⼯作模式改变尝试(发送与接收⼯作模式配置为不匹配) 问题依旧 # 主机发送太过频繁导致,导致接收来不及接收导致 拉⼤发送数据周期问题依旧 # 从数据结果上分析,应该是发送主机与接收从机未同步导致,接收总线的数据先由移位寄存器接收,再copy⾄数据寄存器,所以分析数据错位现象是出现在移位寄存器中,⽐如正在传输中由复位操作或断电操作等,致使移位寄存器只接收了3bit数据,⽽SPI数据的接收机制是,移位寄存器收满8bit数据后copy⾄数据寄存器,这⼀切都是硬件完成,注意数据的搬移是copy,所以移位寄存器中的数据还在即数据残留特性,就像刚刚的这种中断操作⾏为导致移位寄存器残留了当前字节的3bit数据,未满8bit数据故不会copy⾄数据寄存器,所以等待恢复⼯作后,需要再接收5bit数据,这样满8bit数据后copy⾄spi->DR,但是这1byte数据中的前3bit与后5bit数据本不是⼀个有效byte数据,就导致读到1byte⽆效数据,产⽣了接收错误数据的现象<解决> # 拉⼤发送数据周期&在进⼊接收中断后先关闭SPI外设,然后再读取数据,出中断前开始SPI外设 > 在进⼊中断服务程序后关闭spi外设,将导致在关闭外设期间发⽣的中断⽽被忽视,尤其是多数据连续发送,⽐如DMA数据发送,实测将导致丢数据,即其中的部分中断未作出响应⽽丢弃。

第5章stm32单片机外部中断ppt课件

第5章stm32单片机外部中断ppt课件

5.2.3 中断控制器
ICER[2]:全称Interrupt Clear-Enable Registers,是 一个中断清除使能寄存器组。
该寄存器组与ISER寄存器功能相反,用来清除某个 中断的使能位。由于NVIC的这些寄存器都是写1有 效的,写0是无效的。设置一组ICER 寄存器来清除 相应中断使能位。
5.2.1 中断源
ARM Coetex-M3内核共支持256个中断,其中16 个内部中断,240个外部中断和可编程的256级中断优 先级的设置。STM32目前支持的中断共84个(16个内 部+68个外部),还有16级可编程的中断优先级的设 置,仅使用中断优先级设置8bit中的高4位。
5.2.2 中断向量:表5-1 给出STM32F103中断向量表
5.3.2 中断优先级控制
响应优先级可设置为0到15级。 判断两个中断的优先级时: (1)先看抢占优先级的高低; (2)再看响应优先级的高低; (3)看中断通道向量地址。 一个系统使用一个组别就完全可以满足需要,在使 用一个组别后不要在系统中再改动组别。
5.3.2 中断优先级控制
假定设置中断优先级为组2,然后设置: 中断3(RTC中断)的抢占优先级为2,响应优先级为1。 中断6(外部中断0)的抢占优先级为3,响应优先级为0。 中断7(外部中断1)的抢占优先级为2,响应优先级为0。 求这3个中断的优先级顺序? 上面例子中的中断3和中断7都可以打断中断6 的中断。而中 断7和中断3却不可以相互打断(这是因为他们的抢占优先级 是相同的)。
5.2.3 中断控制器
与NVIC相关的寄存器 在“stm32f10x_map.h” 文件中定义了一个结构 体,结构体的内容如下
STM32F103系列单片机 的中断系统在这些寄存 器的控制下有序执行。 了解这些中断寄存器的 含义,才能更好的理解 STM32单片机中断系统 的工作原理

stm32中断学习总结

stm32中断学习总结

stm32中断学习总结经过了两天,终于差不多能看懂32的中断了,由于是⽤的库函数操作的,所以有些内部知识并没有求甚解,只是理解知道是这样的。

但对于要做简单开发的我来说这些已经够了。

我学习喜欢从⼀个例程来看,下⾯的程序是我粘贴但是改编的,⼤部分都做了注释。

其实主要步骤就是:1、将GPIO⼝配置成中断输⼊模式。

void Init_LED(void){GPIO_InitTypeDef GPIO_InitStructure; //定义⼀个GPIO结构体变量RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |RCC_APB2Periph_GPIOG, ENABLE);//使能各个端⼝时钟,GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; //板上LED编号 D2GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOG, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //板上LED编号 D5GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOD, &GPIO_InitStructure);}2、这个例程是做的按键,就是你要哪个地⽅产⽣中断,然后将其所在的总线配置成中断源,然后照猫画虎,填写中断结构体成员,就是配置外部事件的模式、触发条件、使能外部触发,但是别忘了打开复⽤功能(现在我还不理解)void Init_TI_KEY(void){EXTI_InitTypeDef EXTI_InitStructure; //定义⼀个EXTI结构体变量RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能IO复⽤功能,使⽤中断功能重要/* 引脚选择 */GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);//配置端⼝C的13引脚为中断源重要!!板上标号INT2GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0); //配置端⼝E的0引脚为中断源重要!!板上标号INT1/* 设置外部中断结构体的成员*/EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式为中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line13;EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断线EXTI_Init(&EXTI_InitStructure); //根据参数初始化中断寄存器}3、现在就该配置中断了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

STM32系统及各模块配置一、STM32中断优先级和开关总中断(1)中断优先级:STM32(Cortex-M3)中的优先级概念STM32(Cortex-M3)中有两个优先级的概念——抢占式优先级和响应优先级,有人把响应优先级称作'亚优先级'或'副优先级',每个中断源都需要被指定这两种优先级。

具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。

当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。

如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。

既然每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位可以有8种分配方式,如下:所有8位用于指定响应优先级最高1位用于指定抢占式优先级,最低7位用于指定响应优先级最高2位用于指定抢占式优先级,最低6位用于指定响应优先级最高3位用于指定抢占式优先级,最低5位用于指定响应优先级最高4位用于指定抢占式优先级,最低4位用于指定响应优先级最高5位用于指定抢占式优先级,最低3位用于指定响应优先级最高6位用于指定抢占式优先级,最低2位用于指定响应优先级最高7位用于指定抢占式优先级,最低1位用于指定响应优先级这就是优先级分组的概念。

--------------------------------------------------------------------------------Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:第0组:所有4位用于指定响应优先级第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级第4组:所有4位用于指定抢占式优先级可以通过调用STM32的固件库中的函数NVIC_PriorityGroupConfig()选择使用哪种优先级分组方式,这个函数的参数有下列5种:NVIC_PriorityGroup_0 => 选择第0组NVIC_PriorityGroup_1 => 选择第1组NVIC_PriorityGroup_2 => 选择第2组NVIC_PriorityGroup_3 => 选择第3组NVIC_PriorityGroup_4 => 选择第4组接下来就是指定中断源的优先级,下面以一个简单的例子说明如何指定中断源的抢占式优先级和响应优先级:// 选择使用优先级分组第1组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);// 使能EXTI0中断NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 指定抢占式优先级别1NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// 使能EXTI9_5中断NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);要注意的几点是:1)如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;2)抢占式优先级别相同的中断源之间没有嵌套关系;3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。

(2)开关总中断:在STM32/Cortex-M3中是通过改变CPU的当前优先级来允许或禁止中断。

PRIMASK位:只允许NMI和hard fault异常,其他中断/异常都被屏蔽(当前CPU优先级=0)。

FAULTMASK位:只允许NMI,其他所有中断/异常都被屏蔽(当前CPU优先级=-1)。

在STM32固件库中(stm32f10x_nvic.c和stm32f10x_nvic.h) 定义了四个函数操作PRIMASK 位和FAULTMASK位,改变CPU的当前优先级,从而达到控制所有中断的目的。

下面两个函数等效于关闭总中断:void NVIC_SETPRIMASK(void);void NVIC_SETFAULTMASK(void);下面两个函数等效于开放总中断:void NVIC_RESETPRIMASK(void);void NVIC_RESETFAULTMASK(void);上面两组函数要成对使用,不能交叉使用。

例如:第一种方法:NVIC_SETPRIMASK();//关闭总中断NVIC_RESETPRIMASK();//开放总中断第二种方法:NVIC_SETFAULTMASK();//关闭总中断NVIC_RESETFAULTMASK();//开放总中断常常使用NVIC_SETPRIMASK(); // Disable InterruptsNVIC_RESETPRIMASK(); // Enable Interrupts二、STM32时钟系统STM32资料2009-09-23 14:53 阅读72 评论0字号:大大中中小小在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。

①、HSI是高速内部时钟,RC振荡器,频率为8MHz。

②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。

③、LSI是低速内部时钟,RC振荡器,频率为40kHz。

④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。

⑤、PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。

倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。

图1 HSE/LSE时钟源其中40kHz的LSI供独立看门狗IWDG使用,另外它还可以被选择为实时时钟RTC的时钟源。

另外,实时时钟RTC的时钟源还可以选择LSE,或者是HSE的128分频。

RTC的时钟源通过RTCSEL[1:0]来选择。

STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。

该时钟源只能从PLL输出端获取,可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL必须使能,并且时钟频率配置为48MHz或72MHz。

另外,STM32还可以选择一个时钟信号输出到MCO脚(PA8)上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。

系统时钟SYSCLK,它是供STM32中绝大部分部件工作的时钟源。

系统时钟可选择为PLL 输出、HSI或者HSE。

系统时钟最大频率为72MHz,它通过AHB分频器分频后送给各模块使用,AHB分频器可选择1、2、4、8、16、64、128、256、512分频。

其中AHB分频器输出的时钟送给5大模块使用:①、送给AHB总线、内核、内存和DMA使用的HCLK时钟。

②、通过8分频后送给Cortex的系统定时器时钟。

③、直接送给Cortex的空闲运行时钟FCLK。

④、送给APB1分频器。

APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给定时器(Timer)2、3、4倍频器使用。

该倍频器可选择1或者2倍频,时钟输出供定时器2、3、4使用。

⑤、送给APB2分频器。

APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给定时器(Timer)1倍频器使用。

该倍频器可选择1或者2倍频,时钟输出供定时器1使用。

另外,APB2分频器还有一路输出供ADC分频器使用,分频后送给ADC模块使用。

ADC分频器可选择为2、4、6、8分频。

在以上的时钟输出中,有很多是带使能控制的,例如AHB总线时钟、内核时钟、各种APB1外设、APB2外设等等。

当需要使用某模块时,记得一定要先使能对应的时钟。

需要注意的是定时器的倍频器,当APB的分频为1时,它的倍频值为1,否则它的倍频值就为2。

连接在APB1(低速外设)上的设备有:电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3、SPI2、窗口看门狗、Timer2、Timer3、Timer4。

注意USB模块虽然需要一个单独的48MHz时钟信号,但它应该不是供USB模块工作的时钟,而只是提供给串行接口引擎(SIE)使用的时钟。

USB模块工作的时钟应该是由APB1提供的。

连接在APB2(高速外设)上的设备有:UART1、SPI1、Timer1、ADC1、ADC2、所有普通IO口(PA~PE)、第二功能IO口。

下图是STM32用户手册中的时钟系统结构图,通过该图可以从总体上掌握STM32的时钟系统。

三、STM32外部中断STM32资料2009-09-10 21:18 阅读243 评论0字号:大大中中小小STM32 外部中断配置1配置中断1、分配中断向量表:/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_V ectTab_RAM, 0x0);2、设置中断优先级:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //设置中断优先级3、初始化外部中断:/*允许EXTI4中断*/NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel; //中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;//强占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //次优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能NVIC_Init(&NVIC_InitStructure); //初始化中断注意:如果我们配置的外部针脚为PA4,或PB4,或PC4,PD4等,那么采用的外部中断也必须是EXTI4,同样,如果外部中断针脚是PA1,PB1,PC1,PD1 那么中断就要用EXTI1,其他类推。

相关文档
最新文档