外部中断初始化函数分析

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值