5.10 GPIO 使用说明

本章说明 N32G41x 标准外设库中 GPIO 与 AFIO 驱动的文件组成、22 个公开函数,以及 IORemap、LedBlink 两个示例。端口结构、复用功能映射与引脚锁定序列请配合用户手册的“GPIO 和 AFIO”章节阅读,芯片已知问题以勘误手册为准。

5.10.1 相关文件

相对路径 作用
firmware/n32g41x_std_periph_driver/inc/n32g41x_gpio.h 定义 GPIO_InitType 结构体与引脚、模式、上下拉、翻转率、驱动能力、复用功能、EXTI 线来源等宏,并按复位与初始化、读取、写入、配置、AFIO 配置、EXTI 线配置六个区段声明 22 个公开函数
firmware/n32g41x_std_periph_driver/src/n32g41x_gpio.c 实现上述 22 个函数:端口与引脚复位,模式与复用字段写入,端口数据读写,引脚锁定序列,AFIO 与 EXTI 线配置
projects/n32g41x_EVAL/examples/GPIO/ GPIO 示例根目录,含 IORemap、LedBlink 2 个示例
projects/n32g41x_EVAL/examples/GPIO/LedBlink/ 该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt
projects/n32g41x_EVAL/bsp/ 两个示例共用的板级支持文件:评估板 LED 与按键定义、日志串口初始化、毫秒延时函数

5.10.2 API 参考

搜索 API共 22 个函数

以下 22 个公开函数按 n32g41x_gpio.h 的声明顺序分为 6 组;每个条目给出功能摘要与 n32g41x_gpio.c 中该函数正上方的注释原文。

复位与初始化

GPIO_DeInit、GPIO_DeInitPin、GPIO_InitPeripheral、GPIO_InitStruct

读取

GPIO_ReadInputDataBit、GPIO_ReadInputData、GPIO_ReadOutputDataBit、GPIO_ReadOutputData

写入

GPIO_SetBits、GPIO_WritePBSC、GPIO_ResetBits、GPIO_WriteBit、GPIO_Write、GPIO_TogglePin

配置

GPIO_ConfigPinLock、GPIO_ConfigPinRemap

AFIO 配置

AFIO_ConfigSPINSSMode、AFIO_ConfigEXTIFlitEN、AFIO_ConfigIOFlitNum、AFIO_DIGEFTEnable

EXTI 线配置

GPIO_ConfigEXTILine、GPIO_ClearEXTILine

void GPIO_DeInit(void)将 GPIOx 外设寄存器复位为默认复位值。
源码注释
name   GPIO_DeInit.
fun    Reset the GPIOx peripheral registers to their default reset values.
param  none
return none
void GPIO_DeInitPin(GPIO_Module *GPIOx, uint32_t Pin)将选定的 GPIOx 引脚恢复为默认复位值。
源码注释
name   GPIO_DeInitPin.
fun    Restores the selected GPIOx pins to their default reset values.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
          - GPIO_PIN_ALL
return none
void GPIO_InitPeripheral(GPIO_Module *GPIOx, const GPIO_InitType *GPIO_InitParam)按 GPIO_InitType 结构体的值初始化选定的 GPIOx 引脚。
源码注释
name   GPIO_InitPeripheral.
fun    Initialize the selected GPIOx pins with the value of the GPIO_InitType structure.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  GPIO_InitParam :
            - Pin
               - GPIO_PIN_0
               - GPIO_PIN_1
               - GPIO_PIN_2
               - GPIO_PIN_3
               - GPIO_PIN_4
               - GPIO_PIN_5
               - GPIO_PIN_6
               - GPIO_PIN_7
               - GPIO_PIN_8
               - GPIO_PIN_9
               - GPIO_PIN_10
               - GPIO_PIN_11
               - GPIO_PIN_12
               - GPIO_PIN_13
               - GPIO_PIN_14
               - GPIO_PIN_15
               - GPIO_PIN_ALL
            - GPIO_Mode
               - GPIO_MODE_INPUT
               - GPIO_MODE_OUTPUT_PP
               - GPIO_MODE_OUTPUT_OD
               - GPIO_MODE_AF_PP
               - GPIO_MODE_AF_OD
               - GPIO_MODE_ANALOG
            - GPIO_Pull
               - GPIO_NO_PULL
               - GPIO_PULL_UP
               - GPIO_PULL_DOWN
            - GPIO_Slew_Rate
               note: only effective for pins PA0, PA1, PA2, PB5, PB6, PB7
               - GPIO_SLEW_RATE_FAST
               - GPIO_SLEW_RATE_SLOW
            - GPIO_Current
               - GPIO_DS_HIGH
               - GPIO_DS_LOW
            - GPIO_Alternate
               - GPIO_AF0
               - GPIO_AF1
               - GPIO_AF2
               - GPIO_AF3
               - GPIO_AF4
               - GPIO_AF5
               - GPIO_AF6
               - GPIO_AF7
               - GPIO_AF8
               - GPIO_AF9
               - GPIO_AF10
               - GPIO_AF11
               - GPIO_AF12
               - GPIO_AF13
               - GPIO_AF14
               - GPIO_NO_AF            NO alternate Function mapping
