GD32F103学习笔记——GPIO接口使用

Posted Leung_ManWah

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GD32F103学习笔记——GPIO接口使用相关的知识,希望对你有一定的参考价值。

一、简介

最多可支持112个通用I/O引脚(GPIO),分别为PA0 ~ PA15,PB0 ~ PB15,PC0 ~ PC15,PD0 ~ PD15,PE0 ~ PE15,PF0 ~ PF15和PG0 ~ PG15,各片上设备用其来实现逻辑输入/输出功能。每个GPIO端口有相关的控制和配置寄存器以满足特定应用的需求。外设GPIO引脚上的外部中断在中断/事件控制器(EXTI)中有相关的控制和配置寄存器。GPIO端口和其他的备用功能(AFs)共用引脚,在特定的封装下获得最大的灵活性。GPIO引脚通过配置相关的寄存器可以用作备用功能引脚,备用功能输入/输出都可。每个GPIO引脚可以由软件配置为输出(推挽或开漏)、输入、外设的备用功能或者模拟模式。每个GPIO引脚都可以配置为上拉、下拉或无上拉/下拉。 除模拟模式外,所有的GPIO引脚都具备大电流驱动能力。

二、API说明

2.1 外设寄存器说明

GPIO寄存器列表如下表所示:

寄存器名称寄存器描述
GPIOx_CTL0端口控制寄存器0
GPIOx_CTL1端口控制寄存器1
GPIOx_ISTAT端口输入状态寄存器
GPIOx_OCTL端口输出状态寄存器
GPIOx_BOP端口位操作寄存器
GPIOx_BC位清除寄存器
GPIOx_LOCK端口配置锁定寄存器
AFIO_EC事件控制寄存器
AFIO_PCF0AFIO端口配置寄存器0
AFIO_EXTISS0EXTI源选择寄存器0
AFIO_EXTISS1EXTI源选择寄存器1
AFIO_EXTISS2EXTI源选择寄存器2
AFIO_EXTISS3EXTI源选择寄存器3
AFIO_PCF1AFIO端口配置寄存器1

2.2 外设库函数说明

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

2.2.1 gpio_init

功能GPIO参数初始化。注意:首先要保证使用的GPIO的时钟开启
函数定义void gpio_init(uint32_t gpio_periph,uint32_t mode,uint32_t speed,uint32_t pin)
参数gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
mode:GPIO引脚模式
speed:GPIO输出最大速度最大
pin:GPIO引脚x(x=0…15)
返回

mode: IO模式,在GD32标准固件库中,共有四种输入模式,四种输出模式,详细列表如下:

含义官方解释
GPIO_MODE_AIN模拟输入analog input mode
GPIO_MODE_IN_FLOATING浮空输入floating input mode
GPIO_MODE_IPD下拉输入pull-down input mode
GPIO_MODE_IPU上拉输入pull-up input mode
GPIO_MODE_OUT_OD开漏输出GPIO output with open-drain
GPIO_MODE_OUT_PP推挽输出GPIO output with push-pull
GPIO_MODE_OUT_OD复用开漏输出AFIO output with open-drain
GPIO_MODE_OUT_PP复用推挽输出AFIO output with push-pull

speed: IO输出速度最大值,详细列表如下:

含义官方解释
GPIO_OSPEED_10MHZ输出速度最大为10MHzoutput max speed 10MHz
GPIO_OSPEED_2MHZ输出速度最大为2MHzoutput max speed 2MHz
GPIO_OSPEED_50MHZ输出速度最大为50MHzoutput max speed 50MHz

2.2.2 gpio_bit_set

功能将一个GPIO引脚拉高
函数定义void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)
参数gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
pin:GPIO引脚x(x=0…15)
返回

2.2.3 gpio_bit_reset

功能将一个GPIO引脚拉低
函数定义void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin)
参数gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
pin:GPIO引脚x(x=0…15)
返回

2.2.4 gpio_bit_write

功能将特定值写入引脚
函数定义void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value)
参数gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
pin:GPIO引脚x(x=0…15)
bit_value:SET设置或RESET清除
返回

2.2.5 gpio_input_bit_get

