GD32F103学习笔记(5)——EXTI(外部中断)接口使用

一、简介

Cortex-M3集成了嵌套式矢量型中断控制器(Nested Vectored Interrupt Controller (NVIC)) 来实现高效的异常和中断处理。NVIC实现了低延迟的异常和中断处理,以及电源管理控制。它和内核是紧密耦合的。更多关于NVIC 的说明请参考《Cortex-M3 技术参考手册》。
EXTI(中断/事件控制器)包括20个相互独立的边沿检测电路并且能够向处理器内核产生中断
请求或唤醒事件。EXTI有三种触发类型:上升沿触发、下降沿触发和任意沿触发。 EXTI中的每一个边沿检测电路都可以独立配置和屏蔽。

二、API说明

以下 NVIC 接口位于 GD32F10x_Firmware_Library_V2.2.2\Firmware\GD32F10x_standard_peripheral\Include\gd32f10x_misc.h

2.1 nvic_priority_group_set

功能设置优先级组
函数定义void nvic_priority_group_set(uint32_t nvic_prigroup)
参数nvic_prigroup:优先级组
返回

nvic_prigroup: 优先级组,详细列表如下:

含义
NVIC_PRIGROUP_PRE0_SUB40位用于抢占优先级,4位用于响应优先级
NVIC_PRIGROUP_PRE1_SUB31位用于抢占优先级,3位用于响应优先级
NVIC_PRIGROUP_PRE2_SUB22位用于抢占优先级,2位用于响应优先级
NVIC_PRIGROUP_PRE3_SUB13位用于抢占优先级,1位用于响应优先级
NVIC_PRIGROUP_PRE4_SUB04位用于抢占优先级,0位用于响应优先级

2.2 nvic_irq_enable

功能使能NVIC的中断
函数定义void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority)
参数nvic_irq:NVIC中断
nvic_irq_pre_priority:抢占优先级(04)<br>nvic_irq_sub_priority:响应优先级(04)
返回

以下 GPIO 接口位于 GD32F10x_Firmware_Library_V2.2.2\Firmware\GD32F10x_standard_peripheral\Include\gd32f10x_gpio.h

2.3 gpio_exti_source_select

功能选择哪个引脚作为EXTI源
函数定义void gpio_exti_source_select(uint8_t output_port, uint8_t output_pin)
参数output_port:EXTI源端口x(x = A,B,C,D,E,F,G)
output_pin:源端口引脚x(x=0…15)
返回

以下 EXTI 接口位于 GD32F10x_Firmware_Library_V2.2.2\Firmware\GD32F10x_standard_peripheral\Include\gd32f10x_exti.h

2.4 exti_init

功能初始化EXTI线x
函数定义void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type)
参数linex:EXTI线x(x=0,1,2…19)
mode:EXTI模式
trig_type:触发类型
返回

mode: EXTI模式,详细列表如下:

含义
EXTI_INTERRUPT中断模式
EXTI_EVENT事件模式

trig_type: 触发类型,详细列表如下:

含义
EXTI_TRIG_RISING上升沿触发
EXTI_TRIG_FALLING下降沿触发
EXTI_TRIG_BOTH上升沿和下降沿均触发

2.5 exti_interrupt_flag_get

功能获取EXTI线x中断标志位
函数定义FlagStatus exti_interrupt_flag_get(exti_line_enum linex)
参数linex:EXTI线x(x=0,1,2…19)
返回SET或RESET

2.6 exti_interrupt_flag_clear

功能清除EXTI线x中断标志位
函数定义void exti_interrupt_flag_clear(exti_line_enum linex)
参数linex:EXTI线x(x=0,1,2…19)
返回

三、EXTI外部中断

3.1 引脚确定

我使用的是 光子MINI-GD32F103RCT6 开发板

有个 IO 口为 PA1 的按键

3.2 编程要点

  1. 初始化用来产生中断的 GPIO
  2. 初始化 EXTI
  3. 配置 NVIC
  4. 编写中断服务函数

3.3 GPIO初始化

  • 如果硬件上已外部上拉或下拉,则选择浮空输入模式。
  • 如果硬件外部没有上拉,则选择内部上拉模式。
//GPIOA时钟使能
rcu_periph_clock_enable(RCU_GPIOA);
//PA1配置成上拉输入
gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_1);

