CH32V307支持8级中断嵌套和3级硬件压栈,参考EVT中断嵌套例子,测试一下CH32X035的2级中断嵌套和2级硬件压栈,比较简单。
#include "debug.h"
/* Global define */
/* Global Variable */
//nesting level 2,hardware stack push saves 2 lover level ints(lewer level has higher priority),high level ints use software stack push
//ch32x035支持2级中断嵌套2级硬件压栈,2级高优先级硬件压栈后低优先级中断只能软件压栈,通过__attribute__((interrupt("WCH-Interrupt-fast")));来指定硬件压栈,通过__attribute__((interrupt()));指定软件压栈
void SW_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); //hardware push stack
void WWDG_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void PVD_IRQHandler(void) __attribute__((interrupt(/*"WCH-Interrupt-fast"*/))); //soft push stack
void FLASH_IRQHandler(void) __attribute__((interrupt(/*"WCH-Interrupt-fast"*/)));
void EXTI7_0_IRQHandler(void) __attribute__((interrupt(/*"WCH-Interrupt-fast"*/)));
void AWU_IRQHandler(void) __attribute__((interrupt(/*"WCH-Interrupt-fast"*/)));
/*********************************************************************
* @fn Interrupt_Init
*
* @brief Initializes interruption.
*
* @return none
*/
void Interrupt_Init(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //允许2级中断嵌套
NVIC_InitTypeDef NVIC_InitStructure = {0};
//可抢占中断
NVIC_InitStructure.NVIC_IRQChannel = Software_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占位优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0-3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占位优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级0-3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占位优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级0-3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//无抢占中断
NVIC_InitStructure.NVIC_IRQChannel = FLASH_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占位优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0-3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI7_0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占位优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级0-3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = AWU_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占位优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级0-3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*********************************************************************/
// ####_IRQHandler
/*PFIC -> GISR:
9 GPENDSTA RO 当前是否有中断处于挂起:1:有; 0:没有。
8 GACTSTA RO 当前是否有中断被执行: 1:有; 0:没有。
[7:0] NESTSTA[7:0] RO 当前中断嵌套状态,目前最大支持 2 级嵌套,硬件压栈深度最大为 2 级。
0x03:第 2 级中断中;
0x01:第 1 级中断中;
0x00:没有中断发生;
其他:不可能情况。
*/
uint8_t step=0;
void SW_Handler(void)
{
step++;
printf(" 0.0 SW_IRQHandler");
printf(" step:%d\r\n",step);
// NVIC_SetPendingIRQ(WWDG_IRQn);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
printf("GISR:%08x\r\n",PFIC->GISR);
printf("Quit SW_IRQHandler\n");
}
void WWDG_IRQHandler(void)
{
step++;
printf(" 0.2 WWDG_IRQHandler");
printf(" step:%d\r\n",step);
NVIC_SetPendingIRQ(Software_IRQn);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
printf("GISR:%08x\r\n",PFIC->GISR);
printf("Quit WWDG WWDG_IRQHandler\n");
}
void PVD_IRQHandler(void)
{
step++;
printf(" 0.3 PVD_IRQHandler");
printf(" step:%d\r\n",step);
NVIC_SetPendingIRQ(WWDG_IRQn);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
printf("GISR:%08x\r\n",PFIC->GISR);
printf("Quit PVD_IRQHandler\n");
}
void FLASH_IRQHandler(void)
{
step++;
printf(" 1.0 FLASH_IRQHandler");
printf(" step:%d\r\n",step);
NVIC_SetPendingIRQ(PVD_IRQn);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
printf("GISR:%08x\r\n",PFIC->GISR);
printf("Quit FLASH_IRQHandler\n");
}
void EXTI7_0_IRQHandler(void)
{
step++;
printf(" 1.1 EXTI7_0_IRQHandler");
printf(" step:%d\r\n",step);
NVIC_SetPendingIRQ(FLASH_IRQn);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
printf("GISR:%08x\r\n",PFIC->GISR);
printf("Quit EXTI7_0_IRQHandler\n");
}
void AWU_IRQHandler(void)
{
step++;
printf(" 1.3 AWU_IRQHandler");
printf(" step:%d\r\n",step);
NVIC_SetPendingIRQ(EXTI7_0_IRQn);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
printf("GISR:%08x\r\n",PFIC->GISR);
printf("Quit AWU_IRQHandler\n");
}
/*******************************************************************/
/*
*@Note
*GPIO routine:
*PA4 push-pull output.
*
***Only PA0--PA15 and PC16--PC17 support input pull-down.
*/
/*********************************************************************
* @fn GPIO_Toggle_INIT
*
* @brief Initializes GPIOA.0
*
* @return none
*/
void GPIO_Toggle_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*********************************************************************
* @fn main
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
u8 i = 0;
SystemCoreClockUpdate();
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n", SystemCoreClock);
printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
GPIO_Toggle_INIT();
printf("Interrupt Nest Test\r\n");
Interrupt_Init();
printf("GISR:%08x\r\n",PFIC->GISR);
printf("Enter lowest interrupt\r\n");
NVIC_SetPendingIRQ(AWU_IRQn);
printf("Quit lower interrupt\r\n");
printf("Quit step:%d\r\n",step);
while(1)
{
Delay_Ms(500);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
}
}
|