功能获取引脚的输入值
函数定义FlagStatus gpio_input_bit_get(uint32_t gpio_periph,uint32_t pin)
参数gpio_periph:GPIO端口x(x = A,B,C,D,E,F,G)
pin:GPIO引脚x(x=0…15)
返回SET高电平或RESET低电平

2.2.6 gpio_pin_remap_config

功能配置GPIO引脚重映射
函数定义void gpio_pin_remap_config(uint32_t remap, ControlStatus newvalue)
参数remap:选择重映射
newvalue:是否使能,ENABLE使能或DISABLE除能
返回

remap: 重映射,详细列表如下:

含义
GPIO_SPI0_REMAPSPI0重映射
GPIO_I2C0_REMAPI2C0重映射
GPIO_USART0_REMAPUSART0重映射
GPIO_USART1_REMAPUSART1重映射
GPIO_USART2_PARTIAL_REMAPUSART2部分重映射
GPIO_USART2_FULL_REMAPUSART2全部重映射
GPIO_TIMER0_PARTIAL_REMAPTIMER0部分重映射
GPIO_TIMER0_FULL_REMAPTIMER0全部重映射
GPIO_TIMER1_PARTIAL_REMAP0TIMER1部分重映射
GPIO_TIMER1_PARTIAL_REMAP1TIMER1部分重映射
GPIO_TIMER1_FULL_REMAPTIMER1全部重映射
GPIO_TIMER2_PARTIAL_REMAPTIMER2部分重映射
GPIO_TIMER2_FULL_REMAPTIMER2全部重映射
GPIO_TIMER3_REMAPTIMER3重映射
GPIO_PD01_REMAPPD01重映射
GPIO_CAN_PARTIAL_REMAPCAN部分重映射(仅适用于GD32F10X_MD,GD32F10X_HD和GD32F10X_XD)
GPIO_CAN_FULL_REMAPCAN全部重映射(仅适用于GD32F10X_MD,GD32F10X_HD和GD32F10X_XD)
GPIO_SPI2_REMAPSPI2重映射(仅适用于GD32F10X_CL)
GPIO_TIMER4CH3_IREMAPTIMER4 channel3内部重映射(仅适用于GD32F10X_CL和GD32F10X_HD)
GPIO_ADC0_ETRGINS_REMAPADC0外部触发注入转换重映射(仅适用于GD32F10X_MD,GD32F10X_HD和GD32F10X_XD)
GPIO_ADC0_ETRGREG_REMAPADC0外部触发规则转换重映射(仅适用于GD32F10X_MD,GD32F10X_HD和GD32F10X_XD)
GPIO_ADC1_ETRGINS_REMAPADC1外部触发注入转换重映射(仅适用于GD32F10X_MD,GD32F10X_HD和GD32F10X_XD)
GPIO_ADC1_ETRGREG_REMAPADC1外部触发规则转换重映射(仅适用于GD32F10X_MD,GD32F10X_HD和GD32F10X_XD)
GPIO_SWJ_NONJTRST_REMAP全部的SWJ(JTAG-DP + SW-DP),但是不包括NJTRST
GPIO_SWJ_SWDPENABLE_REMAPJTAG-DP除能,SW-DP使能
GPIO_SWJ_DISABLE_REMAPJTAG-DP除能,SW-DP除能
GPIO_CAN0_PARTIAL_REMAPCAN0部分重映射(仅适用于GD32F10X_CL)
GPIO_CAN0_FULL_REMAPCAN0全部重映射(仅适用于GD32F10X_CL)
GPIO_ENET_REMAPENET重映射(仅适用于GD32F10X_CL)
GPIO_CAN1_REMAPCAN0重映射(仅适用于GD32F10X_CL)
GPIO_TIMER1ITI1_REMAPTIMER1内部触发1重映射(仅适用于GD32F10X_CL)
GPIO_PTP_PPS_REMAP以太网PTP PPS重映射(仅适用于GD32F10X_CL)
GPIO_TIMER8_REMAPTIMER8重映射
GPIO_TIMER9_REMAPTIMER9重映射
GPIO_TIMER10_REMAPTIMER10重映射
GPIO_TIMER12_REMAPTIMER12重映射
GPIO_TIMER13_REMAPTIMER13重映射
GPIO_EXMC_NADV_REMAPEXMC_NADV 连接/断开