3.4 外部中断初始化

  • 配置 EXTI 信号源的时候需要用到 AFIO 的外部中断控制寄存器 AFIO_EXTISSx,所以用到 EXTI 必须开启 AFIO 时钟

  • 抢占优先级,数字越小,优先级越高

  • 若抢占优先级相同,判断子优先级,同样,数字越小,优先级越高

//使能复用功能时钟
rcu_periph_clock_enable(RCU_AF);
//设置优先级分组
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
//设置优先级
nvic_irq_enable(EXTI1_IRQn, 2U, 2U);

//设置EXTI触发源
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_1);

//下降沿中断
exti_init(EXTI_1, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
//清中断标志
exti_interrupt_flag_clear(EXTI_1);

NVIC IRQn_Type:

名称功能
EXTI0_IRQnEXTI线0中断
EXTI1_IRQnEXTI线1中断
EXTI2_IRQnEXTI线2中断
EXTI3_IRQnEXTI线3中断
EXTI4_IRQnEXTI线4中断
EXTI5_9_IRQnEXTI线[9:5]中断
EXTI10_15_IRQnEXTI线[15:10]中断

3.5 外部中断处理函数

当中断发生时,对应的中断服务函数就会被执行,我们可以在中断服务函数实现一些控制。

一般为确保中断确实发生,我们会在中断服务函数中调用中断标志位状态读取函数读取外设中断标志位并判断标志位状态。

exti_interrupt_flag_get() 函数用来获取 EXTI 的中断标志位状态,如果 EXTI 线有中断发生函数返回“SET”否则返回“RESET”。实际上,exti_interrupt_flag_get() 函数是通过读取 EXTI_PD 寄存器值来判断 EXTI 线状态的。

/*!
    \brief      this function handles external lines 1 interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void EXTI1_IRQHandler(void)
{
    //判定是否是外部中断线1
    if (RESET != exti_interrupt_flag_get(EXTI_1)) 
    {
        //在此加入自己的控制,一般为置标志等短暂非阻塞操作

        //清除中断标记
        exti_interrupt_flag_clear(TAMPER_KEY_EXTI_LINE);
    }
}

外部中断处理函数名称要与EXTI线相对应,可在 startup_gd32f10x_hd.s 启动文件中查看:

;                   /* external interrupts handler */
                    DCD     WWDGT_IRQHandler                  ; 16:Window Watchdog Timer
                    DCD     LVD_IRQHandler                    ; 17:LVD through EXTI Line detect
                    DCD     TAMPER_IRQHandler                 ; 18:Tamper Interrupt   
                    DCD     RTC_IRQHandler                    ; 19:RTC through EXTI Line
                    DCD     FMC_IRQHandler                    ; 20:FMC
                    DCD     RCU_IRQHandler                    ; 21:RCU
                    DCD     EXTI0_IRQHandler                  ; 22:EXTI Line 0
                    DCD     EXTI1_IRQHandler                  ; 23:EXTI Line 1
                    DCD     EXTI2_IRQHandler                  ; 24:EXTI Line 2
                    DCD     EXTI3_IRQHandler                  ; 25:EXTI Line 3
                    DCD     EXTI4_IRQHandler                  ; 26:EXTI Line 4
                    DCD     DMA0_Channel0_IRQHandler          ; 27:DMA0 Channel 0
                    DCD     DMA0_Channel1_IRQHandler          ; 28:DMA0 Channel 1
                    DCD     DMA0_Channel2_IRQHandler          ; 29:DMA0 Channel 2
                    DCD     DMA0_Channel3_IRQHandler          ; 30:DMA0 Channel 3
                    DCD     DMA0_Channel4_IRQHandler          ; 31:DMA0 Channel 4
                    DCD     DMA0_Channel5_IRQHandler          ; 32:DMA0 Channel 5 
                    DCD     DMA0_Channel6_IRQHandler          ; 33:DMA0 Channel 6
                    DCD     ADC0_1_IRQHandler                 ; 34:ADC0 and ADC1
                    DCD     USBD_HP_CAN0_TX_IRQHandler        ; 35:USBD and CAN0 TX
                    DCD     USBD_LP_CAN0_RX0_IRQHandler       ; 36:USBD and CAN0 RX0
                    DCD     CAN0_RX1_IRQHandler               ; 37:CAN0 RX1
                    DCD     CAN0_EWMC_IRQHandler              ; 38:CAN0 EWMC
                    DCD     EXTI5_9_IRQHandler                ; 39:EXTI Line 5 to EXTI Line 9
                    DCD     TIMER0_BRK_IRQHandler             ; 40:TIMER0 Break
                    DCD     TIMER0_UP_IRQHandler              ; 41:TIMER0 Update
                    DCD     TIMER0_TRG_CMT_IRQHandler         ; 42:TIMER0 Trigger and Commutation
                    DCD     TIMER0_Channel_IRQHandler         ; 43:TIMER0 Channel Capture Compare
                    DCD     TIMER1_IRQHandler                 ; 44:TIMER1
                    DCD     TIMER2_IRQHandler                 ; 45:TIMER2
                    DCD     TIMER3_IRQHandler                 ; 46:TIMER3
                    DCD     I2C0_EV_IRQHandler                ; 47:I2C0 Event
                    DCD     I2C0_ER_IRQHandler                ; 48:I2C0 Error
                    DCD     I2C1_EV_IRQHandler                ; 49:I2C1 Event
                    DCD     I2C1_ER_IRQHandler                ; 50:I2C1 Error
                    DCD     SPI0_IRQHandler                   ; 51:SPI0
                    DCD     SPI1_IRQHandler                   ; 52:SPI1
                    DCD     USART0_IRQHandler                 ; 53:USART0
                    DCD     USART1_IRQHandler                 ; 54:USART1
                    DCD     USART2_IRQHandler                 ; 55:USART2
                    DCD     EXTI10_15_IRQHandler              ; 56:EXTI Line 10 to EXTI Line 15
                    DCD     RTC_Alarm_IRQHandler              ; 57:RTC Alarm through EXTI Line
                    DCD     USBD_WKUP_IRQHandler              ; 58:USBD WakeUp from suspend through EXTI Line
                    DCD     TIMER7_BRK_IRQHandler             ; 59:TIMER7 Break Interrupt
                    DCD     TIMER7_UP_IRQHandler              ; 60:TIMER7 Update Interrupt
                    DCD     TIMER7_TRG_CMT_IRQHandler         ; 61:TIMER7 Trigger and Commutation Interrupt
                    DCD     TIMER7_Channel_IRQHandler         ; 62:TIMER7 Channel Capture Compare 
                    DCD     ADC2_IRQHandler                   ; 63:ADC2
                    DCD     EXMC_IRQHandler                   ; 64:EXMC
                    DCD     SDIO_IRQHandler                   ; 65:SDIO
                    DCD     TIMER4_IRQHandler                 ; 66:TIMER4
                    DCD     SPI2_IRQHandler                   ; 67:SPI2
                    DCD     UART3_IRQHandler                  ; 68:UART3
                    DCD     UART4_IRQHandler                  ; 69:UART4
                    DCD     TIMER5_IRQHandler                 ; 70:TIMER5
                    DCD     TIMER6_IRQHandler                 ; 71:TIMER6
                    DCD     DMA1_Channel0_IRQHandler          ; 72:DMA1 Channel0
                    DCD     DMA1_Channel1_IRQHandler          ; 73:DMA1 Channel1
                    DCD     DMA1_Channel2_IRQHandler          ; 74:DMA1 Channel2
                    DCD     DMA1_Channel3_4_IRQHandler        ; 75:DMA1 Channel3 and Channel4

四、按键外部中断,反转LED灯

4.1 board_gpio.c

/*********************************************************************
 * INCLUDES
 */
#include "gd32f10x.h"

#include "board_gpio.h"

/*********************************************************************
 * PUBLIC FUNCTIONS
 */
/*=========================================================================*/
/*                                   输入                                  */
/*=========================================================================*/
/**
 @brief 按键驱动初始化
 @param 无
 @return 无
*/
void Key_GPIO_Init(void)
{
    // GPIO时钟使能
    rcu_periph_clock_enable(RCU_GPIOA);
    // 配置为内部上拉输入模式
    gpio_init(KEY1_GPIO_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, KEY1_GPIO_PIN);
}

/**
 @brief 获取按键状态
 @param keyNum -[in] 按键编号
 @return 1 - 按下;0 - 松开
*/
uint8_t Key_GPIO_Read(uint8_t keyNum)
{
    uint8_t value = 0;

    if(KEY1 == keyNum)
    {
        value = gpio_input_bit_get(KEY1_GPIO_PORT, KEY1_GPIO_PIN);
    }
//    else if(KEY2 == keyNum)
//    {
//        value = gpio_input_bit_get(KEY2_GPIO_PORT, KEY2_GPIO_PIN);
//    }

    return value;
}


/*=========================================================================*/
/*                                   输出                                  */
/*=========================================================================*/
/**
 @brief LED灯驱动初始化
 @param 无
 @return 无
*/
void LED_GPIO_Init(void)
{
    // PB4管脚默认是NJTRST,要当GPIO,需要重映射
    rcu_periph_clock_enable(RCU_AF);                                    // 管脚复用时钟使能
	gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP, ENABLE);
    
    // GPIO时钟使能
	rcu_periph_clock_enable(RCU_GPIOB);
    // 配置为推挽输出模式
	gpio_init(LED1_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED1_GPIO_PIN);

    LED_GPIO_Write(LED1, LED_OFF);
}