return none
void GPIO_InitStruct(GPIO_InitType *GPIO_InitStructure)为 GPIO_InitType 的各成员赋予默认值。
源码注释
name   GPIO_InitStruct.
fun    Assign default values to each GPIO_InitType member.
param  GPIO_InitStructure :
           pointer to GPIO_InitType structure.
return none
uint8_t GPIO_ReadInputDataBit(const GPIO_Module *GPIOx, uint16_t Pin)获取指定输入端口的引脚状态。
源码注释
name   GPIO_ReadInputDataBit.
fun    Get the pin status on the specified input port.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
return the pin state on the input port.
uint16_t GPIO_ReadInputData(const GPIO_Module *GPIOx)获取指定 GPIO 端口的输入数据。
源码注释
name   GPIO_ReadInputData.
fun    Get the input data on the designated GPIO port.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
return the data value on the GPIO input port.
uint8_t GPIO_ReadOutputDataBit(const GPIO_Module *GPIOx, uint16_t Pin)获取指定输出端口的引脚状态。
源码注释
name   GPIO_ReadOutputDataBit.
fun    Get the pin status on the specified output port.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
return the pin state on the output port.
uint16_t GPIO_ReadOutputData(const GPIO_Module *GPIOx)获取指定 GPIO 端口的输出数据。
源码注释
name   GPIO_ReadOutputData.
fun    Get the output data on the designated GPIO port.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
return the data value on the GPIO output port.
void GPIO_SetBits(GPIO_Module *GPIOx, uint16_t Pin)置位选定的数据端口位。
源码注释
name   GPIO_SetBits.
fun    Sets the selected data port bits.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
return none

使用提示: 实现向 GPIOx->PBSC 写入 Pin,PBSC 中写 1 的位被置位、写 0 的位保持不变,单次 AHB 写即可完成,不需要读改写,也不需要关中断。

void GPIO_WritePBSC(GPIO_Module *GPIOx, uint16_t Pin, uint8_t bitstatus)通过 GPIOx_PBSC 置位或清除选定的数据端口位。
源码注释
name   GPIO_WritePBSC.
fun    Sets or clears the selected data port bits via GPIOx_PBSC.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
param  bitstatus :
             - Bit_SET
             - Bit_RESET
return none

使用提示:bitstatus 为 Bit_SET 时写 GPIOx->PBSC = Pin 置位,其余取值写 GPIOx->PBSC = Pin << 16 清除,即 PBSC 的高 16 位为清除位。

void GPIO_ResetBits(GPIO_Module *GPIOx, uint16_t Pin)复位选定的数据端口位。
源码注释
name   GPIO_ResetBits.
fun    Reset the selected data port bits.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
return none

使用提示: 实现向 GPIOx->PBC 写入 Pin,写 1 的位被清除、写 0 的位保持不变。

void GPIO_WriteBit(GPIO_Module *GPIOx, uint16_t Pin, Bit_OperateType BitCmd)置位或复位选定的数据端口位。
源码注释
name   GPIO_WriteBit.
fun    Set or reset the selected data port bits.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
param  BitCmd :
          - Bit_RESET
          - Bit_SET
return none

使用提示:BitCmd 不等于 Bit_RESET 时向 GPIOx->PBSC 写入 Pin,等于 Bit_RESET 时向 GPIOx->PBC 写入 Pin,两种写法都不影响 Pin 之外的位。

