打印
[RISC-V MCU 应用开发]

CH32X035的2级中断嵌套

[复制链接]
44|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qjixf|  楼主 | 2025-1-17 17:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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));
    }
}



使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

10

帖子

0

粉丝