三、GPIO输出

3.1 引脚确定

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

有个 IO 口为 PB4 的 LED 灯

在复位期间或复位之后,备用功能并未激活,所有GPIO端口都被配置成输入浮空模式,这种输入模式禁用上拉(PU)/下拉(PD)电阻。但是复位后,串行线调试端口(JTAG/Serial-Wired Debug pins)为输入PU/PD模式:
PA15:JTDI为上拉模式;
PA14:JTCK / SWCLK为下拉模式;
PA13:JTMS / SWDIO为上拉模式;
PB4:NJTRST为上拉模式;
PB3:JTDO为浮空模式。

所以PB4要当GPIO需要重映射

//管脚复用时钟使能
rcu_periph_clock_enable(RCU_AF);
//PB4管脚默认是NJTRST,要当GPIO,需要重映射
gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP, ENABLE)

3.2 编程要点

  1. 使能 GPIO 端口时钟
  2. 初始化 GPIO 目标引脚为推挽输出
  3. 控制 GPIO 引脚输出高、低电平

3.3 外设寄存器方法

//GPIOB时钟使能
rcu_periph_clock_enable(RCU_GPIOB);
//配置GPIO端口
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);

//引脚输出低电平
GPIO_BC(GPIOB) = GPIO_PIN_4;
//引脚输出高电平
GPIO_BOP(GPIOB) = GPIO_PIN_4;

3.4 外设库函数方法

//GPIOB时钟使能
rcu_periph_clock_enable(RCU_GPIOB);
//PB4配置成输出
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);

//引脚输出低电平
gpio_bit_reset(GPIOB, GPIO_PIN_4);
//引脚输出高电平
gpio_bit_set(GPIOB, GPIO_PIN_4);
//引脚输出低电平
gpio_bit_write(GPIOB, GPIO_PIN_4, RESET);
//引脚输出高电平
gpio_bit_write(GPIOB, GPIO_PIN_4, SET);

四、GPIO输入

4.1 引脚确定

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

有个 IO 口为 PA1 的按键

4.2 编程要点

  1. 使能 GPIO 端口时钟
  2. 初始化 GPIO 目标引脚为输入模式(由于硬件电路没有外部上拉电阻,这里使用内部上拉输入)
  3. 检测按键的状态

4.3 外设库函数方法

//GPIOA时钟使能
rcu_periph_clock_enable(RCU_GPIOA);
//PA1配置成上拉输入
gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_1);

//读取引脚电平
gpio_input_bit_get(GPIOA, GPIO_PIN_1);

五、轮询读取按下按键,LED灯闪烁

5.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;

5.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_ */

5.3 main.c

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

#include "board_gpio.h"

int main(void)

    systick_config();//系统主频108MHZ,采用外部晶振,由两个宏决定(__SYSTEM_CLOCK_108M_PLL_HXTAL与HXTAL_VALUE)
    
    Key_GPIO_Init();// 按键模块初始化
    LED_GPIO_Init();// LED灯模块初始化
	
    while(1)
    
        if(KEY_ON == Key_GPIO_Read(KEY1))
        
            delay_1ms(100);//等待100ms
            LED_GPIO_Write(LED1, LED_ON);
            delay_1ms(100);//等待100ms
            LED_GPIO_Write(LED1, LED_OFF);
        
    

5.4 工程代码

百度网盘:https://pan.baidu.com/s/1_tjTeP_xVNC-KdVDLbN-Ww?pwd=0h8m 提取码:0h8m


• 由 Leung 写于 2022 年 4 月 12 日

• 参考:GD32F103基础教程—GPIO输出实验(五)
    GD32实战3__点亮LED灯

以上是关于GD32F103学习笔记——GPIO接口使用的主要内容,如果未能解决你的问题,请参考以下文章

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

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

GD32F103学习笔记——在GD32F103移植STM32F103代码

GD32F103学习笔记——在GD32F103移植STM32F103代码

GD32F103学习笔记——USART串口使用

GD32F103学习笔记——USART串口使用