GD32F30x固件库开发笔记(五)

您所在的位置:网站首页 stm32f407数据手册pdf GD32F30x固件库开发笔记(五)

GD32F30x固件库开发笔记(五)

2023-03-01 15:08| 来源: 网络整理| 查看: 265

EXTI 1. 简介1.1 特点1.2 基本功能1.3 NVIC1.4 中断优先级 2. 按键中断2.1 硬件配置2.2 软件配置2.2.1 固件库2.2.2 代码实现 2.3 外部中断效果

1. 简介

EXTI:外部中断/事件控制器(External interrupt/event controller)

EXTI包含20个相互独立的边沿检测电路并且能够向处理器内核产生中断请求或唤醒事件。 EXTI有三种触发类型:上升沿触发、下降沿触发和任意沿触发。 EXTI中的每一个边沿检测电路都可以独立配置和屏蔽。

1.1 特点 Cortex-M4 系统异常;多达 68 种可屏蔽的外设中断;4 位中断优先级配置位,可配置 16 个中断优先等级;高效的中断处理;支持异常抢占和咬尾中断;将系统从省电模式唤醒;EXTI 中有多达 20 个相互独立的边沿检测电路;3 种触发类型:上升沿触发,下降沿触发和任意沿触发;软件中断或事件触发;可配置的触发源。 1.2 基本功能

在这里插入图片描述

EXTI触发源包括来自I/O管脚的16根线以及来自内部模块的4根线。(包括LVD、RTC闹钟、 USB唤醒、以太网唤醒)

通过配置GPIO模块的AFIO_EXTISSx寄存器(备用功能寄存器,备用功能有中断,串口,调试,ADC等),所有的GPIO管脚都可以被选作EXTI的触发源。(使用外部中断线,端口必须配置为输入模式)

端口备用功能分配的详细介绍请下载芯片数据手册

除了中断, EXTI还可以向处理器提供事件信号。Cortex-M4内核完全支持等待中断(WFI),等待事件(WFE)和发送事件(SEV)指令。

芯片内部有一个唤醒中断控制器(WIC),用户可以放心的让处理器和NVIC进入功耗极低的省电模式,由WIC来识别中断和事件以及判断优先级。

当某些预期的事件发生时,例如一个特定的I/O管脚电平翻转或者RTC闹钟动作,EXTI能唤醒处理器及整个系统。

在这里插入图片描述

1.3 NVIC

Cortex-M4集成了嵌套式矢量型中断控制器(Nested Vectored Interrupt Controller (NVIC))来实现高效的异常和中断处理。NVIC实现了低延迟的异常和中断处理,以及电源管理控制。它和内核是紧密耦合的。

NVIC在处理模式下对所有异常 进行优先级区分以及处理。 当异常发生时,系统自动将当前处理器工作状态压栈,在执行完中断服务子程序(ISR)后自动将其出栈。

取向量是和当前工作态压栈并行进行的,从而提高了中断入口效率。 处理器支持咬尾中断,可实现背靠背中断,大大削减了反复切换工作态所带来的开销。

下表是Cotrex-M4中NVIC管理的 异常类型:(向量编号0-15)

在这里插入图片描述

部分中断向量表 在这里插入图片描述

1.4 中断优先级

GD32F303支持4位5组优先级,使用AIRCR寄存器设置分组; 使用IP寄存器(240个,8位宽度)的高四位(如下图的4~7位)设置优先级,由两部分构成,分别对应 高位的抢占优先级 和 低位的响应优先级:

在这里插入图片描述

2. 按键中断 2.1 硬件配置

查看原理图,当前核心板只有一个可控LED,连接管脚为PC13 在这里插入图片描述

当PC13 IO口配置为低电平,+3V3通过电阻 R7_4.7KΩ然后再通过D2发光二极管最终进入PC13形成一条通路,灯亮当PC13 IO口配置为高电平,+3V3通过电阻,再通过D2发光二极管最终进入PC13,同为高电平,线路不导通,灯灭

核心板没有按键,需要外接一个。 没有现成按键的,可以参考【开发板资料】的原理图做一个 在这里插入图片描述

可连接的IO口有不少,我选择连接到PA1 在这里插入图片描述

KEY1 接到 IC 的PA1 IO口上。

当按键K2按下,+3V3先通过电阻 R17_10KΩ,再通过按键 K2 最终进入GND形成一条通路,那么这条线路的全部电压都加到了 R17_10KΩ 这个电阻上,KEY1这个引脚就是低电平。当按键K2松开,线路断开,没有电流通过,那么KEY1和+3V3就是等电位,是一个高电平。

因此,我们可以通过 KEY1 连接 PA1 的高低电平变化来检测按键外部中断。

2.2 软件配置 2.2.1 固件库

外部中断对应库函数文件:gd32f30x_exti.h 和 gd32f30x_exti.c

