本帖最后由 RISCVLAR 于 2021-3-5 13:30 编辑
CH32V103应用教程——中断嵌套
本章教程主要在第四章EXTI基础上进行,主要进行两级中断嵌套测试实验。
1、EXTI简介及相关函数介绍 关于EXTI相关介绍,在前面章节已经进行过相关介绍,在此不再赘述。更多具体信息,可参考CH32V103应用手册。
2、硬件设计 本章教程主要进行两级中断嵌套测试,主要通过PA0、PA1引脚接地产生中断从而执行中断服务函数,连接方式如下: - 用杜邦线将PA0引脚与开发板GND引脚连接,产生中断之后拔下。
- 用杜邦线将PA1引脚与开发板GND引脚连接,产生中断之后拔下。
3、软件设计 本章教程主要进行两级中断嵌套测试,在前面第四章节基础上进行,具体程序如下: exti.h文件 #ifndef __EXTI_H
#define __EXTI_H
#include "ch32v10x_conf.h"
void EXTI0_INT_INIT(void);
#endif
exti.h文件主要进行相关定义和函数声明; exti.c文件 #include "exti.h"
void EXTI0_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void EXTI1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void EXTI0_INT_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA,ENABLE); //使能复用功能时钟和GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //配置GPIO引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //配置GPIO上拉输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA
/* GPIOA ----> EXTI_Line0 */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); //指定中断/事件线的输入源,实际上是设定外部中断配置寄存器AFIO_EXTICRx的值,此处为PA0
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);
EXTI_InitStructure.EXTI_Line=EXTI_Line0|EXTI_Line1; //EXTI中断/事件线选择,此处选择EXTI_Line0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //EXTI模式选择,此处选择为产生中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //EXTI边沿触发事件,此处选择为下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能EXTI线
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能EXTI0中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //设置抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //设置子优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //中断优先级分组初始化
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //使能EXTI0中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //设置抢占优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //设置子优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
}
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)==SET) //EXTI_GetITStatus用来获取中断标志位状态,如果EXTI线产生中断则返回SET,否则返回RESET
{
int i;
Delay_Ms(1000);
printf("Run at EXTI0\r\n");
for(i=0;i<100;i++)
{
printf("%d\n",i);
Delay_Ms(1000);
}
EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位
}
}
void EXTI1_IRQHandler(void)
{
int i;
if(EXTI_GetITStatus(EXTI_Line1)==SET) //EXTI_GetITStatus用来获取中断标志位状态,如果EXTI线产生中断则返回SET,否则返回RESET
{
Delay_Ms(1000);
printf("Run at EXTI1\r\n");
for(i=100;i<1000;i++)
{
printf("%d\n",i);
Delay_Ms(1000);
}
EXTI_ClearITPendingBit(EXTI_Line1); //清除中断标志位
}
}
exti.c文件与第四章exti.c文件类似,在此不再做具体介绍。 main.c文件 /********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.0.0
* Date : 2020/10/22
* Description : Main program body.
*******************************************************************************/
#include "debug.h"
#include "exti.h"
/*******************************************************************************
* Function Name : main
* Description : Main program.
* Input : None
* Return : None
*******************************************************************************/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n",SystemCoreClock);
printf("EXTI0 Test\r\n");
EXTI0_INT_INIT();
while(1)
{
Delay_Ms(1000);
printf("Run at main\r\n");
}
}
main.c文件主要进行函数初始化。
4、下载验证 将编译好的程序下载到开发板并复位,打开串口调试助手,将PA0、PA1接地,可以看到EXTI0可以打断EXTI1的中断,而EXTI1不能打断EXTI0的中断,串口打印如下:
|