精华内容
下载资源
问答
  • STM32 中断原理及外部中断的实现
    千次阅读
    2021-01-18 15:39:09

    内容较充实,作为个人的学习记录

    NVIC 中断优先级管理

    Nested Vectored Interrupt Controller,嵌套向量中断控制器。

    CM3支持256个中断,16个内核中断,240个外部中断,256级可编程中断设置。

    STM32使用了其中一部分,16个内核中断,107系列有68个可屏蔽中断(103系列只有60个),16级可编程的中断优先级。




    中断寄存器

    • ISER[8],Interrupt Set-Enable Registers,中断使能寄存器组,用8个32位寄存器控制(256个可编程中断),每个位控制一个中断。由于STM32f103只有60个可屏蔽中断,于是只用了 ISER[0] 和 ISER[1] 64个中断中的前60位。

    • ISER[0] 的 bit0 至 bit31 对应中断0至31,ISER[1] 的 bit0 至 bit27 对应中断32至59,使能某个中断就将对应的 ISER 置1

    • ICER[8],Interrupt Clear-Enable Register,中断除能寄存器组。中断对应与ISER相同,但作用是置1清除中断使能

    • ISPR[8],Interrupt Set-Pending Register,中断挂起控制寄存器组。置1将正在进行的中断挂起,暂停等待执行,执行同级或更高级别的中断

    • ICPR[8],Interrupt Clear-Pending Register,中断解挂控制寄存器组,置1将挂起的中断解挂

    • IABR[8],Interrupt Active Bit Register,中断激活标志位寄存器组,只读寄存器为1表示该位对应的中断正在被执行

    • IP[240],Interrupt Priority Registers,中断优先级控制寄存器组,相当重要! STM32的中断分组与其密切相关。

      IP[240]有240个8bit寄存器组成,每个可屏蔽中断占用8bit,总共可表示240个可屏蔽中断,STM32f1使用其中60个,IP[59]至IP[0]分别对应中断59至0。每个可屏蔽中断只用高4位,分为抢占优先级响应优先级,抢占优先级在前、响应优先级在后,各占几位由SCB->AIRCR中的中断分组设置。采用库函数==NVIC_PriorityGroupConfig () ==配置。

      AIRCR
      如果组设置为3,则每个中断的中断优先寄存器高4位中前3位是抢占优先级,优先级级别0-7;低1位是响应优先级,优先级级别0-1。

      STM32的中断向量有抢占属性和响应属性,属性编号越小,优先级别越高。

      抢占属性是打断其他中断的属性,有这个属性就有嵌套中断。由库函数NVIC_IRQChannelPreemptionPriority() 进行参数配置。

      响应属性应用在抢占属性相同时(前提),两个中断向量的抢占优先级相同时,如果同时到达,则优先处理响应优先级高的中断。由库函数NVIC_IRQChannelSubPriority() 进行参数配置。




    库函数配置

    NVIC 中断管理函数声明在 misc.c 文件里


    1. 中断优先级分组函数 NVIC_PriorityGroupConfig()

    此函数在系统工程中只能被调用一次!一旦确定好中断分组就不能更改!

    目前了解到的在主函数中调用该函数


    F12 查看函数定义块:

    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
    {
     	assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
    	SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
    }
    

    可以看到,这个函数通过设置 SCB->AIRCR 寄存器设置中断分组。

    补充:

    assert_param(),断言机制函数,在stm32f10x_conf.h文件中可以看到 assert_param() 是一个宏定义,作用就是检测传递给函数的参数是否是有效的参数,返回值是 0假 1真。


    中断优先组配置示例:分组值为2,2优先2抢占:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    

    暂时看到的此函数调用都是在主函数里,以后看到其他程序结构再补充:
    main



    2. 中断初始化函数 NVIC_Init

    函数定义:

    void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
    

    查看结构体 NVIC_InitTypeDef 的成员变量:

    typedef struct
    {
     	uint8_t NVIC_IRQChannel; 
     	uint8_t NVIC_IRQChannelPreemptionPriority;
     	uint8_t NVIC_IRQChannelSubPriority; 
     	FunctionalState NVIC_IRQChannelCmd; 
    } NVIC_InitTypeDef;
    
    • NVIC_IRQChannel,定义初始化的是哪个中断,例如 USART1_IRQn
    • NVIC_IRQChannelPreemptionPriority,定义这个中断的抢占优先级别,级别数不超过2的“抢占优先级位数”次方。(一个是位数,一个是级别数)
    • NVIC_IRQChannelSubPriority,定义这个中断的响应优先级别,级别数不超过2的“响应优先级位数”次方。
    • NVIC_IRQChannelCmd,该中断是否使能

    IRQ全称为Interrupt Request,即是“中断请求”的意思


    中断初始化配置示例:

    NVIC_InitTypeDef NVIC_InitStructure;
    
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    //串口 1 中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
    // 抢占优先级为 1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    // 响应优先级为 2
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    //IRQ 通道使能
    NVIC_Init(&NVIC_InitStructure); 
    //根据上面指定的参数初始化 NVIC 寄存器
    

    通常如果写外部中断时,此代码块放在 \exti.c\EXTI_Init() 函数内部,每个端口配置结束都需要一个NVIC_Init(&NVIC_InitStructure);




    小结

    中断优先级设置的步骤:

    1. 系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和子优先级的分配位数。调用函数为 NVIC_PriorityGroupConfig();
    2. 设置所用到的中断的中断优先级别,对每个中断调用函数为 NVIC_Init();




    STM32 外部中断

    基础知识

    STM32 外部 IO 口的中断功能

    文件: stm32f10x_exti.c/h

    每个 IO 口都可以作为外部中断的中断输入口,支持19个外部中断/事件请求,每个中断设有状态位、独立的触发/屏蔽设置。

    19个外部中断为:

    • 线 0-15:对应外部 IO 口的输入中断 (供 IO 口使用的中断线)
    • 线 16 :连接到PVD输出(Programmable Votage Detector,可编程电压监测器)
    • 线 17 :连接到RTC闹钟事件
    • 线 18 :连接到USB唤醒事件

    映射方式:

    映射关系
    每个中断线对应最多7个IO口,但每次只能连接到一个IO口上,利用选择器的配置来决定中断线配置到哪个IO口上去。



    库函数配置

    1. 映射关系配置 GPIO_EXTILineConfig()

    外部中断端口映射配置示例 (GPIOE_2 与 EXTI_2):

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
    


    2. 中断初始化 EXTI_Init()

    void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
    //结构体函数参数
    

    查看一下结构体:

    typedef struct
    {
     	uint32_t EXTI_Line; 
     	EXTIMode_TypeDef EXTI_Mode; 
     	EXTITrigger_TypeDef EXTI_Trigger; 
     	FunctionalState EXTI_LineCmd; 
    }EXTI_InitTypeDef;
    

    有4个需要设置的参数:

    1. 中断线标号,EXTI_Line0~EXTI_Line15
    2. 中断模式,中断 EXTI_Mode_Interrupt 和事件 EXTI_Mode_Event
    3. 触发方式,下降沿触发 EXTI_Trigger_Falling,上升沿触发 EXTI_Trigger_Rising,任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling
    4. 使能,ENABLE

    中断事件的区别


    简而言之,中断是需要经过芯片内部程序处理,然后跳转的中断程序
    事件是检测到某一动作(电平边沿)触发事件发生了,进而由提前设置好的相应的联动硬件自动完成产生的结果


    中断是红线
    事件是绿线中断和事件


    外部中断初始化配置示例:

    EXTI_InitTypeDef EXTI_InitStructure;
    //定义结构体
    EXTI_InitStructure.EXTI_Line=EXTI_Line4;
    //中断线4
    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 寄存器
    


    3. 设置中断线2的中断优先级

    优先级配置见第一部分NVIC的配置

    NVIC_InitTypeDef NVIC_InitStructure;
    //定义NVIC结构体
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; 
    //使能按键外部中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; 
    //抢占优先级 2,
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; 
    //响应优先级 2
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    //使能外部中断通道
    NVIC_Init(&NVIC_InitStructure); 
    //中断优先级分组初始化
    


    4. 中断服务函数

    STM32一共15个IO口外部中断线,共有6个中断函数:

    EXPORT EXTI0_IRQHandler
    EXPORT EXTI1_IRQHandler
    EXPORT EXTI2_IRQHandler
    EXPORT EXTI3_IRQHandler
    EXPORT EXTI4_IRQHandler
    EXPORT EXTI9_5_IRQHandler
    EXPORT EXTI15_10_IRQHandler

    0-4每个中断线对应一个中断函数,5-9共用EXTI9_5_IRQHandler,10-15共用EXTI15_10_IRQHandler

    当多线共用一个处理函数的时候,就必须写EXTI_GetITStatus()判断到底是哪一线中断请求


    • 1. ITStatus EXTI_GetITStatus();

    用在中断服务函数的开头,判断中断是否发生

    EXTI_GetFlagStatus()与之的区别
    EXTI_GetITStatus() 函数中会先判断这种中断是否使能,使能了才去判断中断标志位
    而EXTI_GetFlagStatus() 直接用来判断状态标志位


    • 2. EXTI_ClearITPendingBit(EXTI_Line0);

    中断服务函数结束之前调用,清除某中断线上的中断标志位

    EXTI_ClearFlag(),与之功能相同


    常用的中断服务函数格式:

    void EXTI2_IRQHandler(void)
    {
    	if(EXTI_GetITStatus(EXTI_Line2)!=RESET)
    	//判断某个线上的中断是否发生 
    	{
    		中断逻辑…
    		
    		EXTI_ClearITPendingBit(EXTI_Line2); 
    		//清除 LINE 上的中断标志位 
    	} 
    }
    


    外部中断配置示例

    1. exit.c

    包含4个函数:

    • EXTI_Init()

      外部中断初始化,(以按键功能为例):

    void EXTIX_Init(void)
    {
     EXTI_InitTypeDef EXTI_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;
     //调用结构体
    
    1. 调用 KEY_Init 函数,来初始化外部中断输入的 IO 口。
    KEY_Init();
    //初始化按键对应 io 模式
    
    1. 调用RCC_APB2PeriphClockCmd()函数来使能复用功能时钟。
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    //外部中断,需要使能 AFIO 时钟
    
    1. 接着配置中断线和 GPIO 的映射关系。
    //GPIOC.5 与中断线5映射
      	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
    
    1. 然后初始化中断线。
    EXTI_InitStructure.EXTI_Line=EXTI_Line5;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
    
    1. 中断初始化、配置优先级
     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;					
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								
     NVIC_Init(&NVIC_InitStructure); 
    
    • EXTI0_IRQHandler()

    中断处理函数

    void EXTI0_IRQHandler(void)
    {
      delay_ms(10);   
    	if(WK_UP==1)//WK_UP在key.h文件中定义
    	{	  
    		LED0=!LED0;//LED0在led.h文件中定义
    		LED1=!LED1;	
    	}
    	EXTI_ClearITPendingBit(EXTI_Line0); 
    	//清除EXTI0线路挂起位
    }
    
    • EXTI9_5_IRQHandler()
    • EXTI15_10_IRQHandler()




    小结

    使用 IO 口外部中断的一般步骤:

    1. 初始化 IO 口为输入
    2. 开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。
    3. 初始化线上中断(EXTI),设置触发条件等。
    4. 配置中断分组(NVIC),并使能中断。
    5. 编写中断服务函数。
    更多相关内容
  • 通过一条外部中断线或外部事件线的示意图,讲解STM32中断与事件的区别。
  • STM32中断流程处理

    2018-04-30 14:58:33
    中断的定义:指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程。即在程序运行过程中,中断的定义:指当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的程序和执行过程。即...
  • STM32中断配置器,懒人STM32,一键搞定32定时器和外部中断,让32中断不再望城莫及,轻松写代码。
  • 在Keil MDK 5的软件是,STM32进入停止模式,然后使用中断唤醒的方式唤醒,有需要可以相互交流
  • STM32中断

    千次阅读 2021-11-02 09:31:31
    STM32中断控制LED灯一、STM32中断1. 概念2. 中断响应过程3. 中断优先级二、仿中断高低电平控制LED灯1. CubeMx2. 控制代码编写三、总结四、参考 一、STM32中断 1. 概念 中断是由内核外部产生的,一般由硬件引起,...

    一、STM32中断

    1. 概念

    • 中断是由内核外部产生的,一般由硬件引起,比如外设中断和外部中断等。

    2. 中断响应过程

    1. 中断源发出中断请求
    2. 判断处理器是否允许中断,以及该中断源是否被屏蔽
    3. 中断优先级排队
    4. 处理器暂停当前程序,保护断点地址和处理器的当前状态,根据中断类型号,查找中断向量表,转到对应的中断服务程序
    5. 执行中断服务程序
    6. 恢复被保护的状态,执行中断返回指令,回到被中断的程序

    中断全过程
    在这里插入图片描述
    中断分为同步中断和异步中断:

    • 同步中断:同步中断是当指令执行时由控制单元产生的,之所以称为同步,是因为只有在一条指令终止执行后 CPU 才会发出中断。
    • 异步中断:异步中断是由其他硬件设备依照 CPU时钟信号随机产生的。

    3. 中断优先级

    在这里插入图片描述

    • 多个中断同时出现时,处理器先响应高优先级的中断
    • 低优先级中断的ISR执行时,可以被高优先级中断再次打断
    • ISR比App Code拥有更高的执行优先级

    二、仿中断高低电平控制LED灯

    1. CubeMx

    1. 进入STM32CubeMX新建项目
      2.
    2. 检索所需芯片,并完成项目的基础创建
      在这里插入图片描述
    3. 点击sys,将debug->Serial Wire
      在这里插入图片描述
    4. Rcc->HSE->Crystal/Ceramic Resonator
      在这里插入图片描述
    5. 将PB0选为外部中断触发器,PA2控制led灯的->GPIO_output
      在这里插入图片描述
      在这里插入图片描述
      • 设置中断触发器B0
        在这里插入图片描述
    6. PLLCLK,晶振频率最大值改为72M赫兹
      在这里插入图片描述
    7. NVIC设置:
      在这里插入图片描述
    8. 完成项目生成
      • Project配置
        在这里插入图片描述
      • Code Generator
        在这里插入图片描述
      • 项目生成
        在这里插入图片描述

    2. 控制代码编写

    1. 打开工程,搜索HAL_GPIO_EXTI_Callback函数:
      在这里插入图片描述
      • 弱函数,需要重写
        在这里插入图片描述
    2. main.c中编写回调函数
    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
    	GPIO_PinState b0_pin = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);  // 读取b0的状态
    	switch (GPIO_Pin){
    		case GPIO_PIN_0:
    			HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, b0_pin);  // 将a2写入与b0相同的电位
    			break;
    	}	
    }
    

    在这里插入图片描述
    3. 编译并烧录
    在这里插入图片描述
    使用mscuip进行烧录
    在这里插入图片描述
    4. 运行结果
    在这里插入图片描述

    三、HAL库中断方式进行串口通信

    1. CudeMX配置项目

    1. 点击sys,将debug->Serial Wire
      在这里插入图片描述
    2. Rcc->HSE->Crystal/Ceramic Resonator
      在这里插入图片描述
    3. A-Z->USART1->Mode
      在这里插入图片描述
    4. NVIC设置:
      在这里插入图片描述
    5. 完成项目生成
      • Project配置
        在这里插入图片描述

      • Code Generator
        在这里插入图片描述

      • 项目生成
        在这里插入图片描述

    2. Keil代码设置

    1. main函数定义缓冲区大小
    #define LENGTH 10   // 接收缓冲区大小
    

    在这里插入图片描述
    2. 定义缓冲区和标志位

    uint8_t RxBuffer[LENGTH];   // 接收缓冲区
    uint8_t Rxflag = 0;    // 标志位,0为接收未完成,1为接收完成
    

    在这里插入图片描述
    3. 定义接收成功信息

    HAL_UART_Receive_IT(&huart1, (uint8_t*)RxBuffer, LENGTH);  // 使能接收中断
    char data[] = "\nReveive Success\n";  // 接收成功信息
    
    1. while循环发送信息与接收信息
    if (Rxflag == 1){ // 若数据接收完成
    	Rxflag = 0;  // 清除标志位
    	HAL_UART_Transmit(&huart1, (uint8_t *)data, 18, 0xFFFF);  // 接收成功信息
    	// 发送接收到的字符
    	HAL_UART_Transmit_IT(&huart1, (uint8_t*)RxBuffer, LENGTH);
    }
    
    
    1. 定义回调函数
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
    	if (huart->Instance == USART1){
    		Rxflag = 1;  // 设置标志位为1
    		HAL_UART_Receive_IT(&huart1, (uint8_t*)&RxBuffer, LENGTH); // 使能接收中断
    	}
    }
    

    在这里插入图片描述
    6. 编译烧录
    在这里插入图片描述
    7. 运行效果
    在这里插入图片描述

    四、总结

    • 中断方式不必等待数据的传输过程,只需要在每字节数据收发完成后,由中断标志位触发中断,在中断服务程序中放入新的一字节数据或者读取接收到的一字节数据。
    • 提高Cpu的运行效率,可以处理突发事件

    五、参考

    STM32之中断控制LED灯
    STM32中断控制的流程
    【嵌入式11】HAL库实验中断开关点灯及串口通信
    【STM32CubeMX】HAL库中断方式UART串口通信
    HAL库中断方式进行串口通信

    展开全文
  • STM32中断优先级详细讲解,还有简单的例子。综述,有限级判断,优先级分组等。
  • 中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大大增加,而且中断的设置也更加复杂。...
  • STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。
  • STM32 外部中断简介

    2020-08-11 08:13:53
    STM32 IO 口中断的一些基础概念。STM32 的每个 IO 都可以作为外部中断中断输入口,这点也是 STM32 的强大之处。STM32F103 的中断控制器支持 19 个外部中断/事件请求。
  • 断断续续学习STM32一学期了,时间过的好快,现在对STM32F103系列单片机的中断嵌套及外部中断做一个总结,全当学习笔记。废话不多说,ARM公司的Cortex-m3 内核,支持256个中断,其中包含16个内核中断和240个外部中断...
  • STM32中断相关知识总结

    千次阅读 2020-10-07 21:58:00
    STM32中断相关知识总结 一:中断是什么? 中断是指处理器运行过程中,出现某些意外情况,CPU能自动停止正在运行的程序并转入处理新情况的程序(中断服务函数),处理完毕后又返回原被暂停的程序继续运行。 CM3和CM7 ...

    STM32中断相关知识总结

    一:中断是什么?

    中断是指处理器运行过程中,出现某些意外情况,CPU能自动停止正在运行的程序并转入处理新情况的程序(中断服务函数),处理完毕后又返回原被暂停的程序继续运行。
    CM3和CM7 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。但 STM32 并没有使用 CM3或CM7 内核的全部东西,而是只用了它的一部分。STM32F1系列有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断,STM32F767xx总共有118个中断,包括10个内核中断和108个可屏蔽中断,他们都具有16级可编程的中断优先级。我们经常使用的一般是它们的可屏蔽中断。

    二:什么是可屏蔽中断和不可屏蔽中断?
    1:可由程序控制其屏蔽的中断称为可屏蔽中断。
    2:不能由程序控制其屏蔽,处理机一定要立即处理的中断称为非屏蔽中断或不可屏蔽中断。
    不可屏蔽中断主要用于断电、电源故障等必须立即处理的情况

    三:内核中断和外部中断
    STM32的内核中断
    在这里插入图片描述
    STM32的外部中断
    在这里插入图片描述

    四:什么是中断优先级
    在实际系统中,常常遇到多个中断源同时请求中断的情况,这时CPU必须确定首先为哪一个中断源服务,以及服务的次序。解决的方法是中断优先排队,即根据中断源请求的轻重缓急,排好中断处理的优先次序即优先级( Priority ),又称优先权,先响应优先级最高的中断请求。另外,当CPU正在处理某一中断时,要能响应另一个优先级更高的中断请求,而屏蔽掉同级或较低级的中断请求,形成中断嵌套。优先级的数值越小,则优先级越高。CM3 支持中断嵌套,使得高优先级异常会抢占(preempt)低优先级异常。
    CM3 支持 3 个固定的高优先级和多达 256 级的可编程优先级,为了使抢占机能变得更可控,CM3 还把 256 级优先级按位分成高低两段,分别是抢占优先级和亚优先级,使得其最多支持 128级抢占,因为至少有一个位代表亚优先级。但是,绝大多数 CM3 芯片都会精简设计,以致实际上支持的优先级数会更少,如 8 级,16 级,32 级等。它们在设计时会裁掉表达优先级的几个低端有效位,以达到减少优先级数的目的。
    在这里插入图片描述
    NVIC 中有一个寄存器是“应用程序中断及复位控制寄存器”(ARICR),它里面有一个位段名为“优先级组”。该位段的值对每一个优先级可配置的异常都有影响——把其优先级分为个位段:MSB 所在的位段(左边的)对应抢占优先级,而 LSB 所在的位段(右边的)对应亚优先级,如表 7-4 所示
    在这里插入图片描述
    实际在使用过程中STM32裁掉了第0-3位,以达到减少优先级数的目的。将中断分为5个组,组0-4,与上述分组恰好相反。该分组的设置是由SCB->AIRCR 寄存器的 bit10~8 来定义的。
    在这里插入图片描述通过这个表,可以清楚的看到组 0-4 对应的配置关系,例如分组设置为 3,那么此时所有的中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是响应优先级。每个中断,你可以设置抢占优先级为 0-7,响应优先级为 1 或 0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高

    五:抢占优先级和响应优先级的区别?
    1:高优先级的抢占优先级可以打断正在进行的低抢占优先级中断。
    2:抢占优先级相同的中断、高优先级不可以打断低响应优先级的中断。
    3:抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
    4:如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。
    实例说明:假定设置中断优先级组为 2,然后设置
    中断 3(RTC 中断)的抢占优先级为 2,响应优先级为 1。
    中断 6(外部中断 0)的抢占优先级为 3,响应优先级为 0。
    中断 7(外部中断 1)的抢占优先级为 2,响应优先级为 0。
    那么这 3 个中断的优先级顺序为:中断 7>中 断 3>中断 6。中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3 却不可以相互打断!

    六:中断优先级分组函数

    //设置 NVIC 分组
    //NVIC_Group:NVIC 分组 0~4 总共 5 组 
    void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
    { 
    u32 temp,temp1; 
    //为什么取“反”,注意优先级分组的标志,111对应组0,110对应组1
    //可以看到都是相应的组号取反后的结果
    temp1=(~NVIC_Group)&0x07;//取后三位
    temp1<<=8;
    temp=SCB->AIRCR; //读取先前的设置
    temp&=0X0000F8FF; //清空先前分组
    temp|=0X05FA0000; //写入钥匙
    temp|=temp1; //写入优先级分组
    SCB->AIRCR=temp; //设置分组
    }
    

    STM32 的 5 个分组是通过设置 SCB->AIRCR 的 BIT[10:8]来实现的, SCB->AIRCR 的修改需要通过在高 16 位写入 0X05FA 这个密钥才能修改的,故在设置 AIRCR 之前,应该把密钥加入到要写入的内容的高 16 位,以保证能正常的写入 AIRCR。在修改 AIRCR 的时候,我们一般采用读-改-写的步骤,来实现不改变 AIRCR 原来的其他设置。

    七:什么是中断向量表
    当发生了异常/中断并且要响应它时,CM3 需要定位其处理例程(中断服务函数)的入口地址。这些入口地址存储在所谓的“(异常)向量表”中
    在这里插入图片描述
    该向量表便定义了相关硬件发生中断时中断处理函数的入口地址。

    八:STM32响应中断的处理过程(摘自Cotex-M3权威指南(中文)第七章)
    在这里插入图片描述
    当中断输入脚被 assert 后,该中断就被悬起。即使后来中断源取消了中断请求,已经被标记成悬起的中断也被记录下来。到了系统中它的优先级最高的时候,就会得到响应。
    但是,如果在某个中断得到响应之前,其悬起状态被清除了(例如,在 PRIMASK 或FAULTMASK 置位的时候软件清除了悬起状态标志),则中断被取消,如图 7.9 所示。
    在这里插入图片描述
    当某中断的服务例程开始执行时,就称此中断进入了“活跃”状态,并且其悬起位会被硬件自动清除,如图 7.10 所示。在一个中断活跃后,直到其服务例程执行完毕,并且返回(亦称为中断退出,第九章详细讨论)了,才能对该中断的新请求予以响应(即单实例)。
    当然,新请求的响应亦是由硬件自动清零悬起标志位。中断服务例程也可以在执行过程中把自己对应的中断重新悬起(使用时要注意避免进入“死循环”——译注)
    在这里插入图片描述
    如果中断源咬住请求信号不放,该中断就会在其上次服务例程返回后再次被置为悬起状态,如图 7.11 所示。这一点上 CM3 和传统的 ARM7TDMI 是相同的
    在这里插入图片描述
    另一方面,如果某个中断在得到响应之前,其请求信号以若干的脉冲的方式呈现,则被视为只有一次中断请求,多出的请求脉冲全部错失——这是中断请求太快,以致于超出处理器反应限度的情况。如图 7.12 所示。
    在这里插入图片描述
    在这里插入图片描述

    九:中断设置相关寄存器

    NVIC(nested vector interupt controller)向量中断控制器
    在这里插入图片描述

    typedef struct
    {
     __IO uint32_t ISER[8]; //中断使能寄存器组
     uint32_t RESERVED0[24];
     __IO uint32_t ICER[8]; //中断除能寄存器组
     uint32_t RSERVED1[24];
     __IO uint32_t ISPR[8]; //中断挂起控制寄存器组
     uint32_t RESERVED2[24];
     __IO uint32_t ICPR[8]; //中断解挂控制寄存器组
     uint32_t RESERVED3[24];
     __IO uint32_t IABR[8]; //中断激活标志位寄存器组
     uint32_t RESERVED4[56];
     __IO uint8_t IP[240]; //中断优先级控制寄存器组
     uint32_t RESERVED5[644];
     __O uint32_t STIR; //软件触发中断寄存器组
    } NVIC_Type;
    

    ISER[8]:ISER 全称是:Interrupt Set-Enable Registers,这是一个中断使能寄存器组。 CM3 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断。但是STM32 的可屏蔽中断最多只有 68 个(互联型),所以对我们来说,有用的就是三个(ISER[0~2]]),总共可以表示 96 个中断。而 STM32 只用了其中的前 68 位。ISER[0]的 bit0~31 分别对应中断0~31;ISER[1]的 bit0~32 对应中断 32~63;ISER[2]的 bit0~3 对应中断 64~67;这样总共 68 个中断就分别对应上了。你要使能某个中断,必须设置相应的 ISER 位为 1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、IO 口映射等设置才算是一个完整的中断设置)。
    ICER[8]:全称是:Interrupt Clear-Enable Registers,是一个中断除能寄存器组。该寄存器组与 ISER 的作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和 ICER 一样。这里要专门设置一个 ICER 来清除中断位,而不是向 ISER 写 0 来清除,是因为 NVIC 的这些寄存器都是写 1 有效的,写 0 是无效的。具体为什么这么设计,是因为通过这种方式,使能/除能中断时只需把“当事位”写成1,其它的位可以全部为零。再也不用像以前那样,害怕有些位被写入 0 而破坏其对应的中断设置(写 0 没有效果),从而实现每个中断都可以自顾地设置,而互不侵犯——只需单一的写指令,不再需要读‐改‐写。
    在这里插入图片描述
    ISPR[8]:全称是:Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。如果中断发生时,正在处理同级或高优先级异常,或者被掩蔽,则中断不能立即得到响应。此时中断被悬起。中断的悬起状态可以通过“中断设置悬起寄存器(SETPEND)”和“中断悬起清除寄存器(CLRPEND)”来读取,还可以写它们来手工悬起中断。每个位对应的中断和 ISER 是一样的。通过置 1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写 0 是无效的。
    ICPR[8]:全称是:Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。其作用与 ISPR 相反,对应位也和 ISER 是一样的。通过设置 1,可以将挂起的中断接挂。写 0 无效。
    在这里插入图片描述

    IABR[8]:全称是:Interrupt Active Bit Registers,是一个中断激活标志位寄存器组。对应位所代表的中断和 ISER 一样,如果为 1,则表示该位所对应的中断正在被执行。这是一个只读寄
    存器,通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。由于支持嵌套,允许高优先级异常抢占某个ISR。然而,哪怕一个中断被抢占,其活动状态也依然为1。
    在这里插入图片描述

    IP[240]:全称是:Interrupt Priority Registers,是一个中断优先级控制的寄存器组。这个寄
    存器组相当重要!STM32 的中断分组与这个寄存器组密切相关。IP 寄存器组由 240 个 8bit 的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。而 STM32 只用到了其中的 68 个。IP[67]~IP[0]分别对应中断 67~0。而每个可屏蔽中断占用的 8bit 并没有全部使用,而是 只用了高 4 位。这 4 位,又分为抢占优先级和子优先级。抢占优先级在前,子优先级
    在后。而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定。
    在这里插入图片描述
    十:相关配置函数

    //设置 NVIC 
    //NVIC_PreemptionPriority:抢占优先级
    //NVIC_SubPriority :响应优先级
    //NVIC_Channel :中断编号
    //NVIC_Group :中断分组 0~4
    //注意优先级不能超过设定的组的范围!否则会有意想不到的错误
    //组划分:
    //组 0:0 位抢占优先级,4 位响应优先级
    //组 1:1 位抢占优先级,3 位响应优先级
    //组 2:2 位抢占优先级,2 位响应优先级
    //组 3:3 位抢占优先级,1 位响应优先级
    //组 4:4 位抢占优先级,0 位响应优先级
    //NVIC_SubPriority 和 NVIC_PreemptionPriority 的原则是,数值越小,越优先
    void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,
    u8 NVIC_Group)
    { 
    u32 temp;
    MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
    temp=NVIC_PreemptionPriority<<(4-NVIC_Group); 
    temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
    temp&=0xf; //取低四位 
    NVIC->ISER[NVIC_Channel/32]|=(1<<NVIC_Channel%32);
    //使能中断位(要清除的话,相反操作就 OK) 
    NVIC->IP[NVIC_Channel]|=temp<<4; //设置响应优先级和抢断优先级
    }
    

    十一:STM32中断控制的流程(重要)
    https://www.cnblogs.com/yihuihong/p/4967636.html

    十二:中断的具体行为
    在这里插入图片描述

    参考:《STM32不完全手册_寄存器版本_V3.1》
    《Cortex-M3权威指南(中文)》
    正点原子相关教程

    展开全文
  • stm32中断按键

    2015-07-28 01:02:06
    stm32中断按键,里面有中断 按键 串口程序
  • 本文主要讲了关于STM32的一些相关知识,下面一起来学习一下
  • STM32外部中断实验

    2018-11-14 10:54:47
    亲测可用,可以用来做STM32的外部中断,有问题可以联系或者在评论区评论
  • STM32GPIO外部中断总结

    2020-07-15 00:32:35
    STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处。
  • STM32中断编程步骤

    千次阅读 2020-07-01 19:36:45
    介绍stm32f10x中断的概念,已经中断向量表,还有中断编程的一下要点,涉及的一下寄存器

    前言

    51单片机了解过中断,现在又来看嵌入式的有关中断,涉及的寄存器就有些复杂了。不过中断是一定要搞懂的。

    STM32 中断非常强大,可产生中断嵌套,每个外设都可以产生中断,所以中断的讲解放在哪一个外设里面去讲都不合适,这里单独抽出一章来做一个总结性的介绍。如无特别说明,异常就是中断,中断就是异常。

    1.中断处理

    中断处理

    2.异常类型(中断向量表)

    灰色的是系统异常,体现在内核水平
    白色的是外部中断,体现在外设水平

    F103 在内核水平上搭载了一个异常响应系统, 支持为数众多的系统异常和外部中断。其中系统异常有 8 个(如果把 Reset 和 HardFault 也算上的话就是 10 个) ,外部中断有 60个。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。有关具体的系统异常和外部中断可在标准库文件 stm32f10x.h 这个头文件查询到,在 IRQn_Type 这个结构体里面包含了 F103 系列全部的异常声明。

    有关系统异常和外部中断的清单可查阅参考手册第9章的向量表部分。
    STM32F10xxx产品(小容量、中容量和大容量)的向量表:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    3.NVIC(嵌套向量中断控制器)

    它控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对 Cortex-M3 内核里面的 NVIC 进行裁剪,把不需要的部分去掉,所以说 STM32 的 NVIC 是 Cortex-M3 的 NVIC 的一个子集。

    两个重要的库文件:core_cm3.h和misc.h
    NVIC 结构体定义,来自固件库头文件: core_cm3.h

    typedef struct {
    __IO uint32_t ISER[8]; // 中断使能寄存器
    uint32_t RESERVED0[24];
    __IO uint32_t ICER[8]; // 中断清除寄存器
    uint32_t RSERVED1[24];
    __IO uint32_t ISPR[8]; // 中断使能悬起寄存器
    uint32_t RESERVED2[24];
    __IO uint32_t ICPR[8]; // 中断清除悬起寄存器
    uint32_t RESERVED3[24];
    __IO uint32_t IABR[8]; // 中断有效位寄存器
    uint32_t RESERVED4[56];
    __IO uint8_t IP[240]; // 中断优先级寄存器(8Bit wide)
    uint32_t RESERVED5[644];
    __O uint32_t STIR; // 软件触发中断寄存器
    } NVIC_Type;
    

    在配置中断的时候我们一般只用 ISER、 ICER 和 IP 这三个寄存器, ISER 用来使能中断, ICER 用来失能中断, IP 用来设置中断优先级。

    4.中断优先级

    4.1 优先级定义

    中断优先级决定了一个中断是否被屏蔽以及在未屏蔽的情况下何时可以响应。

    在 NVIC 有一个专门的寄存器:中断优先级寄存器NVIC_IPRx, 用来配置外部中断的优先级, IPR 宽度为 8bit,原则上每个外部中断可配置的优先级为 0~255,数值越小,优先级越高。但是绝大多数 CM3 芯片都会精简设计,以致实际上支持的优先级数减少,在F103 中,只使用了高 4bit,如下所示:

    在这里插入图片描述用于表达优先级的这 4bit,又被分组成抢占优先级和子优先级。如果有多个中断同时响应,抢占优先级高的就会 抢占 抢占优先级低的优先得到执行,如果抢占优先级相同,就比较子优先级。如果抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号,编号越小,优先级越高。

    4.1 优先级分组

    优先级的分组由内核外设 SCB 的应用程序中断及复位控制寄存器 AIRCR 的PRIGROUP[10:8]位决定, F103 分为了 5 组,具体如下:主优先级=抢占优先级
    在这里插入图片描述
    设置优先级分组可调用库函数 NVIC_PriorityGroupConfig()实现,有关 NVIC 中断相关的库函数都在库文件 misc.c 和 misc.h 中。

    优先级分组真值表
    在这里插入图片描述

    5.中断服务函数(ESR)

    通常用 PPP_IRQHandler命名

    6.中断编程

    在配置每个中断的时候一般有 4 个编程要点:
    1、 使能中断请求(配置外设寄存器)

    2、中断优先级分组(SCB-AIRCR寄存器)

    3、 初始化 NVIC_InitTypeDef 结构体:
    (1)NVIC_IROChannel:用来设置中断源,不同的中断中断源不一样,且不可写错,即使写错了程序也不会报错,只会导致不响应中断。具体的成员配置可参考 stm32f10x.h 头文件里面的 IRQn_Type 结构体定义,这个结构体包含了所有的中断源。

    (2)NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定。

    (3)NVIC_IRQChannelSubPriority:子优先级,具体的值要根据优先级分组来确定

    (4)NVIC_IRQChannelCmd:中断使能( ENABLE)或者失能( DISABLE)。操作的是 NVIC_ISER 和 NVIC_ICER 这两个寄存器。

    4、 编写中断服务函数
    在启动文件 startup_stm32f10x_hd.s 中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写, 为了方便管理我们把中断服务函数统一写在 stm32f10x_it.c 这个库文件中。

    关于中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。

    后记

    中断是非常重要的,主要掌握中断编程的4个步骤

    关于文章中提到的参考手册,还有一些官方手册,可见如下链接
    链接: STM32f10x官方手册.rar.

    展开全文
  • STM32中断控制LED灯

    千次阅读 2021-11-08 21:48:55
    文章目录 一、相关概念 1.中断概念 2.中断过程 3.中断作用 4.中断优先级 5.中断响应过程 二、 CubeMX中断控制LED灯 1.创建项目 2.代码修改 3.... 参考链接 【STM32CubeMX】HAL库中断方式UART串口通信
  • STM32中断使用注意事项/使用详解

    千次阅读 2021-12-30 10:59:35
    STM32中设置了许多中断,今天我们就来讲讲几个常用中断的使用细节及注意事项。
  • STM32中断系统

    千次阅读 多人点赞 2022-03-17 09:41:56
    文章目录中断介绍中断概念NVIC介绍常用寄存器中断配置寄存器 中断介绍 中断概念 中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回...
  • stm32 定时器3实现精确的1s延时时基,LED灯以1s间隔黄绿蓝三盏灯循环闪烁,通过Proteus仿真看效果。
  • STM32CUBE配置GPIO中断,以及中断回调函数编写 .
  • 该程序编写了STM32F103三个串口初始化程序,可快速调用,同时支持接收和发送单个字符和多个字符,并存储数据,方便接收数据后的通信协议校验,支持自定义接收数据最大长度,重写printf函数。
  • STM32F103单片机上实现ADC转换功能,用ADC1通道0采集外部波形,采用连续转换模式,中断的方式进行数据采集。
  • STM32中断代码

    2015-08-07 19:29:44
    STM32f10x中断程序,很详细的,说明很全
  • 这个资料是关于STM32中断寄存器配置的,里面非常详细,我就是以这个为主要依据学的STM32中断,非常适合刚学完51等低位单片机,想从寄存器着手学STM32的初学者。
  • 问题表现 在MCU系统负载较重、串口收发数据频率很高、多个中断存在(如同时有定时器更新中断、外部中断、DMA中断、串口接收中断)的情况下,容易出现串口溢出错误(ORE)。该错误的主要显现形式是:...在STM32中断函数
  • stm32中断和连续发送数据

    千次阅读 2021-11-08 19:59:51
    选择STM32F103C8 3.找到PA9,选择为GPIO——EXTI5中断模式 4.选择PA1设置为GPIO_Output输出模式 5.设置引脚 PA1设置high 6.设置RCC和SYS 7,设置开启中断 8.设置时钟树 9.项目命名,...
  • STM32中断的概念

    千次阅读 2020-08-07 09:09:07
    中断,个人理解即为一个突发的任务打断了正在进行的任务。 中断分为两类:1.系统中断,体现在内核。 2.外部中断,体现在外设。 NVIC(向量中断控制器),是一个内核外设,通过NVIC管理内核以及片上外设的中断。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 62,291
精华内容 24,916
关键字:

stm32中断

友情链接: ARIMA_Prediction-master.zip