zoukankan      html  css  js  c++  java
  • STM32F407 NVIC 中断优先级管理 个人笔记

    内嵌向量中断控制器:Nested Vectored Interrupt Controller (NVIC)
    设置中断向量的优先级并使能。

    响应优先级& 抢占优先级

    抢占优先级:一个中断A还在处理时,另一个中断B发生,B能否先处理? 答:如果B抢占优先级高就行。
    响应优先级:抢占优先级相同时,中断A和中断B同时发生时,先处理哪个? 答:响应优先级高的哪个。
    而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。

    中断优先级组

    是指在寄存器SCB->AIRCR中,配置:
    4个位当中,几位是抢占优先级,几位是响应优先级

    注意:设置好后不要再改了!以免造成混乱

    相关库函数

    NVIC相关的库函数在FWLIB的misc.c中

    中断优先级分组函数

    (一般只调用一次!)
    void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
    例如:
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    中断初始化函数

    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_InitTypeDef 结构体中间有三个成员变量,这三个成员变量的作用是:

    NVIC_IRQChannel:定义初始化的是哪个中断,这个我们可以在 stm32f4xx.h 中定义的枚举类 型 IRQn
    的成员变量中可以找到每个中断对应的名字。例如串口 1 对应 USART1_IRQn。
    NVIC_IRQChannelPreemptionPriority:定义这个中断的抢占优先级别。
    NVIC_IRQChannelSubPriority:定义这个中断的响应优先级别。
    NVIC_IRQChannelCmd:该中断通道是否使能。

    比如我们要使能串口 1 的中断,同时设置抢占优先级为 1,响应优先级位 2,初始化的方法是:

    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 寄存器
    

    编程步骤

    最简单的应用中,只要

    1. 设置分组
    2. 外设中断使能(函数名在外设的头文件中有)
    3. 初始化
    4. 写中断服务函数(函数名在setup巴拉巴拉中定义)
      即可:
    //1.
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //可能在主函数
    //2.
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);             //可能在初始化函数中
    //3.
    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 寄存器
    //4.中断服务函数
    void USART1_IRQHandler(void)
    {
    }
    

    上面是一些常用的东西,下面是其他一些有的没的

    支持的中断数量

    • CM4内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
    • STM32F4并没有使用CM4内核的全部东西,而是只用了它的一部分。
      STM32F40xx/STM32F41xx总共有92个中断。
      STM32F42xx/STM32F43xx则总共有96个中断
    • STM32F40xx/STM32F41xx的92个中断里面,包括10个内核中断和82个可屏蔽中断,具有16级可编程的中断优先级,而我们常用的就是这82个可屏蔽中断。

    中断设置相关的寄存器

    __IO uint8_t  IP[240]; //中断优先级控制的寄存器组
    
    __IO uint32_t ISER[8]; //中断使能寄存器组
    
    __IO uint32_t ICER[8]; //中断失能寄存器组
    
    __IO uint32_t ISPR[8]; //中断挂起寄存器组
    
    __IO uint32_t ICPR[8]; //中断解挂寄存器组
    
    __IO uint32_t IABR[8]; //中断激活标志位寄存器组
    

    中断优先级控制寄存器组:IP[240]

    Interrupt Priority Registers
    240个8位寄存器
    void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
    例如:NVIC_Init(&NVIC_InitStructure);

    中断使能寄存器组:ISER[8]

    8个32位寄存器(CM4内核支持256个中断)
    每个位控制一个中断的使能
    STM32F40x只有82个可屏蔽中断,所以只使用了其中的ISER[0]~ISER[2]。

    ISER[0]的bit031分别对应中断0-31
    ISER[1]的bit0-27对应中断32-63;
    ISER[2]的bit0-17对应中断64~81;

  • 相关阅读:
    2018.09.08什么是ajax
    2018.09.03怎样让网页自适应所有屏幕宽度
    2018.08.25字符串和二维数组之间的转换
    2018.08.20MySQL常用命令总结(二)
    2018.08.15解决MySQL1290问题
    2018.08.13MySQL常用命令总结(一)
    2018.08.11MySQL无法启动错误码1067的解决方法
    2018.08.10 css中position定位问题
    2018.08.10jQuery导航栏置顶
    2018.08.07css实现图片放大
  • 原文地址:https://www.cnblogs.com/YuQiao0303/p/10021419.html
Copyright © 2011-2022 走看看