/**
 @brief 配置LED灯工作模式
 @param ledNum -[in] LED灯编号
 @param ledMode -[in] 工作模式
 @return 无
*/
void LED_GPIO_Write(uint8_t ledNum, uint8_t ledMode)
{
    if(LED1 == ledNum)
    {
        gpio_bit_write(LED1_GPIO_PORT, LED1_GPIO_PIN, ledMode);
    }
//    else if(LED2 == ledNum)
//    {
//        gpio_bit_write(LED2_GPIO_PORT, LED2_GPIO_PIN, ledMode);
//    }
}

/**
 @brief 获取LED灯工作模式
 @param ledNum -[in] LED灯编号
 @return 工作模式
*/
uint8_t LED_GPIO_Read(uint8_t ledNum)
{
    uint8_t ledMode = 0;
    if(LED1 == ledNum)
    {
        ledMode = gpio_output_bit_get(LED1_GPIO_PORT, LED1_GPIO_PIN);
    }
//    else if(LED2 == ledNum)
//    {
//        ledMode = gpio_output_bit_get(LED2_GPIO_PORT, LED2_GPIO_PIN, &ledMode);
//    }
    return ledMode;
}

/****************************************************END OF FILE****************************************************/

4.2 board_gpio.h

#ifndef _BOARD_GPIO_H_
#define _BOARD_GPIO_H_