在这里插入图片描述

中断优先级对应库函数文件:gd32f30x_misc.h 和 gd32f30x_misc.c

在这里插入图片描述 详情可以官网下载 《GD32F30x_固件库用户指南.pdf》

2.2.2 代码实现

在现有工程下,参考【开发板资料】的第三个例程【03_EXTI_Key_Interrupt_mode】做修改

//文件 gd32f303c_eval.h //配置KEY1按键连接的GPIO为PA1 #define TAMPER_KEY_PIN GPIO_PIN_1 #define TAMPER_KEY_GPIO_PORT GPIOA #define TAMPER_KEY_GPIO_CLK RCU_GPIOA //配置外部中断参数 #define TAMPER_KEY_EXTI_LINE EXTI_1 //配置EXTI线1 #define TAMPER_KEY_EXTI_PORT_SOURCE GPIO_PORT_SOURCE_GPIOA //配置EXTI在GPIO的A组 #define TAMPER_KEY_EXTI_PIN_SOURCE GPIO_PIN_SOURCE_1 //配置EXTI在GPIO的A组的第一个PIN脚 #define TAMPER_KEY_EXTI_IRQn EXTI1_IRQn //配置EXTI线1的中断编号 //文件 gd32f303c_eval.c //初始化LED void gd_eval_led_init (led_typedef_enum lednum) { rcu_periph_clock_enable(GPIO_CLK[lednum]); // 使能LED对应IO口时钟 gpio_init(GPIO_PORT[lednum], GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN[lednum]); // 配置LED对应IO口的属性参数 GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum]; // LED对应IO口复位 } //切换LED输出状态 void gd_eval_led_toggle(led_typedef_enum lednum) { gpio_bit_write(GPIO_PORT[lednum], GPIO_PIN[lednum], (bit_status)(1-gpio_input_bit_get(GPIO_PORT[lednum], GPIO_PIN[lednum]))); //在对应的IO口写入数据 } //初始化按键 void gd_eval_key_init(key_typedef_enum key_num, keymode_typedef_enum key_mode) { rcu_periph_clock_enable(KEY_CLK[key_num]); // 使能按键对应IO口时钟 rcu_periph_clock_enable(RCU_AF); // 使能复用时钟 // 初始化按键属性为输入,速度50MHz gpio_init(KEY_PORT[key_num], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, KEY_PIN[key_num]); //配置按键为外部中断模式 if (key_mode == KEY_MODE_EXTI) { nvic_irq_enable(KEY_IRQn[key_num], 2U, 0U); // 使能NVIC,设置中断优先级 gpio_exti_source_select(KEY_PORT_SOURCE[key_num], KEY_PIN_SOURCE[key_num]); // 将按键EXTI线连接到对应GPIO引脚 /* 初始化 EXTI线 */ exti_init(KEY_EXTI_LINE[key_num], EXTI_INTERRUPT, EXTI_TRIG_FALLING); //将按键EXTI线配置为外部中断模式,下降沿触发 exti_interrupt_flag_clear(KEY_EXTI_LINE[key_num]); // 清除按键EXTI线的待定标志 } } //返回当前按键状态 uint8_t gd_eval_key_state_get(key_typedef_enum key) { return gpio_input_bit_get(KEY_PORT[key], KEY_PIN[key]); // 获取GPIO引脚输入状态 }

查看启动文件 startup_gd32f30x_xd.s 中的中断向量表,即可找到中断服务函数的名字。 出现异常或中断,系统根据向量编号,找到中断服务的地址,进而执行中断函数。 在这里插入图片描述

中断函数后面都会跟一个[weak]标识,代表这个函数可以在其它文件中重定义。 在这里插入图片描述

我们需要在 gd32f30x_it.c 中重新定义 EXTI1_IRQHandler函数

//文件 gd32f30x_it.c //添加外部中断处理 void EXTI1_IRQHandler(void) { if(RESET != exti_interrupt_flag_get(EXTI_1)) // 得到EXTI_1线中断标志 { gd_eval_led_toggle(LED1); // 中断一次,切换一次LED状态 exti_interrupt_flag_clear(EXTI_1); // 清除按键EXTI_1线的中断标志位 } } //文件 main.c #include "gd32f30x.h" #include "gd32f303c_eval.h" #include "systick.h" int main(void) { gd_eval_key_init(KEY_TAMPER, KEY_MODE_GPIO); //调用接口,将按键KEY1 初始化为外部中断模式,默认为浮空输入模式,下降沿触发 gd_eval_led_init(LED1); //调用接口,初始化LED1的GPIO引脚,默认推挽输出模式 while(1){ } } 2.3 外部中断效果

GPIO检测按键按下,触发外部中断,LED灯的状态改变一次, LED默认灭,按一下,【灭—>亮】改变,再次按下,LED灯【亮—>灭】改变,反复循环。 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3