中断库函数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; } }