打印
[牛人杂谈]

M051的嵌套向量中断控制器 (NVIC)

[复制链接]
1618|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huangcunxiake|  楼主 | 2016-8-29 19:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Cortex-M0提供中断控制器,作为异常模式的组成部分,称之为“嵌套向量中断控制器(NVIC)”。 它与处 理器内核紧密联系,并具有以下特性:  
  • 支持嵌套和向量中断
  • 自动保存和恢复处理器状态 „
  • 可动态改变优先级 „
  • 简化的精确的中断延迟  


NVIC对所有支持的异常按优先级排序并处理,所有异常在“处理模式“处理. NVIC结构支持具有四级优先 级的32个(IRQ[31:0])离散中断。 所有的中断和大多数系统异常可以配置为不同优先级。当中断发生 时,NVIC将比较新中断与当前中断的优先级,如果新中断优先级高于当前中断,则新中断将代替当前 中断被处理。

NVIC对所有支持的异常按优先级排序并处理,所有异常在“处理模式“处理. NVIC结构支持具有四级优先 级的32个(IRQ[31:0])离散中断。 所有的中断和大多数系统异常可以配置为不同优先级。当中断发生 时,NVIC将比较新中断与当前中断的优先级,如果新中断优先级高于当前中断,则新中断将代替当前 中断被处理。

软件可以对其中一些异常以及所有中断设置4级优 先级。高用户可配置优先级记为“0”,低优先级记为“3”,所有用户可配置的优先级的默认值为“0”。 注意:优先级为“0”在整个系统中为第4优先级,排在“Reset”, “NMI” 与“Hard Fault”之后。


沙发
huangcunxiake|  楼主 | 2016-8-29 19:49 | 只看该作者
大家会问,这些东西在哪儿呢,库函数吗,这不是外设啊
对了,这不是外设,这个是CPU的功能。
CPU管理中断的功能,因此函数肯定是在CPU内核的头文件里
这里就是

core_cm0.h
部分代码如下

/** \brief  Enable External Interrupt

    The function enables a device-specific interrupt in the NVIC interrupt controller.

    \param [in]      IRQn  External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
  NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}


/** \brief  Disable External Interrupt

    The function disables a device-specific interrupt in the NVIC interrupt controller.

    \param [in]      IRQn  External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
  NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}


/** \brief  Get Pending Interrupt

    The function reads the pending register in the NVIC and returns the pending bit
    for the specified interrupt.

    \param [in]      IRQn  Interrupt number.

    \return             0  Interrupt status is not pending.
    \return             1  Interrupt status is pending.
*/
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
  return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}


/** \brief  Set Pending Interrupt

    The function sets the pending bit of an external interrupt.

    \param [in]      IRQn  Interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
  NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}


/** \brief  Clear Pending Interrupt

    The function clears the pending bit of an external interrupt.

    \param [in]      IRQn  External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
  NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}


/** \brief  Set Interrupt Priority

    The function sets the priority of an interrupt.

    \note The priority cannot be set for every core interrupt.

    \param [in]      IRQn  Interrupt number.
    \param [in]  priority  Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
  if(IRQn < 0) {
    SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
  else {
    NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
        (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}


/** \brief  Get Interrupt Priority

    The function reads the priority of an interrupt. The interrupt
    number can be positive to specify an external (device specific)
    interrupt, or negative to specify an internal (core) interrupt.


    \param [in]   IRQn  Interrupt number.
    \return             Interrupt Priority. Value is aligned automatically to the implemented
                        priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{

  if(IRQn < 0) {
    return((uint32_t)((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for Cortex-M0 system interrupts */
  else {
    return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS)));  } /* get priority for device specific interrupts  */
}


/** \brief  System Reset

    The function initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void NVIC_SystemReset(void)
{
  __DSB();                                                     /* Ensure all outstanding memory accesses included
                                                                  buffered write are completed before reset */
  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |
                 SCB_AIRCR_SYSRESETREQ_Msk);
  __DSB();                                                     /* Ensure completion of memory access */
  while(1);                                                    /* wait until reset */
}



使用特权

评论回复
板凳
dongnanxibei| | 2016-8-29 20:19 | 只看该作者
以前还真不知道是在这里,从来没有搞过这个嵌套,都是默认来的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

204

主题

3476

帖子

10

粉丝