码迷,mamicode.com
首页 > 其他好文 > 详细

STM32 之 NVIC(中断向量、优先级) 简述

时间:2016-09-10 19:09:32      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

一、背景
        需要使用STM32的CAN进行通信,经过一系列配置后,已可正常收发,还剩下一个CAN通信的错误处理。可错
    误中断使能寄存器已经配置使能了,出错后就是无法进入"CAN1_SCE_IRQHandler"中断。(让CAN通信出错的的
    办法很简单,将"CAN_H""CAN_L"直接短接,然后让其发送数据,正常情况下,就会触发错误中断了,发送错
    误寄存器会瞬间加至"128",如果继续发,每发一次,发送错误计数器会+8,直到256,然后CAN节点即会进入离
    线状态了,也就是"Bus off"状态)。
        一步一步查,才发现,"CAN1_SCE_IRQn"的M3内核中断没有开,也就是NVIC相关配置。对于NVIC还真没太明
    白,幸好有老司机左栋——虽然他还是对这个称谓是拒绝的:)——跟左栋学了很多,非常感谢。

二、正文
        对于NVIC(Nested Vectored Interrupt Controller),中文一般翻译为嵌套向量中断控制器,
   其为M3内核层次概念,相关寄存器配置需要使用到Cotex
-M3数据手册,ST的用户手册涉及的较少,还好有ST的库
   函数,此次则暂不深究NVIC,仅对NVIC的概念以及其相对应的库函数使用做个简述。 STM32是基于Cotex
-M3内核的MCU,Cotex-M3有两个优先级概念: --->抢占优先级(主优先级) --->响应优先级(次优先级) 其实际的层次概念如下图:

技术分享

        如图所示,抢占优先级高的任务出现后,会打断抢占优先级低的任务,即所谓的中断嵌套。例如:
    --->抢占优先级为N的中断任务正在运行,此时,抢占优先级为2的中断产生,则MCU会将抢断优先级为N的任务
        中断,先响应执行中断优先级为2的任务,待该任务完成后,再来完成抢占优先级为N的任务。
    --->若是抢占优先级为2的中断正在运行,又有新的抢占优先级为2的中断产生,则新产生的中断会等待当前中
        任务完成后,再执行新产生的中断。
    --->若是抢占优先级,次优先级均相同的中断同时产生,则根据该中断在中断向量表的顺序来执行中断任务。
        
        以上的任务全是由Cotex-M3内核的NVIC(中断控制器)来完成。在中断控制器中,Cotex-M3定义了1个字节
    (8位)的寄存器来定义抢占优先级和响应优先级。具体定义如下:
    --->最高1位用于指定抢占式优先级,最低7位用于指定响应优先级
    --->最高2位用于指定抢占式优先级,最低6位用于指定响应优先级
    --->最高3位用于指定抢占式优先级,最低5位用于指定响应优先级
    --->最高4位用于指定抢占式优先级,最低4位用于指定响应优先级
    --->最高5位用于指定抢占式优先级,最低3位用于指定响应优先级
    --->最高6位用于指定抢占式优先级,最低2位用于指定响应优先级
    --->最高7位用于指定抢占式优先级,最低1位用于指定响应优先级
        这么一大串,开始我也很懵逼,经过左栋老司机指点后,才弄明白。
        之前已经说明,此寄存器一共有8位,若最高1位用于指定抢占式优先级,最低7位用于指定响应优先级,代
    表的意思就是,抢占优先级只有2^1=2个,每个抢占优先级对应的指定相应优先级有2^7 = 128 个。其他的则以
    此类推。
        STM32则没有全部使用8位,而只使用了4位,所以其定义了5种优先级分组,具体如下:
    --->#define NVIC_PriorityGroup_0         ((uint32_t)0x700) 
        /* 0 bits for pre-emption priority
         * 4 bits for subpriority */
        // 有2^0 = 1 个抢占优先级, 2^4 = 16个响应优先级                                           
    --->#define NVIC_PriorityGroup_1         ((uint32_t)0x600) 
        /* 1 bits for pre-emption priority
         * 3 bits for subpriority */
        // 有2^1 = 2 个抢占优先级, 2^3 = 8 个响应优先级                                           
    --->#define NVIC_PriorityGroup_2         ((uint32_t)0x500)
        /* 2 bits for pre-emption priority
         * 2 bits for subpriority */
        // 有2^2 = 4 个抢占优先级, 2^2 = 4 个响应优先级                                           
    --->#define NVIC_PriorityGroup_3         ((uint32_t)0x400)
        /* 3 bits for pre-emption priority
         * 1 bits for subpriority */
        // 有2^3 = 8 个抢占优先级, 2^1 = 2 个响应优先级                                           
    --->#define NVIC_PriorityGroup_4         ((uint32_t)0x300)
        /* 4 bits for pre-emption priority
         * 0 bits for subpriority */
        // 有2^4 = 16个抢占优先级, 2^0 = 1 个响应优先级                                           

        首先ST提供了库函数"void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)"来设置抢占优先
    级以及响应优先级组类型,参数"NVIC_PriorityGroup"既是上面提及的5个宏定义。
        ST同时提供了库函数"void NVIC_Init(NVIC_InitTypeDef*NVIC_InitStruct)",该库函数会根据结构体
    "NVIC_InitStruct"内的内容完成NVIC的配置,其具体定义如下:
    typedef struct
    {
        // 定义哪个中断(譬如有"USART1_IRQn","USB_LP_CAN1_RX0_IRQn"等等)
        uint8_t NVIC_IRQChannel;                    
        // 该中断的抢占优先级是多少
        uint8_t NVIC_IRQChannelPreemptionPriority;  
        // 该中断的响应优先级是多少
        uint8_t NVIC_IRQChannelSubPriority;        
        // 该值代表是否生效该设置(ENABLE, DISABLE)
        FunctionalState NVIC_IRQChannelCmd;        
    } NVIC_InitTypeDef;

    至此,记录完毕

记录时间:2016年9月10日
记录地点:深圳WZ

 

STM32 之 NVIC(中断向量、优先级) 简述

标签:

原文地址:http://www.cnblogs.com/ChYQ/p/5859974.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!