中断库函数misc

1/中断的优先级分为抢占优先级和响应优先级,这个设置是针对所有中断的设置,共分为5种,在AIRCR寄存器的[10:8]中设置。

关于抢占和响应的区别等,网上有很多,就不罗列了。

RM手册中会有中断向量表,每个AF接口都有一个中断,比如I2C2,UART5等。一共有16个外部中断EXTI。每个端口的第X个管脚,可以映射到第X个EXTI。

其中EXTI0~EXTI4是独立的,EXTI5~EXTI9是一组,EXTI10~EXTI15是一组,所以每个端口的GPIO,比如GPIOA0~GPIOA4可以分别映射到EXTI0~EXTI4,是独立的,后面的GPIO,都是捆绑在一起的。

 void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

 

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
  /* Check the parameters */
  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); //NVIC_PriorityGroup_0~4
  
  /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; // AIRCR_VECTKEY_MASK=0x05FA,要对这个寄存器操作,必须在头上写入05FA
}

2/ void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)

 中断初始化函数

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
  uint8_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
  
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
  assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));  
  assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
    //比如选择NVIC_PriorityGroup_3,0x0400,抢占3位,响应1位
  if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
  {
    /* Compute the Corresponding IRQ Priority --------------------------------*/    
    tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08; //  tmppriority= 0x03
    tmppre = (0x4 - tmppriority); //tmppre=0x01
    tmpsub = tmpsub >> tmppriority; //tmpsub = 0x1

    tmppriority = NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;   //设置抢占优先级
    tmppriority |=  (uint8_t)(NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub); //设置响应优先级
        
    tmppriority = tmppriority << 0x04;
        
    NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority; //在IP寄存器中设置这个中断的优先级等级
    
    /* Enable the Selected IRQ Channels --------------------------------------*/
    NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);//使能
  }
  else
  {
    /* Disable the Selected IRQ Channels -------------------------------------*/
    NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] = //禁止中断
      (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
  }
}

以上函数的调用方法如下:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//分组2
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;        //响应3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //中断使能
NVIC_Init(&NVIC_InitStructure);    //调用初始化函数,把这些设置写入寄存器

 

3/void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)

中断向量表偏移地址

void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{ 
  /* Check the parameters */
  assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
  assert_param(IS_NVIC_OFFSET(Offset));  
   
  SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}

 

4/void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState)

Selects the condition for the system to enter low power mode?

void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_NVIC_LP(LowPowerMode));
  assert_param(IS_FUNCTIONAL_STATE(NewState));  
  
  if (NewState != DISABLE)
  {
    SCB->SCR |= LowPowerMode;
  }
  else
  {
    SCB->SCR &= (uint32_t)(~(uint32_t)LowPowerMode);
  }
}

5/void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)

这个是设置SysTick的频率

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
  /* Check the parameters */
  assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
  {
    SysTick->CTRL |= SysTick_CLKSource_HCLK;
  }
  else
  {
    SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
  }
}

 

posted on 2015-07-30 09:40  nasduc  阅读(1032)  评论(0编辑  收藏  举报

导航