[RISC-V MCU 应用开发] 第八十一章、CH32V103应用教程——中断嵌套

[复制链接]
 楼主| RISCVLAR 发表于 2021-3-5 13:30 | 显示全部楼层 |阅读模式
本帖最后由 RISCVLAR 于 2021-3-5 13:30 编辑

CH32V103应用教程——中断嵌套

本章教程主要在第四章EXTI基础上进行,主要进行两级中断嵌套测试实验。

1、EXTI简介及相关函数介绍
关于EXTI相关介绍,在前面章节已经进行过相关介绍,在此不再赘述。更多具体信息,可参考CH32V103应用手册。

2、硬件设计
本章教程主要进行两级中断嵌套测试,主要通过PA0、PA1引脚接地产生中断从而执行中断服务函数,连接方式如下:
  • 用杜邦线将PA0引脚与开发板GND引脚连接,产生中断之后拔下。
  • 用杜邦线将PA1引脚与开发板GND引脚连接,产生中断之后拔下。

3软件设计
本章教程主要进行两级中断嵌套测试,在前面第四章节基础上进行,具体程序如下:
exti.h文件
  1. #ifndef  __EXTI_H
  2. #define  __EXTI_H

  3. #include "ch32v10x_conf.h"

  4. void EXTI0_INT_INIT(void);

  5. #endif
exti.h文件主要进行相关定义和函数声明;
exti.c文件
  1. #include "exti.h"

  2. void EXTI0_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  3. void EXTI1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

  4. void EXTI0_INT_INIT(void)
  5. {
  6.   GPIO_InitTypeDef  GPIO_InitStructure;
  7.   EXTI_InitTypeDef EXTI_InitStructure;
  8.   NVIC_InitTypeDef NVIC_InitStructure;

  9.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA,ENABLE); //使能复用功能时钟和GPIOA时钟

  10.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;       //配置GPIO引脚
  11.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;              //配置GPIO上拉输入模式
  12.   GPIO_Init(GPIOA, &GPIO_InitStructure);                     //初始化GPIOA

  13.    /* GPIOA ----> EXTI_Line0 */
  14.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); //指定中断/事件线的输入源,实际上是设定外部中断配置寄存器AFIO_EXTICRx的值,此处为PA0
  15.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);
  16.   EXTI_InitStructure.EXTI_Line=EXTI_Line0|EXTI_Line1;        //EXTI中断/事件线选择,此处选择EXTI_Line0
  17.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        //EXTI模式选择,此处选择为产生中断模式
  18.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;    //EXTI边沿触发事件,此处选择为下降沿触发
  19.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;                  //使能EXTI线
  20.   EXTI_Init(&EXTI_InitStructure);

  21.   NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;           //使能EXTI0中断通道
  22.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //设置抢占优先级为1
  23.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;         //设置子优先级为1
  24.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //使能外部中断通道
  25.   NVIC_Init(&NVIC_InitStructure);                            //中断优先级分组初始化

  26.   NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;           //使能EXTI0中断通道
  27.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //设置抢占优先级为2
  28.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;         //设置子优先级为1
  29.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //使能外部中断通道
  30.   NVIC_Init(&NVIC_InitStructure);
  31. }

  32. void EXTI0_IRQHandler(void)
  33. {
  34.   if(EXTI_GetITStatus(EXTI_Line0)==SET)  //EXTI_GetITStatus用来获取中断标志位状态,如果EXTI线产生中断则返回SET,否则返回RESET
  35.   {
  36.     int i;
  37.     Delay_Ms(1000);
  38.     printf("Run at EXTI0\r\n");
  39.     for(i=0;i<100;i++)
  40.     {
  41.         printf("%d\n",i);
  42.         Delay_Ms(1000);
  43.     }
  44.     EXTI_ClearITPendingBit(EXTI_Line0);  //清除中断标志位
  45.   }
  46. }

  47. void EXTI1_IRQHandler(void)
  48. {
  49.   int i;
  50.   if(EXTI_GetITStatus(EXTI_Line1)==SET)  //EXTI_GetITStatus用来获取中断标志位状态,如果EXTI线产生中断则返回SET,否则返回RESET
  51.   {
  52.     Delay_Ms(1000);
  53.     printf("Run at EXTI1\r\n");
  54.     for(i=100;i<1000;i++)
  55.     {
  56.         printf("%d\n",i);
  57.         Delay_Ms(1000);
  58.     }
  59.     EXTI_ClearITPendingBit(EXTI_Line1);  //清除中断标志位
  60.   }
  61. }
exti.c文件与第四章exti.c文件类似,在此不再做具体介绍。
main.c文件
  1. /********************************** (C) COPYRIGHT *******************************
  2. * File Name          : main.c
  3. * Author             : WCH
  4. * Version            : V1.0.0
  5. * Date               : 2020/10/22
  6. * Description        : Main program body.
  7. *******************************************************************************/
  8. #include "debug.h"
  9. #include "exti.h"

  10. /*******************************************************************************
  11. * Function Name  : main
  12. * Description    : Main program.
  13. * Input          : None
  14. * Return         : None
  15. *******************************************************************************/
  16. int main(void)
  17. {
  18.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  19.     Delay_Init();
  20.     USART_Printf_Init(115200);
  21.    
  22.     printf("SystemClk:%d\r\n",SystemCoreClock);
  23.     printf("EXTI0 Test\r\n");
  24.    
  25.     EXTI0_INT_INIT();
  26.     while(1)
  27.     {
  28.      Delay_Ms(1000);
  29.      printf("Run at main\r\n");
  30.     }
  31. }
main.c文件主要进行函数初始化。

4下载验证
将编译好的程序下载到开发板并复位,打开串口调试助手,将PA0、PA1接地,可以看到EXTI0可以打断EXTI1的中断,而EXTI1不能打断EXTI0的中断,串口打印如下:
图片1.png

80、中断嵌套.rar

472.52 KB, 下载次数: 256

jerow 发表于 2021-3-11 19:53 | 显示全部楼层
说实话虽然中断嵌套可以用但是一般人都不会中断嵌套的,大家都是根据它的优先级来调整
gejigeji521 发表于 2021-3-13 15:34 | 显示全部楼层
还没尝试过这种。
jcky001 发表于 2021-3-16 14:32 | 显示全部楼层
坐沙发的说的很有道理哟
wwppd 发表于 2021-4-6 20:18 | 显示全部楼层
            
杨寅辉 发表于 2021-4-18 19:13 | 显示全部楼层
CH32V103支持几级的中断嵌套的呢?一般不会对他进行特别的配置,把显示或者定时器放到最高就好了。

评论

支持两级中断嵌套  发表于 2021-4-19 13:34
两只袜子 发表于 2021-4-19 09:41 | 显示全部楼层
感谢分享,学习一下
onlycook 发表于 2021-5-12 14:50 | 显示全部楼层
相当新鲜的教程
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

296

帖子

45

粉丝
快速回复 在线客服 返回列表 返回顶部

133

主题

296

帖子

45

粉丝
快速回复 在线客服 返回列表 返回顶部