void GPIO_Write(GPIO_Module *GPIOx, uint16_t data_value)向指定的 GPIO 数据端口写入数据。
源码注释
name   GPIO_Write.
fun    Write data on the designated GPIO data port.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  data_value :
          the value to be written to the port output data register.
          - 0~0xFFFF
return none

使用提示: 实现直接把 data_value 整字写入 GPIOx->POD,写入范围为 0~0xFFFF,会覆盖该端口全部 16 个引脚的输出电平,不是逐位操作。

void GPIO_TogglePin(GPIO_Module *GPIOx, uint16_t Pin)翻转指定端口引脚的电平。
源码注释
name   GPIO_TogglePin.
fun    Toggle the specified port pin level.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
return none

使用提示: 实现是 GPIOx->POD ^= Pin,即读回输出数据寄存器再整字写回,与 GPIO_SetBits、GPIO_ResetBits 的单次写不同。

void GPIO_ConfigPinLock(GPIO_Module *GPIOx, uint16_t Pin)配置 GPIO 端口锁定寄存器。
源码注释
name   GPIO_ConfigPinLock.
fun    GPIO port lock register configuration.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
return none

使用提示: 实现按 w1 → w0 → w1 的次序把 GPIO_PLOCK_PLOCKK | Pin 与 Pin 交替写入 GPIOx->PLOCK,再连续两次读回该寄存器,即手册要求的 w1→w0→w1→r0 序列;序列中间不能改变 PLOCK[15:0]。

void GPIO_ConfigPinRemap(uint8_t PortSource, uint32_t PinSource, uint32_t AlternateFunction)配置引脚复用映射。
源码注释
name   GPIO_ConfigPinRemap.
fun    Pin remapping configuration.
param  PortSource :
          - GPIOA_PORT_SOURCE
          - GPIOB_PORT_SOURCE
          - GPIOC_PORT_SOURCE
          - GPIOD_PORT_SOURCE
param  PinSource :
          - GPIO_PIN_SOURCE0
          - GPIO_PIN_SOURCE1
          - GPIO_PIN_SOURCE2
          - GPIO_PIN_SOURCE3
          - GPIO_PIN_SOURCE4
          - GPIO_PIN_SOURCE5
          - GPIO_PIN_SOURCE6
          - GPIO_PIN_SOURCE7
          - GPIO_PIN_SOURCE8
          - GPIO_PIN_SOURCE9
          - GPIO_PIN_SOURCE10
          - GPIO_PIN_SOURCE11
          - GPIO_PIN_SOURCE12
          - GPIO_PIN_SOURCE13
          - GPIO_PIN_SOURCE14
          - GPIO_PIN_SOURCE15
param  AlternateFunction :
          - GPIO_AF0
          - GPIO_AF1
          - GPIO_AF2
          - GPIO_AF3
          - GPIO_AF4
          - GPIO_AF5
          - GPIO_AF6
          - GPIO_AF7
          - GPIO_AF8
          - GPIO_AF9
          - GPIO_AF10
          - GPIO_AF11
          - GPIO_AF12
          - GPIO_AF13
          - GPIO_AF14
          - GPIO_NO_AF            NO alternate Function mapping
return none
void AFIO_ConfigSPINSSMode(uint32_t AFIO_SPIx_NSS, uint32_t SpiNssMode)SPIx NSS 配置成推挽复用模式时配置 NSS 空闲状态。
源码注释
name   AFIO_ConfigSPINSSMode.
fun    Selects the alternate function SPIx NSS mode.
param  AFIO_SPIx_NSS :
          choose which SPI configuration.
          - AFIO_SPI1_NSS
          - AFIO_SPI2_NSS
param  SpiNssMode :
          specifies the SPI_NSS mode to be configured.
          - AFIO_SPI_NSS_HIGH_IMPEDANCE
          - AFIO_SPI_NSS_HIGH_LEVEL
return none
void AFIO_ConfigEXTIFlitEN(FunctionalState Cmd)配置 EXTI 滤波使能。
源码注释
name   AFIO_ConfigEXTIFlitEN.
fun    Configure EXTI filter enable.
param  Cmd :
          - ENABLE
          - DISABLE
