• 单片机中使用内核文件关闭中断需要注意的事项!!!!!!!


      通过观察单片机程序的中断向量表,我们不难发现对于ARM架构的单片机中断向量表基本分为两部分,一部分是内部中断另一部分是外部中断

      下面是MKL25Z4的中断向量表:

      下面是STM32F429的中断向量表:

       当我们在写单片机程序的时候,经常会与中断打交道,控制中断的开和关是必经的操作,中断分外部中断和内部中断,为了能准确控制中断就需要明白当前要控制的中断是外部中断还是内部中断。开发单片机程序的都知道对于中断的控制开关,芯片厂商早已在提供的底层驱动程序中以功能函数的形式呈现给开发人员,我们只需调用即可。以MKL25Z4为例,比如如下几个函数:

    /**
      rief   Enable External Interrupt
      details 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[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
    }
    
    
    /**
      rief   Disable External Interrupt
      details 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[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
    }
    
    
    /**
      rief   Get Pending Interrupt
      details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
      param [in]      IRQn  Interrupt number.
      
    eturn             0  Interrupt status is not pending.
      
    eturn             1  Interrupt status is pending.
     */
    __STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
    {
      return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
    }
    
    
    /**
      rief   Set Pending Interrupt
      details 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[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
    }
    
    
    /**
      rief   Clear Pending Interrupt
      details 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[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
    }
    
    
    /**
      rief   Set Interrupt Priority
      details Sets the priority of an interrupt.
      
    ote    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 ((int32_t)(IRQn) < 0)
      {
        SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
           (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
      }
      else
      {
        NVIC->IP[_IP_IDX(IRQn)]  = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)]  & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
           (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
      }
    }
    
    
    /**
      rief   Get Interrupt Priority
      details 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.
      
    eturn             Interrupt Priority.
                          Value is aligned automatically to the implemented priority bits of the microcontroller.
     */
    __STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
    {
    
      if ((int32_t)(IRQn) < 0)
      {
        return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
      }
      else
      {
        return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
      }
    }

      虽然以上函数能很方便的被开发人员调用,但在调用的时候需要知道,以上函数只能用来控制单片机的外部中断,对于内部中断是不能用以上函数控制的。如下图所示,除了注释有说明外,在做标记的地方已经限定死了中断的范围为0-31。

     

     

       因此并非所有的中断都能使用驱动程序中提供的中断控制函数来控制中断,那么如果想要关闭内部中断该如何做?下面以SysTick为例:

       具体操作就是怎么打开就怎么关闭,上面只关闭了Systick定时器,控制中断关是一样的。

    #end

  • 相关阅读:
    fastjson转换包含date类型属性的对象时报错com.alibaba.fastjson.JSONException: For input string: "13:02:19"
    HTTP Status 500
    org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
    myeclipse 报错:Set project compiler compliance settings to '1.5'
    Myeclipse安装svn插件
    junit单元测试报错Failed to load ApplicationContext,但是项目发布到tomcat浏览器访问没问题
    使用mybatis时,sql查出来的结果映射不进逆向工程生成的该模型
    整合mybatis时报错:Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/tx]
    TinkerPop中的遍历:图的遍历步骤(3/3)
    TinkerPop中的遍历:图的遍历步骤(2/3)
  • 原文地址:https://www.cnblogs.com/wenhao-Web/p/13559097.html
Copyright © 2020-2023  润新知