本帖最后由 chengxuan104 于 2014-11-20 09:46 编辑 最近在学习stm32f2的中断,有点不明白nvic和exti这两个的区别,清中断挂起这两个都可以做, EXTI_ClearFlag函数和EXTI_ClearITPendingBit,这两个函数操作的寄存器是一样的,只贴一个 void EXTI_ClearITPendingBit(uint32_t EXTI_Line) { /* Check the parameters */ assert_param(IS_EXTI_LINE(EXTI_Line)); EXTI->PR = EXTI_Line; }复制代码 但是,为什么nvic也可以呢很奇怪,以下代码是在core_cm3.h里面的 /** \brief Get Pending Interrupt This function reads the pending register in the NVIC and returns the pending bit for the specified interrupt. \param [in] IRQn Number of the interrupt for get pending \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[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ }复制代码
我的理解,不一定正确:
NVIC是核内资源,CMSIS提供了几个参考API,具体功能的实现,依赖厂商。毕竟STM32对中断进行了改造。
而EXTI则是由STM32提供的具体中断操作。
所以结论是:请无视CMSIS中的API,直接使用STM32库中的EXTI寄存器才是正道。
我将的试验中的两张图你比较一下看:
注意ISPR及PR的值,一个变化了,另一个全是0。
至于EXTI_ClearFlag函数和EXTI_ClearITPendingBit,我看效果是一样的。
初步看了一下,static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)这个函数涉及到了NVIC->ISPR[x]这个寄存器。指向的寄存器地址是:0xE000E200+(ISPR[x]的x的偏移)。
可以看一下官方的Cortex-M3手册,从中找到线索。
---------------------------------------------------------------------------------------------
typedef struct
{
__IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[24];
__IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[24];
__IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[24];
__IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[24];
__IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
uint32_t RESERVED4[56];
__IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
uint32_t RESERVED5[644];
__O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
} NVIC_Type;
------------------------------------------------------------------------------------------------------------------
正常来看,读取操作不会对挂起的中断产生影响。这些寄存器写操作才会起作用。
我这边没有STM32F2xx的芯片,也没办法进一步的验证。
楼上几位来帮忙看了哦,是否弄明白了呢