return none
void AFIO_ConfigIOFlitNum(uint32_t filter_clk)以 HCLK 时钟周期为单位配置 IO 滤波时间。
源码注释
name   AFIO_ConfigIOFlitNum.
fun    Configure the IO filter time in HCLK clock cycles.
param  filter_clk
          - GPIO_FILTER_BYPASS
          - GPIO_FILTER_1_CLK
          - GPIO_FILTER_2_CLK
          - GPIO_FILTER_3_CLK
return none
void AFIO_DIGEFTEnable(const GPIO_Module *GPIOx, uint32_t Pin, FunctionalState Cmd)使能或禁止端口引脚的数字化毛刺滤波器。
源码注释
name   AFIO_DIGEFTEnable.
fun    Enables or disables the digital glitch filter of port pins.
param  GPIOx :
          - GPIOA
          - GPIOB
          - GPIOC
          - GPIOD
param  Pin :
          - GPIO_PIN_0
          - GPIO_PIN_1
          - GPIO_PIN_2
          - GPIO_PIN_3
          - GPIO_PIN_4
          - GPIO_PIN_5
          - GPIO_PIN_6
          - GPIO_PIN_7
          - GPIO_PIN_8
          - GPIO_PIN_9
          - GPIO_PIN_10
          - GPIO_PIN_11
          - GPIO_PIN_12
          - GPIO_PIN_13
          - GPIO_PIN_14
          - GPIO_PIN_15
          - GPIO_PIN_ALL
param  Cmd :
          - ENABLE
          - DISABLE
return none
void GPIO_ConfigEXTILine(uint8_t PortSource, uint32_t PinSource)选择用作 EXTI 线的 GPIO 引脚。一条 EXTI 线只能配置一个引脚。
源码注释
name   GPIO_ConfigEXTILine.
fun    Selects the GPIO pin used as EXTI Line. A single EXTI line can only be configured with a single pin.
param  PortSource :
          - GPIOA_PORT_SOURCE
          - GPIOB_PORT_SOURCE
          - GPIOC_PORT_SOURCE
          - GPIOD_PORT_SOURCE
param  PinSource :
          - GPIO_PIN_SOURCE0
          - GPIO_PIN_SOURCE1
          - GPIO_PIN_SOURCE2
          - GPIO_PIN_SOURCE3
          - GPIO_PIN_SOURCE4
          - GPIO_PIN_SOURCE5
          - GPIO_PIN_SOURCE6
          - GPIO_PIN_SOURCE7
          - GPIO_PIN_SOURCE8
          - GPIO_PIN_SOURCE9
          - GPIO_PIN_SOURCE10
          - GPIO_PIN_SOURCE11
          - GPIO_PIN_SOURCE12
          - GPIO_PIN_SOURCE13
          - GPIO_PIN_SOURCE14
          - GPIO_PIN_SOURCE15
return none

使用提示: 实现把 PortSource 与 PinSource 一并写入 AFIO 的 EXTI 线配置寄存器,同一引脚源只能绑定一个端口,重复配置会覆盖上一次的选择。

void GPIO_ClearEXTILine(uint8_t LineSource)清除用作 EXTI 线的 GPIO 引脚。
源码注释
name   GPIO_ClearEXTILine.
fun    Clear the GPIO pin used as EXTI Line.
param  LineSource :
          - GPIO_EXTILINE_SOURCE0
          - GPIO_EXTILINE_SOURCE1
          - GPIO_EXTILINE_SOURCE2
          - GPIO_EXTILINE_SOURCE3
          - GPIO_EXTILINE_SOURCE4
          - GPIO_EXTILINE_SOURCE5
          - GPIO_EXTILINE_SOURCE6
          - GPIO_EXTILINE_SOURCE7
          - GPIO_EXTILINE_SOURCE8
          - GPIO_EXTILINE_SOURCE9
          - GPIO_EXTILINE_SOURCE10
          - GPIO_EXTILINE_SOURCE11
          - GPIO_EXTILINE_SOURCE12
          - GPIO_EXTILINE_SOURCE13
          - GPIO_EXTILINE_SOURCE14
          - GPIO_EXTILINE_SOURCE15
return none

使用提示: 实现按 LineSource 清除 AFIO 中对应 EXTI 线的端口选择位,使该线不再由任何 GPIO 引脚驱动。

