void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
{
uint32_t tmp = 0;
/* Check the parameters */
assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode));
assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger));
assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line));
assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd));
tmp = (uint32_t)EXTI_BASE;
if (EXTI_InitStruct->EXTI_LineCmd != DISABLE)
{
/* Clear EXTI line configuration */
EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line;
EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line;
tmp += EXTI_InitStruct->EXTI_Mode;
*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
/* Clear Rising Falling edge configuration */
EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line;
EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line;
/* Select the trigger for the selected external interrupts */
if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling)
{
/* Rising Falling edge */
EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;
EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;
}
else
{
tmp = (uint32_t)EXTI_BASE;
tmp += EXTI_InitStruct->EXTI_Trigger;
*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
}
}
else
{
tmp += EXTI_InitStruct->EXTI_Mode;
/* Disable the selected external lines */
*(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line;
}
}
如果没记错的话,笔者好像写过关于EXTI的文章,应该也分析过这个,不过年事高了容易忘,而且每次看应该感悟不同,分析的思路也不同,所以再写写换个脑子也可以。
如上,是外部中断/事件初始化的代码。
要理解这个代码首先得知道要初始化一个外部中断/事件,其实是在对外部中断/事件这个外设的对应寄存器的设置。那么首先介绍的肯定是这个外设对应的寄存器。
这个图截自《stm32f10x-中文参考手册》的目录,因为这样比较明显的看的出来EXTI这个外设有哪些寄存器。一目了然,6个。不一一打字,看代码里面如何定义的(stm32f10x.h文件中):
/**
* @brief External Interrupt/Event Controller
*/
typedef struct
{
__IO uint32_t IMR;
__IO uint32_t EMR;
__IO uint32_t RTSR;
__IO uint32_t FTSR;
__IO uint32_t SWIER;
__IO uint32_t PR;
} EXTI_TypeDef;
#define EXTI ((EXTI_TypeDef *) EXTI_BASE)
#define EXTI_BASE (APB2PERIPH_BASE + 0x0400)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
/*!< Peripheral base address in the alias region */
#define PERIPH_BASE ((uint32_t)0x40000000)
笔者将外设基地址,APB2基地址,EXTI基地址和EXTI地址都列出来,相信读者会更清晰的知道代码在阐释一个外设的时候是怎么来做的。其实就是一个地址的操作,定义成那样一个结构,是因为在寄存器都是按32bit,也就是4字节间隔的地址来映射的。uint32_t就是四字节,那么在数据结构中,IMR EMR RTSR FTSR