目录
- GPIO模式
- 模拟
- 浮空输入
- 下拉输入
- 上拉输入
- 推挽
- 开漏
- 例程
- 点亮LED
- 按钮检测
GPIO全称为通用输入输出接口(General Purpose Input Output),是单片机中必不可少的外设,它控制这单片机的IO管脚,无论使用什么通信协议,如SPI、I2C都需要对GPIO进行初始化。
GPIO模式
GD32的GPIO模式一共有6种,下面结合原理图详细解释。
模拟
下面是模拟模式的框图。
在模拟模式,单片机需要接收或发送模拟信号,因此电路中不需要任何去噪的电路,因此可以简单理解为就一条直线连接到单片机对应管脚。
这时,弱上拉和下拉电阻禁用;输出缓冲器禁用;施密特触发输入禁用;端口输入状态寄存器相应位为“0”。
浮空输入
下面是GD32输入结构的框图,浮空输入、下拉输入、上拉输入都是同样的框图。
当单片机管脚处于浮空输入,输入电路中的上拉和下拉电阻被禁用,施密特触发器使能,可以理解为管脚上为高或低电平,单片机就接收到高或低电平。
下拉输入
当单片机处于下拉输入,输入电路中的下拉电阻使能,施密特触发器使能。当管脚接上了线时,它的作用是和浮空输入一样的;但当管脚悬空时,管脚电平会被下拉至低电平,此时单片机只能接收到低电平。
上拉输入
当单片机处于上拉输入,输入电路中的上拉电阻使能,施密特触发器使能。现象和下拉输入是相反的,就是当管脚悬空时,管脚电平会被上拉至高电平,此时单片机只能接收到高电平。
推挽
下面是GD32输出结构的框图,推挽和开漏都是同样的框图。
当GPIO配置为输出模式时,统一禁用上拉和下拉电阻,使能施密特触发器,使能输出缓冲区。
当处于推挽模式时,输出控制寄存器设置为“0”时,相应引脚输出低电平;输出控制寄存器设置为“1”,相应引脚输出高电平。
开漏
当处于开漏模式时,输出控制寄存器设置为“0”时,相应引脚输出低电平;输出控制寄存器设置为“1”,相应管脚处于高阻状态。
大家可能注意到,单片机的几乎每个模式都离不开施密特触发器这个东西,所以在这里简单解释一下,施密特触发器的作用。
施密特触发器在GPIO中的作用主要是波形变换和整波,因为有电磁干扰或电路中有噪声的时候,那么经过GPIO管脚的电压就可能会不稳定,即上下起伏的;经过施密特触发器后,起伏的信号会被规整为矩形波,便于单片机识别高低电平信号。
例程
点亮LED
具体的现象为开发板上对应的LED闪烁。
#include "gd32f10x.h"
#include "main.h"
void delay(__IO uint32_t ms) // 随便写一个软件延时函数,不准确的,在例程中能用就行
{
for(uint32_t i = 0; i < ms; ++i)
{
for(uint32_t j = 0; j < 10000; ++j)
{
}
}
}
int main(void)
{
rcu_periph_clock_enable(RCU_GPIOC); // 初始化GPIO口的时钟
// 初始化GPIO引脚,使能PC13引脚,速度为50MHz,模式为推挽输出
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
while(1)
{
gpio_bit_write(GPIOC, GPIO_PIN_13, SET); // PC13引脚高电平
delay(1000);
gpio_bit_write(GPIOC, GPIO_PIN_13, RESET); // PC13引脚低电平
delay(1000);
}
}
说明:
对GPIO管脚写“1”不一定就是亮灯,有可能是灭灯,写“0”反之;这个是根据单片机的设计时的原理图决定的。
GD32为GPIO管脚提供了3种时钟速率——50MHz、10MHz、2MHz,一般来说没有特殊要求一般选择最高速率;有一些情况下,如使用SPI与ESP32进行通信时,速率就不能选最高,因为ESP32在SPI模式下的GPIO管脚承受不住50MHz的速度,这个我们后面遇到再详细说。
按钮检测
现象为,当我们按下开关时,LED灯亮;当我们松开开关时,LED灯灭。
#include "gd32f10x.h"
#include "main.h"
int main(void)
{
rcu_periph_clock_enable(RCU_GPIOC); // 初始化GPIO口的时钟
// 初始化GPIO引脚,使能PC13引脚,速度为50MHz,模式为推挽输出
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
rcu_periph_clock_enable(RCU_GPIOA); // 初始化GPIO口的时钟
// 初始化GPIO引脚,使能PA0引脚,速度为50MHz,模式为浮空输入
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
while(1)
{
if(gpio_input_bit_get(GPIOA, GPIO_PIN_0) == SET) // 获取对应管脚的电平值
{
gpio_bit_write(GPIOC, GPIO_PIN_13, SET); // 亮灯
}
else
{
gpio_bit_write(GPIOC, GPIO_PIN_13, RESET); // 灭灯
}
}
}
说明:
在设计按钮检测代码时需查看开发板的原理图里面按钮模块的设计,一般按钮在按下时会产生抖动,所以在设计开发板时会用RC电路进行包裹,实现硬件消抖;但如果在开发板设计之初没有考虑这个问题,那么就需要在代码中添加消抖代码,实现软件消抖。