/*********************************************************************
 * INCLUDES
 */
#include "gd32f10x_gpio.h"
 
/*********************************************************************
 * DEFINITIONS
 */
/*=========================================================================*/
/*                                   输入                                  */
/*=========================================================================*/
#define KEY1_GPIO_PORT                  GPIOA
#define KEY1_GPIO_PIN                   GPIO_PIN_1
#define KEY_OFF                         0x01
#define KEY_ON                          0x00
#define KEY1                            1
#define KEY2                            2

/*=========================================================================*/
/*                                   输出                                  */
/*=========================================================================*/
#define LED1_GPIO_PORT                  GPIOB
#define LED1_GPIO_PIN                   GPIO_PIN_4
#define LED_OFF                         0x01
#define LED_ON                          0x00
#define LED1                            1
#define LED2                            2

/*********************************************************************
 * API FUNCTIONS
 */
void Key_GPIO_Init(void);
uint8_t Key_GPIO_Read(uint8_t keyNum);

void LED_GPIO_Init(void);
void LED_GPIO_Write(uint8_t ledNum, uint8_t ledMode);
uint8_t LED_GPIO_Read(uint8_t ledNum);

#endif /* _BOARD_GPIO_H_ */

4.3 board_exti.c

/*********************************************************************
 * INCLUDES
 */
#include "gd32f10x.h"

#include "board_exti.h"

/*********************************************************************
 * PUBLIC FUNCTIONS
 */
/**
 @brief 按键外部中断初始化
 @param 无
 @return 无
*/
void Key_EXTI_Init(void)
{
    // AFIO时钟使能
    rcu_periph_clock_enable(RCU_AF);
    
    // 设置优先级分组
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
    // 设置优先级
    nvic_irq_enable(EXTI1_IRQn, 2U, 2U);
    
    // 设置EXTI触发源
    gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_1);

    // 下降沿中断
    exti_init(EXTI_1, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
    // 清中断标志
    exti_interrupt_flag_clear(EXTI_1);
}

/****************************************************END OF FILE****************************************************/

4.4 board_exti.h

#ifndef _BOARD_EXTI_H_
#define _BOARD_EXTI_H_

/*********************************************************************
 * INCLUDES
 */
#include "gd32f10x_exti.h"
 
/*********************************************************************
 * DEFINITIONS
 */

/*********************************************************************
 * API FUNCTIONS
 */
void Key_EXTI_Init(void);

#endif /* _BOARD_EXTI_H_ */