5.10.3 Demo 示例说明

本节说明 GPIO 的 2 个示例:IORemap 让 SWD 引脚 PA13、PA14 在调试功能与普通输出之间切换,LedBlink 用推挽输出控制评估板上的三路 LED。

5.10.3.1 IORemap SWD 引脚复用为普通 IO

工程目录: projects/n32g41x_EVAL/examples/GPIO/IORemap/

初始化日志串口→配置 PA1、PA7 为推挽输出与 PA4 为上拉输入→轮询 KEY1 的按下状态→按下期间把 PA13、PA14 释放为普通推挽输出并每 50 ms 轮流翻转→松开后恢复两只引脚的 SWD 复用功能并点亮 LED2

项目 源码解读
功能 按住 KEY1 时把 SWD 引脚 PA13(SWDIO)、PA14(SWCLK)从调试功能释放为推挽输出并轮流翻转;
松开 KEY1 时把两脚恢复为 SWD 复用功能。
LED1 亮表示两脚处于普通输出状态,LED2 亮表示处于 SWD 状态。
源码组成 src/main.c:LED 与按键初始化、SWD_Function_Initialize、SWD_As_GPIO_Initialize 与主循环;
inc/main.h:SWDIO_PORT/SWDIO_PIN、SWCLK_PORT/SWCLK_PIN 等宏与函数声明;
src/n32g41x_it.c、inc/n32g41x_it.h:中断服务函数;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程。
关键配置 LED1 为 PA1、LED2 为 PA7,均初始化为 GPIO_MODE_OUTPUT_PP;
KEY1 为 PA4,初始化为 GPIO_MODE_INPUT 且上下拉取 BUTTON_KEY1_PULL,按下电平为 BUTTON_KEY1_STATE。
SWD 状态下 PA13 配置为 GPIO_MODE_AF_PP、GPIO_PULL_UP、GPIO_AF0,PA14 配置为 GPIO_MODE_AF_PP、GPIO_PULL_DOWN、GPIO_AF0;
普通输出状态下 PA13、PA14 一起配置为 GPIO_MODE_OUTPUT_PP、GPIO_NO_AF。
系统时钟 HSI+PLL,N32G412 为 80 MHz,N32G415 为 96 MHz。
程序与数据路径 main 先调用 log_init 并打印 IO remaping demo!,再初始化 LED 与 KEY1 后进入循环:读到 KEY1 为按下电平时点亮 LED1、熄灭 LED2,调用 SWD_As_GPIO_Initialize,随后以 50 ms 间隔用 GPIO_TogglePin 轮流翻转 PA13、PA14,直到 KEY1 松开;
KEY1 未按下时调用 SWD_Function_Initialize,点亮 LED2、熄灭 LED1,并等待 KEY1 再次按下。
主要 API GPIO_InitStruct、GPIO_InitPeripheral、GPIO_ConfigPinRemap、GPIO_ReadInputDataBit、GPIO_TogglePin、GPIO_SetBits、GPIO_ResetBits
验证方法 复位运行后串口打印 IO remaping demo!;
未按 KEY1 时 LED2 常亮;
按住 KEY1 时 LED1 常亮,在 PA13、PA14 上外接 LED 或示波器可看到两脚每 50 ms 轮流翻转。
使用提示 N32G41x 没有 JTAG 接口,只支持 SWD 调试(PA13 为 SWDIO,PA14 为 SWCLK);
下载程序后需取下评估板 J5 上 SWDIO 与 SWCLK 的跳线帽。
按住 KEY1 期间 SWD 不可用。
开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1,芯片支持 N32G412x8L7、N32G412xBL7、N32G415x8L7、N32G415xBL7。
核心代码解读与移植

示例让同一组引脚轮流承担两种角色:KEY1 按下时把 SWD 引脚释放为普通输出,松开时恢复 SWD 复用功能。

数据路径: KEY1(PA4)电平 → GPIO_ReadInputDataBit → SWD_As_GPIO_Initialize 或 SWD_Function_Initialize 改写 PA13、PA14 的模式与复用字段 → GPIO_TogglePin 翻转 PA13、PA14 → 外接 LED 或示波器观察

1. 用宏定义两只 SWD 引脚。 inc/main.h 把 SWDIO 定义为 PA13、SWCLK 定义为 PA14,并把两者的端口时钟都取为 RCC_AHB_PERIPH_GPIO,后续配置都通过这组宏访问引脚。

