【GD32】从0开始学GD32单片机(3)—— 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电路进行包裹,实现硬件消抖;但如果在开发板设计之初没有考虑这个问题,那么就需要在代码中添加消抖代码,实现软件消抖。

  • 14
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
GD32F103ZET6开发板PDF原理图+硬件用户手册+软件Demo源码资料,01_Running_LED 02_SysTick_LED 03_USART1_Print 04_USART2_Print 05_I2C_EEPROM 06_SPI_SPI-Flash 07_RTC_Clock 08_EXMC_NandFlash 09_EXMC_TouchScreen 10_ADC_DMA 11_DAC Output Voltage Value 12_SDIO_SDCardTest 13_I2S_Audio Player 14_USB_Custom_HID #include "gd32f10x.h" #include #include "systick.h" /* Private function prototypes -----------------------------------------------*/ void LED_config(void); void Turn_On_LED(uint8_t LED_NUM); /* Private variables ---------------------------------------------------------*/ uint8_t count=0; /* Private functions ---------------------------------------------------------*/ /** * @brief Configure the GPIO ports. * @param None * @retval None */ void LED_config(void) { GPIO_InitPara GPIO_InitStructure; /* Enable GPIOF clock */ RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOF, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_PIN_0 |GPIO_PIN_1 |GPIO_PIN_2 |GPIO_PIN_3; GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ; GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP; GPIO_Init(GPIOF,&GPIO_InitStructure); GPIO_ResetBits(GPIOF, GPIO_PIN_0 |GPIO_PIN_1 |GPIO_PIN_2 |GPIO_PIN_3); } /** * @brief Light the LEDs. * @param LED_NUM:LEDx where x can be 2..5. * @retval None */ void Turn_On_LED(uint8_t LED_NUM) { switch(LED_NUM) { /* Light the LED2 */ case 0: GPIO_SetBits(GPIOF,GPIO_PIN_0); break; /* Light the LED3 */ case 1: GPIO_SetBits(GPIOF,GPIO_PIN_1); break; /* Light the LED4 */ case 2: GPIO_SetBits(GPIOF,
您好!对于STM32GPIO输出实验,点亮三色LED,您可以按照以下步骤进行操作: 1. 首先,您需要在STM32的开发环境中创建一个新的工程。 2. 在工程中,您需要包含相应的头文件,如"stm32f10x.h"。 3. 接下来,配置相应的引脚为输出模式。假设红色LED连接到GPIOA的Pin0引脚,绿色LED连接到GPIOA的Pin1引脚,蓝色LED连接到GPIOA的Pin2引脚,您可以使用以下代码进行配置: ``` GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置红色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置绿色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置蓝色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ``` 4. 现在,您可以使用相应的寄存器来控制LED点亮和熄灭。例如,要点亮红色LED,可以使用以下代码: ``` GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置高,点亮红色LED ``` 要熄灭红色LED,可以使用以下代码: ``` GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置低,熄灭红色LED ``` 同样的方法,您可以控制绿色和蓝色LED点亮和熄灭。 这就是点亮三色LED的基本步骤。希望对您有所帮助!如果您有任何其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

马浩同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值