查看: 827|回复: 0

CH32V103应用教程——EXTI

[复制链接]

41

主题

168

帖子

3215

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3215
发表于 2021-11-27 11:32:36 | 显示全部楼层 |阅读模式
本帖最后由 zly188 于 2021-11-27 11:34 编辑

本章教程通过PA14引脚(KEY1)输入信号产生中断控制运营中断服务函数,并将程序运行状态通过串口调试助手打印显示,具体如下:
当无中断产生,串口调试助手打印显示:Run at main;
当有中断产生,串口调试助手打印显示:Run at EXTI。

1、EXTI简介及相关函数介绍
EXTI(External interrupt/event controller)—外部中断/事件控制器,可分为产生中断和产生事件两大功能。每个中断/事件线都对应一个边沿检测器,可实现输入信号的上升沿检测和下降沿检测。EXTI可对每个中断/事件线进行单独配置,可单独配置为中断或者事件,以及相应触发事件的属性。

EXTI可分为产生中断和产生事件两大功能。产生中断线路目的是把输入信号输入到NVIC,从而执行中断服务函数,实现相应功能,属于软件级;产生事件线路目的是传输脉冲信号给对应外设使用,为电路级别信号传输,属于硬件级。

CH32V103外部中断的触发源既可以是软件中断(SWIEVR),也可以是外部中断通道。当触发源为外部中断通道时,其输入信号会经过边沿检测电路进行筛选。只要软件中断和外部中断二者信号产生一个,即可通过或门电路并输出给事件使能和中断使能两个与门电路,只要有中断被使能或者事件被使能,就会产生中断或者事件。关于CH32V103 EXTI具体说明,可参考CH32V103应用手册。

外部中断库函数初始化结构体及相关声明定义在ch32v10x_exti.h文件中,初始化库函数定义在ch32v10x_exti.c文件中,进行外部中断程序编程需结合上述两个文件使用,其主要内容介绍如下:
  1. void EXTI_DeInit(void);
  2. void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
  3. void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
  4. void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
  5. FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
  6. void EXTI_ClearFlag(uint32_t EXTI_Line);
  7. ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
  8. void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
复制代码
1.1、void EXTI_DeInit(void)
功  能:将EXTI外围寄存器初始化为其默认重置值。
输  入:无。

1.2、void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
功  能:根据EXTI_InitStruct中指定的参数初始化EXTI外围设备。
输  入:EXTI_InitStruct:指向EXTI_InitTypeDef结构的指针。

1.3、void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct)
功  能:用重置值填充每个EXTI_InitStruct成员。
输  入:EXTI_InitStruct:指向EXTI_InitTypeDef结构的指针。

1.4、void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
功  能:生成软件中断。
输  入:EXTI_Line:指定要启用或禁用的EXTI行。

1.5、FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
功  能:检查是否设置了指定的EXTI行标志。
输  入:EXTI_Line:指定要启用或禁用的EXTI行。

1.6、void EXTI_ClearFlag(uint32_t EXTI_Line)
功  能:清除EXTI的行挂起标志。
输  入:EXTI_Line:指定要启用或禁用的EXTI行。

1.7、ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
功  能:检查指定的EXTI行是否被断言。
输  入:EXTI_Line:指定要启用或禁用的EXTI行。

1.8、ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)
功  能:清除EXTI的行挂起位
输  入:EXTI_Line:指定要启用或禁用的EXTI行。

在进行外部中断程序编写时,若需用到上述函数,直接在程序中进行调用即可。

2、硬件设计
本教程通过PA14引脚接地产生中断从而执行中断服务函数,PA14已经连接一个按键KEY1,按下为接地。

3、软件设计
外部中断使用步骤通常如下:
  • 配置GPIO操作;
  • 配置对应的外部中断通道的中断使能位;
  • 配置触发沿,选择相应触发方式;
  • 在内核NVIC中配置EXTI中断,以保证其可以正确响应

根据上述步骤,编写相关程序,具体如下:

外部中断初始化,并设置中断。
  1. /*******************************************************************************
  2. * 函数名  : EXTI0_INT_INIT
  3. * 描述    : EXTI初始化.
  4. * 输入    : None
  5. * 返回    : None
  6. *******************************************************************************/
  7. void EXTI0_INT_INIT(void)
  8. {
  9.   GPIO_InitTypeDef GPIO_InitStructure;
  10.   EXTI_InitTypeDef EXTI_InitStructure;
  11.   NVIC_InitTypeDef NVIC_InitStructure;

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

  13.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;                  //配置GPIO引脚
  14.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;              //配置GPIO上拉输入模式
  15.   GPIO_Init(GPIOA, &GPIO_InitStructure);                     //初始化GPIOA

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

  23.   NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;           //使能EXTI0中断通道
  24.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //设置抢占优先级为1
  25.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;         //设置子优先级为2
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //使能外部中断通道
  27.   NVIC_Init(&NVIC_InitStructure);                            //中断优先级分组初始化
  28. }
复制代码

中断响应函数:
  1. /*******************************************************************************
  2. * 函数名  : EXTI15_10_IRQHandler
  3. * 描述    : 中断函数.
  4. * 输入    : None
  5. * 返回    : None
  6. *******************************************************************************/
  7. extern "C"{
  8. void EXTI15_10_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  9. void EXTI15_10_IRQHandler(void)
  10. {
  11.   if(EXTI_GetITStatus(EXTI_Line14)==SET)  //EXTI_GetITStatus用来获取中断标志位状态,如果EXTI线产生中断则返回SET,否则返回RESET
  12.   {
  13.     delay(1000);
  14.     Serial1.println("Run at EXTI");
  15.     EXTI_ClearITPendingBit(EXTI_Line14);  //清除中断标志位
  16.   }
  17. }
  18. }
复制代码
所有程序如下:
  1. #include <CH32V103.h>
  2. #include "HardwareSerial.h"

  3. /*******************************************************************************
  4. * 函数名  : EXTI0_INT_INIT
  5. * 描述    : EXTI初始化.
  6. * 输入    : None
  7. * 返回    : None
  8. *******************************************************************************/
  9. void EXTI0_INT_INIT(void)
  10. {
  11.   GPIO_InitTypeDef GPIO_InitStructure;
  12.   EXTI_InitTypeDef EXTI_InitStructure;
  13.   NVIC_InitTypeDef NVIC_InitStructure;

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

  15.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;                  //配置GPIO引脚
  16.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;              //配置GPIO上拉输入模式
  17.   GPIO_Init(GPIOA, &GPIO_InitStructure);                     //初始化GPIOA

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

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

  31. /*******************************************************************************
  32. * 函数名  : EXTI15_10_IRQHandler
  33. * 描述    : 中断函数.
  34. * 输入    : None
  35. * 返回    : None
  36. *******************************************************************************/
  37. extern "C"{
  38. void EXTI15_10_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  39. void EXTI15_10_IRQHandler(void)
  40. {
  41.   if(EXTI_GetITStatus(EXTI_Line14)==SET)  //EXTI_GetITStatus用来获取中断标志位状态,如果EXTI线产生中断则返回SET,否则返回RESET
  42.   {
  43.     delay(1000);
  44.     Serial1.println("Run at EXTI");
  45.     EXTI_ClearITPendingBit(EXTI_Line14);  //清除中断标志位
  46.   }
  47. }
  48. }

  49. int main(void)
  50. {
  51.   CH32_Init();
  52.   Serial1.begin(115200);
  53.   delay(2000);
  54.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  55.   Serial1.println("SystemClk:"+ String(SystemCoreClock));
  56.   Serial1.println("EXTI0 Test");
  57.   EXTI0_INT_INIT();
  58.   while(1){
  59.     delay(1000);
  60.     Serial1.println("Run at main");
  61.   }
  62.   return 1;
  63. }

复制代码

4.下载验证
在天问Block插入USB左边的TypeC口下载这个程序,再插入右侧的USB口,打开软件监视器。上位机波特率设置成115200,点击“连接串口”。如下图:
无标题.png

按下KEY1(RUN)键,程序运行,监视器显示:
SystemClk:72000000 EXTI0 test   
Run at main
(源代码有误这样应该修改成“EXTI14  test”,后面修改)
再按下KEY1键,串口监视器马上返回显示:Run at EXTI


源代码在范例代码->CH32V外设代码范例->3.EXIT.hd

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|好好搭搭在线 ( © 好好搭搭在线 浙ICP备19030393号-1 )

GMT+8, 2024-5-21 01:57 , Processed in 0.094182 second(s), 26 queries .

Powered by Discuz!

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表