2.GPIO 模块介绍
GPIO的全称为通用输入输出口,是很多外设能够正常工作的必要条件。除了一些特定功能的引脚(如电源脚)外,MCU上其他的引脚都可以当做GPIO来使用。本章,我们将对GPIO进行简单介绍,并通过一个“流水灯”的实验来熟悉GPIO的工作模式。
2.1.GPIO 基础知识
GD32系列MCU的GPIO口是以“组”的形式工作,命名方式为PX(X=A,B,C,D,E···),每组配置有16个pin脚。每个pin脚都可由软件配置为输出(推挽或开漏)、输入、外设备用功能或者模拟模式。每个 GPIO 引脚都可以配置为上拉、下拉或浮空。除模拟模式外,所有的 GPIO 引脚都具备大电流驱动能力。
GPIO的主要特性
◼ 输入/输出方向控制;
◼ 施密特触发器输入功能使能控制;
◼ 每个引脚都具有弱上拉/下拉功能;
◼ 推挽/开漏输出使能控制;
◼ 置位/复位输出使能;
◼ 可编程触发沿的外部中断—使用EXTI配置寄存器;
◼ 模拟输入/输出配置;
◼ 备用功能输入/输出配置;
◼ 端口锁定配置;
◼ 单周期输出翻转功能;
GPIO结构框图
如图所示为标准I/O端口位的基本结构图。
GPIO引脚配置
在复位期间或复位之后,备用功能并未激活,所有GPIO端口都被配置成输入浮空模式,这种输入模式禁用上拉(PU)/下拉(PD)电阻。用户可通过软件配置GPIO为输入或输出模式。当 GPIO引脚配置为输入引脚时,所有的GPIO引脚内部都有一个可选择的弱上拉和弱下拉电阻。当GPIO引脚配置为输出引脚,用户可以配置端口的输出速度和选择输出驱动模式:推挽或开漏模式。
输入配置
当GPIO引脚配置为输入时:
◼ 施密特触发输入使能;
◼ 可选择的弱上拉和下拉电阻;
◼ 当前I/O引脚上的数据在每个APB2时钟周期都会被采样并存入端口输入状态寄存器;
◼ 输出缓冲器禁用。 如图为输入配置是I/O引脚的输入配置。
输出配置
当GPIO引脚配置为输出时:
◼ 施密特触发输入使能;
◼ 弱上拉和下拉电阻禁用;
◼ 输出缓冲器使能;
◼ 开漏模式:输出控制寄存器设置为“0”时,相应引脚输出低电平;输出控制寄存器设置为“1”,相应管脚处于高阻状态;
◼ 推挽模式:输出控制寄存器设置为“0”时,相应引脚输出低电平;输出控制寄存器设置为“1”,相应引脚输出高电平;
◼ 对端口输出控制寄存器进行读操作,将返回上次写入的值;
◼ 对端口输入状态寄存器进行读操作,将获得当前I/O口的状态。
如图为I/O端口的输出配置
模拟配置
当GPIO引脚配置为模拟模式时:
◼ 弱上拉和下拉电阻禁用;
◼ 输出缓冲器禁用;
◼ 施密特触发输入禁用;
◼ 端口输入状态寄存器相应位为“0”。
如图为I/O端口的输出配置
2.2.备用功能(AF)
除了用作通用 IO 口以外,所有的 GPIO 都有备用功能。
对于 GD32F10x/20x/30x/403/E10x/E50x/A501/VF103 系列 MCU,用户可通过软件将某一个 GPIO配置为复用模式,然后再使能相应外设即可使用 IO 对应的复用功能。
对于 GD32F1x0/3x0/4xx/E23x/A501 系列 MCU,用户可通过软件将某一个 GPIO 配置为复用模式,同时还需要设置 GPIO 备用功能选择寄存器选择 16 个备用功能中的一个。以 GD32F130 为例,说下具体的配置流程。
(1) 设置 GPIO 模式 gpio_mode_setgpio_mode_set函数原型为:
void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin)
{
xxx
xxx
}
其中形参gpio_periph为需要设置的GPIO口组,其对应的实参为GPIOx(x = A,B,C,D,E,F,G),形参mode为需要设置的GPIO模式,对应的实参为:
GPIO_MODE_INPUT(输入模式)
GPIO_MODE_OUTPUT(输出模式)
GPIO_MODE_AF(复用模式)
GPIO_MODE_ANALOG(模拟模式)
形参pull_up_down为GPIO的上下拉设置,对应的实参为:
GPIO_PUPD_NONE(无上下拉)
GPIO_PUPD_PULLUP(上拉)
GPIO_PUPD_PULLDOWN(下拉)
形参pin为pin脚号,实参为GPIO_PIN_x(x=0..15)。
(2) 设置 AF 类型 gpio_af_set
当需要将GPIO设置为复用模式时,除了调用gpio_mode_se设置GPIO模式外,还需要调用函数gpio_af_set进行复用类型的设置。gpio_af_set函数原型为:
void gpio_mode_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin)
{
xxx
xxx
}
其中形参gpio_periph为需要设置的GPIO口组,其对应的实参为GPIOx(x = A,B,C,D,E,F,G),形参alt_func_num为需要设置复用类型,对应的实参为:
GPIO_AF_0(复用类型0)
GPIO_AF_1(复用类型1)
GPIO_AF_2(复用类型2)
GPIO_AF_3(复用类型3)
GPIO_AF_4(复用类型4)
GPIO_AF_5(复用类型5)
GPIO_AF_6(复用类型6)
GPIO_AF_7(复用类型7)
F1x0、F3x0、F4xx(F405\F407\F450)、E23x系列MCU的GPIO的复用类型可以从对应MCU的 Datasheet中查得,如GD32F130系列的复用类型表如下图(部分截图):
形参pin为pin脚号,实参为GPIO_PIN_x(x=0..15)。
根据以上介绍,如设置PA0为复用模式,且设置功能为USART0_CTS功能,函数调用如下:
gpio_mode_set(GPIOA,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_0);
gpio_af_set (GPIOA,GPIO_AF_1,GPIO_PIN_0);
2.3.I/O 重映射功能
本节内容只适用于GD32F10x/30x/403/E103/E50x/A501/VF103系列MCU。
介绍
为了扩展 GPIO 的 灵 活 性 或 外 设 功 能 使 用 , 通 过 配 置 AFIO 端 口 配 置 寄 存 器(AFIO_PCF0/AFIO_PCF1),每个I/O引脚都可以配置多达4种不同的功能。通过使用外设 IO 的重映射功能可以选择合适的引脚另外,通过配置相应的EXTI源选择寄存器(AFIO_EXTISSx)选择触发中断或事件,GPIO引脚可以用作EXTI中断线。
主要特性
◼ EXTI 源选择
◼ 每个引脚具有多达4种备用功能的配置外设重映射配置以GD32F30x的USART0 AF重映射来说明重映射配置。
由上表可看出,当 USART0_REMAP = 0 时 ,USART0_TX 和USART0_RX 功 能 映 射 在 PA9 、 PA10 上 ,而当 USART0_REMAP = 1 时 ,USART0_TX和USART0_RX功能映射在PB6、PB7上。
其他外设端口重映射或其他系列MCU重映射表,请参考各系列MCU的User Manual。
JTAG/SWD 备用功能重映射
调试接口信号映射在 GPIO 端口的情况下表所示。
为了减少用于调试的 GPIO 端口,用户可以配置 AFIO_PCF0 寄存器中的 SWJ_CFG [2:0]位为不同的值。具体情况参照下表调试端口映射。
注意:当JTAG或SWD定义的IO口被用户设置为其他功能时,需要根据此表将JTAG或SWD功能关闭,否则可能会出现MCU无法运行的情况。
2.4.硬件连接说明
本章以一个“流水灯”的实验来熟悉GPIO的工作模式。
“流水灯”实验硬件连接图
如实验硬件连接图所示,LED2、LED3通过470Ω电阻和MCU的PF0、PF1连接,另一端接GND,可通过配置PF0、PF1的输出电平,来达到控制LED2、LED3亮灭的目的。
读者可以根据典型硬件连接图和相应系列的Datasheet设计出自己的硬件连接方式。
2.5.软件配置说明
本小节讲解GPIO_Example例程中GPIO的配置说明,主要包括外设时钟配置、GPIO引脚配置、主函数介绍以及运行结果。
软件设计的流程如下:
(1) 使能GPIOF时钟
(2) 初始化PF0和PF1,将这两个引脚配置为推挽输出
(3) 通过调用库函数配置PF0和PF1的电平,再通过一些延时处理,使LED2和LED3交替点亮,以实现流水灯
外设时钟配置
外设时钟配置如代码清单GPIO例程时钟配置所示,在GD32全系列MCU中需打开GPIOF时钟。
void rcu_config(void)
{
/* enable the led clock */
rcu_periph_clock_enable(RCU_GPIOF);
}
GPIO 引脚配置
代码清单 0-9.GPIO 例程引脚配置
void gpio_config(void)
{
/* configure led GPIO port */
#if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X
gpio_init(GPIOF, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
gpio_init(GPIOF, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
#elif GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E23X
gpio_mode_set(GPIOF,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_0);
gpio_mode_set(GPIOF,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_1);
gpio_output_options_set(GPIOF,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
gpio_output_options_set(GPIOF,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_1);
#endif
}
如代码清单GPIO例程引脚配置 ,GD32F10X、GD32F30X、GD32F20X、GD32E10X系列GPIO配置为推挽输出相同,调用gpio_init函数(由标准库提供)即可,此函数原型为:
void gpio_init(uint32_t gpio_periph, uint32_t mode, uint32_t speed, uint32_t pin)
{
xxx
xxx
}
其中形参gpio_periph为需要设置的GPIO口组,其对应的实参为GPIOx(x = A,B,C,D,E,F,G),形参mode为需要设置的GPIO模式,对应的实参为:
GPIO_MODE_AIN(模拟输入)
GPIO_MODE_IN_FLOATING(浮空输入)
GPIO_MODE_IPD(下拉输入)
GPIO_MODE_IPU(上拉输入)
GPIO_MODE_OUT_OD(开漏输出)
GPIO_MODE_OUT_PP(推挽输出)
GPIO_MODE_AF_OD(复用开漏输出)
GPIO_MODE_AF_PP(复用推挽输出)
形参speed为GPIO的速度设置,对应的实参为:
GPIO_OSPEED_2MHZ
GPIO_OSPEED_10MHZ
GPIO_OSPEED_50MHZ
GPIO_OSPEED_MAX(只有部分系列 MCU 的 GPIO 支持大于 50MHz)
形参pin为pin脚号,实参为GPIO_PIN_x(x=0..15)。
实际上GPIO的速度设置只在设置为输出模式下才有效,输入模式下是无效的。
如代码清单GPIO例程引脚配置 ,F1x0、F4xx、F3x0、E23x系列GPIO配置为推挽输出相同,需调用gpio_mode_set和gpio_output_options_set函数。
(1) gpio_mode_set函数
gpio_mode_set函数原型为:
void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin)
{
xxx
xxx
}
其中形参gpio_periph为需要设置的GPIO口组,其对应的实参为GPIOx(x = A,B,C,D,E,F,G),形参mode为需要设置的GPIO模式,对应的实参为:
GPIO_MODE_INPUT(输入模式)
GPIO_MODE_OUTPUT(输出模式)
GPIO_MODE_AF(复用模式)
GPIO_MODE_ANALOG(模拟模式)
形参pull_up_down为GPIO的上下拉设置,对应的实参为:
GPIO_PUPD_NONE(无上下拉)
GPIO_PUPD_PULLUP(上拉)
GPIO_PUPD_PULLDOWN(下拉)
形参pin为pin脚号,实参为GPIO_PIN_x(x=0..15)。
(2) gpio_output_options_set函数
当需要将GPIO设置为输出模式时,除了调用gpio_mode_set设置GPIO模式外,还需要调用函数gpio_output_options_set进行GPIO的速度及输出类型的设置。gpio_output_options_set函数原型为:
void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin)
{
xxx
xxx
}
其中形参gpio_periph为需要设置的GPIO口组,其对应的实参为GPIOx(x = A,B,C,D,E,F,G),形参otype为需要设置的GPIO输出类型,对应的实参为:
GPIO_OTYPE_PP(推挽模式)
GPIO_OTYPE_OD(开漏模式)
形参speed为引脚速度,实参为:
GPIO_OSPEED_2MHZ
GPIO_OSPEED_10MHZ
GPIO_OSPEED_50MHZ
GPIO_OSPEED_MAX(只有部分系列 MCU 的 GPIO 支持大于 50MHz)
形参pin为pin脚号,实参为GPIO_PIN_x(x=0..15)。
主函数说明
代码清单 GPIO 例程主函数
int main(void)
{
systick_config();
rcu_config();
gpio_config();
GPIO_BC(GPIOF) = GPIO_PIN_0;
GPIO_BC(GPIOF) = GPIO_PIN_1;
while(1){
/* turn on led2, turn off led3 */
GPIO_BC(GPIOF) = GPIO_PIN_0;
GPIO_BOP(GPIOF) = GPIO_PIN_1;
delay_1ms(1000);
/* turn on led3, turn off led2 */
GPIO_BC(GPIOF) = GPIO_PIN_1;
GPIO_BOP(GPIOF) = GPIO_PIN_0;
delay_1ms(1000);
}
}
如代码清单 GPIO 例程主函数,该主函数主要分成四部分,systick 配置、RCU 时钟配置、GPIO 配置和 while(1)主循环,其中 systick 配置用于产生延时,while(1)主循环通过控制相应 GPIO 的 BC 和 BOP 寄存器来控制 GPIO 的输出电平。
运行结果
2.6.GPIO 使用注意事项
-
当出现在调试状态下程序可运行,但run模式下MCU无法启动,需要查看是否使用了JTAG口定义的IO,用户需要在程序中将JTAG口功能屏蔽,具体请参考2.3节。
-
当JTAG和SWD功能都被禁用后,MCU将无法通过仿真器连接。
本章内容每日持续更新,如有兴趣,请关注收藏
更多GD32 MCU相关咨询:https://www.gd32bbs.com/