4.5 user_key.c

/*********************************************************************
 * INCLUDES
 */
#include "board_exti.h"
#include "board_gpio.h"

/*********************************************************************
 * PUBLIC FUNCTIONS
 */
/**
 @brief 按键模块初始化
 @param 无
 @return 无
*/
void Key_Init(void)
{
    Key_GPIO_Init();
    Key_EXTI_Init();
}

/**
 @brief 按键中断回调函数
 @param 无
 @return 无
*/
void Key_GPIO_IrqCallback(void)
{
    static uint8_t toggle;
    if(0 == toggle)
    {
        LED_GPIO_Write(LED1, LED_ON);
        toggle = 1;
    }
    else
    {        
        LED_GPIO_Write(LED1, LED_OFF);
        toggle = 0;
    }
}

/****************************************************END OF FILE****************************************************/

4.6 user_key.h

#ifndef _USER_KEY_H_
#define _USER_KEY_H_

/*********************************************************************
 * INCLUDES
 */

/*********************************************************************
 * API FUNCTIONS
 */
void Key_Init(void);

#endif /* _USER_KEY_H_ */

4.7 gd32f10x_it.c

/*!
    \file    gd32f10x_it.c
    \brief   interrupt service routines

    \version 2014-12-26, V1.0.0, firmware for GD32F10x
    \version 2017-06-20, V2.0.0, firmware for GD32F10x
    \version 2018-07-31, V2.1.0, firmware for GD32F10x
    \version 2020-09-30, V2.2.0, firmware for GD32F10x
*/

/*
    Copyright (c) 2020, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this 
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice, 
       this list of conditions and the following disclaimer in the documentation 
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors 
       may be used to endorse or promote products derived from this software without 
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
*/
#include "gd32f10x_it.h"
#include "systick.h"

void Key_GPIO_IrqCallback(void);

/*!
    \brief      this function handles NMI exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void NMI_Handler(void)
{
}

/*!
    \brief      this function handles HardFault exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void HardFault_Handler(void)
{
    /* if Hard Fault exception occurs, go to infinite loop */
    while(1){
    }
}

/*!
    \brief      this function handles MemManage exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void MemManage_Handler(void)
{
    /* if Memory Manage exception occurs, go to infinite loop */
    while(1){
    }
}

/*!
    \brief      this function handles BusFault exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void BusFault_Handler(void)
{
    /* if Bus Fault exception occurs, go to infinite loop */
    while(1){
    }
}

/*!
    \brief      this function handles UsageFault exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void UsageFault_Handler(void)
{
    /* if Usage Fault exception occurs, go to infinite loop */
    while(1){
    }
}

/*!
    \brief      this function handles SVC exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void SVC_Handler(void)
{
}

/*!
    \brief      this function handles DebugMon exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void DebugMon_Handler(void)
{
}

/*!
    \brief      this function handles PendSV exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void PendSV_Handler(void)
{
}

/*!
    \brief      this function handles SysTick exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void SysTick_Handler(void)
{
    delay_decrement();
}

/*!
    \brief      this function handles external lines 1 interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void EXTI1_IRQHandler(void)
{
    if(RESET != exti_interrupt_flag_get(EXTI_1)) 
    {
        Key_GPIO_IrqCallback();
        exti_interrupt_flag_clear(EXTI_1);
    }    
}

/**
 @brief 弱化函数,请在其他地方实现
 @param 无
 @return 无
*/
__attribute__((weak)) void Key_GPIO_IrqCallback(void)
{
  /* NOTE : This function should not be modified, when the callback is needed,
            it could be implemented in the user file
   */
}

4.8 main.c

#include "gd32f10x.h"
#include "systick.h"

#include "board_gpio.h"
#include "user_key.h"

int main(void)
{
    systick_config();//系统主频108MHZ,采用外部晶振,由两个宏决定(__SYSTEM_CLOCK_108M_PLL_HXTAL与HXTAL_VALUE)
    
    Key_Init();     // 按键模块初始化
    LED_GPIO_Init();// LED灯模块初始化
	
    while(1)
    {
    }
}

4.9 工程代码

百度网盘:https://pan.baidu.com/s/1wMrs0xfVbFU5qNGYovO8ow?pwd=lszm 提取码:lszm


• 由 Leung 写于 2022 年 4 月 13 日

• 参考:11. GD32F103C8T6 入门教程-外部中断

  • 8
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leung_ManWah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值