inc/main.hinc/main.h
/* SWD pin defines */
#define SWDIO_PORT      GPIOA
#define SWDIO_PIN       GPIO_PIN_13
#define SWDIO_CLK       RCC_AHB_PERIPH_GPIO

#define SWCLK_PORT      GPIOA
#define SWCLK_PIN       GPIO_PIN_14
#define SWCLK_CLK       RCC_AHB_PERIPH_GPIO

移植到其它板卡时,SWD 引脚由芯片固定,通常只需改动 bsp/inc/n32g41x_stb.h 里的 LED 与按键定义。

2. 主循环按 KEY1 状态切换角色。 KEY1 按下时先点亮 LED1、熄灭 LED2,再调用释放 SWD 引脚的初始化函数;KEY1 未按下时走另一分支恢复 SWD。

src/main.csrc/main.c · main
    while(1)
    {
        if (GPIO_ReadInputDataBit(BUTTON_KEY1_PORT, BUTTON_KEY1_PIN) == BUTTON_KEY1_STATE)
        {
            /* Turn on Led1 */
            LED_On(LED1_PORT, LED1_PIN);

比较电平用 BUTTON_KEY1_STATE,它由 bsp/inc/n32g41x_stb.h 给出;换板或改按键有效电平时同步改这个宏。

3. 内层循环轮流翻转两只引脚。 释放引脚后在嵌套的 while(1) 里交替翻转 PA13 与 PA14,两次翻转之间各延时 50 ms,并在每轮结束后检查 KEY1 是否松开。

src/main.csrc/main.c · main
                /* Toggle SWDIO pin */
                GPIO_TogglePin(SWDIO_PORT, SWDIO_PIN);
src/main.csrc/main.c · main
                /* Toggle SWCLK pin */
                GPIO_TogglePin(SWCLK_PORT, SWCLK_PIN);

翻转间隔由两次 SysTick_Delay_Ms(50) 决定,调整观察频率时改这两处参数。

4. 释放与恢复 SWD 引脚的两段配置。 SWD_As_GPIO_Initialize 先把 PA13、PA14 的复用字段写为 GPIO_NO_AF,再把两脚一起初始化为推挽输出;SWD_Function_Initialize 反过来把复用字段写为 GPIO_AF0,并按 PA13 上拉、PA14 下拉分别初始化。

src/main.csrc/main.c · SWD_As_GPIO_Initialize
    /* Remap PA13 (SWDIO) and PA14 (SWCLK) to GPIO_NO_AF (release from SWD) */
    GPIO_ConfigPinRemap(GPIOA_PORT_SOURCE, GPIO_PIN_SOURCE15, GPIO_NO_AF);
    GPIO_ConfigPinRemap(GPIOA_PORT_SOURCE, GPIO_PIN_SOURCE14, GPIO_NO_AF);

    /* Configure PA15 and PA14 as gpio output push-pull */
    GPIO_InitStructure.Pin            = SWDIO_PIN | SWCLK_PIN;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_NO_AF;
    GPIO_InitPeripheral(SWDIO_PORT, &GPIO_InitStructure);
src/main.csrc/main.c · SWD_Function_Initialize
    GPIO_InitStructure.Pin            = SWDIO_PIN;
    GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Pull      = GPIO_PULL_UP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF0;
    GPIO_InitPeripheral(SWDIO_PORT, &GPIO_InitStructure);

源码里释放 SWD 的注释写作 Remap PA13 (SWDIO) to AF0、配置输出时又写作 Configure PA15 and PA14,而代码实际传入的引脚源是 GPIO_PIN_SOURCE15 与 GPIO_PIN_SOURCE14,使用的是 GPIO_NO_AF。移植到复用功能映射不同的芯片时,需要同步核对引脚源编号与复用功能编号。

对应源码: inc/main.h、src/main.c

工程目录: projects/n32g41x_EVAL/examples/GPIO/LedBlink/

使能 GPIO 与板级时钟→配置 PA1、PA7、PB1 为推挽输出→LED1 与 LED3 各翻转 4 次→主循环按 LED1、LED2、LED3 顺序轮流点亮

项目 源码解读
功能 用推挽输出控制评估板上的 LED1、LED2、LED3:先让 LED1 与 LED3 一起闪烁 4 次,再按 LED1 → LED2 → LED3 的顺序轮流点亮并循环。
源码组成 src/main.c:LED_Init、LED_On、LED_Off、LED_Blink 四个辅助函数与 main 的闪烁、轮流点亮流程;
inc/main.h:四个函数的声明;
src/n32g41x_it.c、inc/n32g41x_it.h:中断服务函数;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程。
关键配置 LED1 为 PA1、LED2 为 PA7、LED3 为 PB1,LED_Init 中统一配置为 GPIO_MODE_OUTPUT_PP、GPIO_NO_AF、GPIO_NO_PULL、GPIO_SLEW_RATE_FAST、GPIO_DS_HIGH,并调用 RCC_EnableAHBPeriphClk 打开对应端口时钟。
循环用 uint32_t i 从 0 到 7 共 8 次翻转,每次间隔 SysTick_Delay_Ms(500)。
系统时钟 HSI+PLL,N32G412 为 80 MHz,N32G415 为 96 MHz。
程序与数据路径 main 依次调用三次 LED_Init 打开 PA1、PA7、PB1 的时钟并配置为推挽输出,随后在 for 循环里用 LED_Blink 翻转 LED1 与 LED3 并延时 500 ms,共 8 次;
接着用 LED_Off 熄灭三路 LED,最后在 while (1) 里按 LED1、LED2、LED3 的顺序点亮,每次点亮都熄灭上一路并延时 500 ms。
主要 API GPIO_InitStruct、GPIO_InitPeripheral、GPIO_SetBits、GPIO_ResetBits、GPIO_TogglePin;
时钟使能 RCC_EnableAHBPeriphClk,延时 SysTick_Delay_Ms
验证方法 复位运行后 LED1 与 LED3 同时闪烁 4 次,随后 LED1、LED2、LED3 依次点亮并循环;
以 500 ms 的节奏观察即可判断翻转与轮流点亮全部生效。
使用提示 开发环境为 KEIL MDK-ARM V5.34 或 IAR EWARM 8.50.1,芯片支持 N32G412x8L7、N32G412xBL7、N32G415x8L7、N32G415xBL7;
LED 与引脚对应关系取自评估板定义,换板时需要同步修改。
核心代码解读与移植

示例用三个辅助函数把引脚配置、点亮、熄灭与翻转封装起来,主程序只负责编排闪烁与轮流点亮的次序。

数据路径: main → LED_Init → RCC_EnableAHBPeriphClk 打开端口时钟、GPIO_InitPeripheral 写入 PA1/PA7/PB1 的输出模式 → LED_Blink/LED_On/LED_Off → GPIO_TogglePin/GPIO_SetBits/GPIO_ResetBits → 引脚电平 → LED 亮灭

1. 逐个初始化三路 LED。 main 开头对三路 LED 各调用一次 LED_Init,分别传入自己的端口、引脚与时钟宏。

src/main.csrc/main.c · main
    /* LED port init */
    LED_Init(LED1_PORT, LED1_PIN, LED1_CLOCK);
    LED_Init(LED2_PORT, LED2_PIN, LED2_CLOCK);
    LED_Init(LED3_PORT, LED3_PIN, LED3_CLOCK);

三个端口与引脚来自 bsp/inc/n32g41x_stb.h;换板时改这组宏即可,主程序与辅助函数不用动。

2. 先让两路 LED 闪烁 4 次。 for 循环从 0 到 7 共 8 次,每轮翻转 LED1 与 LED3 后延时 500 ms,因此表现为“闪烁 4 次”。

src/main.csrc/main.c · main
    /* LED1 and LED3 blink 4 times */
    for(i=0;i<8;i++)
    {
        LED_Blink(LED1_PORT, LED1_PIN);
        LED_Blink(LED3_PORT, LED3_PIN);
        SysTick_Delay_Ms(500);
    }

闪烁次数由循环上界 8 决定,节奏由 SysTick_Delay_Ms(500) 决定,改观察效果时同步调整这两处。

3. 主循环按顺序轮流点亮。 进入 while (1) 后先熄灭 LED3 再点亮 LED1,然后每轮熄灭上一路、点亮下一路,各延时 500 ms。

src/main.csrc/main.c · main
        /* Turn on LED1 and turn off LED3*/
        LED_Off(LED3_PORT, LED3_PIN);
        LED_On(LED1_PORT, LED1_PIN);
        SysTick_Delay_Ms(500);
src/main.csrc/main.c · main
        /* Turn on LED2 and turn off LED1*/
        LED_Off(LED1_PORT, LED1_PIN);
        LED_On(LED2_PORT, LED2_PIN);
        SysTick_Delay_Ms(500);
src/main.csrc/main.c · main
        /* Turn on LED3 and turn off LED2 */
        LED_Off(LED2_PORT, LED2_PIN);
        LED_On(LED3_PORT, LED3_PIN);
        SysTick_Delay_Ms(500);

轮流点亮的顺序就是这三段的先后次序,增加或调换 LED 时按同样方式追加一段。

4. 初始化函数把参数写进 GPIO_InitType。 LED_Init 先用 GPIO_InitStruct 取默认值,再逐项填入引脚与输出参数,最后交给 GPIO_InitPeripheral 写入寄存器。

src/main.csrc/main.c · LED_Init
    /* Init GPIO as output push-pull mode */
    InitStruct.Pin            = Pin;
    InitStruct.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
    InitStruct.GPIO_Mode      = GPIO_MODE_OUTPUT_PP;
    InitStruct.GPIO_Alternate = GPIO_NO_AF;
    InitStruct.GPIO_Pull      = GPIO_NO_PULL;
    InitStruct.GPIO_Current   = GPIO_DS_HIGH;

翻转率、驱动能力与上下拉都在这段里给定,换成开漏输出或需要上拉时改 InitStruct.GPIO_Mode 与 InitStruct.GPIO_Pull。

对应源码: src/main.c、inc/main.h、projects/n32g41x_EVAL/bsp/inc/n32g41x_stb.h

5.10.4 注意与排障

场景 检查与建议 来源
I/O 端口寄存器的访问宽度 每个 I/O 端口位可以任意编程,但必须按 32 位字访问 I/O 端口寄存器,不允许 16 位半字或 8 位字节访问。 用户手册
逐位改变输出而不影响其它位 向位设置/清除寄存器 GPIOx_PBSC 和位清除寄存器 GPIOx_PBC 中要改变的位写 1 即可单独置位或清除,未写入 1 的位保持不变,单次 AHB 写操作完成,软件不需要禁止中断。 用户手册
引脚配置被意外改写 锁定机制在某个端口位上执行 LOCK 序列后,到下一次复位之前不能再更改该引脚配置;
PLOCKK 只有在按 w1→w0→w1→r0 序列操作后才置 1,序列过程中 PLOCK[15:0] 不能改变,序列出错必须重做。
用户手册
用了复用功能却没有输出 端口配置为复用功能模式时,使用前必须对端口位配置寄存器 GPIOx_AFL/GPIOx_AFH 和输出类型寄存器 GPIOx_POTYPE(推挽或开漏)编程;
复用输入或输出由外设决定。
用户手册
翻转率配置位并非每个端口都有 翻转率配置位不是每个端口齐全:GPIOB 上只有 SR5、SR6、SR7,GPIOA 上只有 SR0、SR1、SR2,GPIOC、GPIOD 上没有这些位。 用户手册
SPI NSS 处于 AFIO 推挽模式 GPIOx_AFH 中的 SPI1_NSS、SPI2_NSS 位在对应 SPI 作为从机时必须配置为 0,即 NSS 空闲时为高阻态。 用户手册
IO 滤波时间的时钟来源 IO 滤波时间以 HCLK 分频后的时钟为周期,分频值由 RCC 的 GPIOFCLKDIV 配置,改滤波档位时要一并核对这个分频。 用户手册

N32G412、N32G415 系列勘误手册 V1.0.0(2026.6.30)的勘误列表只列出一行 A 版芯片条目且勘误链接列为空,未列出 GPIO 相关条目。

国民技术开发套件文档中心

按芯片系列在线查阅国民技术 MCU 开发套件的芯片资料、SDK、驱动 API 与 Demo 示例说明。

© 2026 国民技术股份有限公司 版权所有粤ICP备11069485号本站使用不含 Cookie 的匿名访问统计