GPIO输入/输出(标准库)

本文详细介绍了STM32F407ZG微控制器的GPIO功能,包括GPIO端口配置、工作模式、初始化代码及库函数使用方法。通过具体实例展示了如何配置GPIO引脚实现LED控制和按键检测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、GPIO功能概述

(1)概述

STM32F407ZG有8个16引脚的GPIO端口。还有一个12引脚的PI端口。

GPIO端口都连接在AHB1总线上,自高时钟频率168MHz。

GPIO引脚能承受5V电压.

每个GPIO端口有4个32位寄存器,用于配置GPIO引脚的工作模式;1个32位输入数据寄存器和1个32位输出数据寄存器,还有复用功能选择寄存器等。

(2)GPIO引脚可以配置多种工作模式:

输入浮空(input floating):作为GPIO输入引脚,不使用上拉或下拉电阻。

输入上拉(input pull-up),作为GPIO输入引脚,使用内部上拉电阻。当没有外部输入时,引脚输入电平为高电平。

输入下拉(input pull-down):作为GPIO输入引脚,使用内部下拉电阻。当没有外部输入时,引脚输入电平为低电平。

模拟(analog):作为GPIO模拟引脚,用于ADC输入引脚或DAC输出引脚。

具有上拉或下拉的开漏输出(output open-drain):如果不使用上拉或下拉电阻,开漏输出1时引脚为高阻态,输出0时引脚是低电平。这种模式可用于共用总线的信号。

具有上拉或下拉的推挽输出(output push-pull):如果不使用上拉或下拉电阻,推挽输出1时引脚是高电平,输出0时引脚为低电平。若需要增强引脚输出驱动能力,就可以使用上拉。例如需要GPIO引脚输出高电平点亮LED时。

具有上拉或下拉的复用功能推挽(afternate function push-pull)。

具有上拉或下拉的复用功能开漏(afternate function open-drain)。

2、初始化代码

(1)GPIO工作模式

typedef enum
{ 
  GPIO_Mode_IN   = 0x00, /*!< GPIO Input Mode */
  GPIO_Mode_OUT  = 0x01, /*!< GPIO Output Mode */
  GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */
  GPIO_Mode_AN   = 0x03  /*!< GPIO Analog Mode */
}GPIOMode_TypeDef;

(2)GPIO输出频率

typedef enum
{ 
  GPIO_Low_Speed     = 0x00, /*!< Low speed    */
  GPIO_Medium_Speed  = 0x01, /*!< Medium speed */
  GPIO_Fast_Speed    = 0x02, /*!< Fast speed   */
  GPIO_High_Speed    = 0x03  /*!< High speed   */
}GPIOSpeed_TypeDef;
#define  GPIO_Speed_2MHz    GPIO_Low_Speed    
#define  GPIO_Speed_25MHz   GPIO_Medium_Speed 
#define  GPIO_Speed_50MHz   GPIO_Fast_Speed 
#define  GPIO_Speed_100MHz  GPIO_High_Speed 

(3)GPIO输出模式

typedef enum
{ 
  GPIO_OType_PP = 0x00,
  GPIO_OType_OD = 0x01
}GPIOOType_TypeDef;

(4)GPIO上拉下拉设置

typedef enum
{ 
  GPIO_PuPd_NOPULL = 0x00,
  GPIO_PuPd_UP     = 0x01,
  GPIO_PuPd_DOWN   = 0x02
}GPIOPuPd_TypeDef;

(5)GPIO位设置

typedef enum
{ 
  Bit_RESET = 0,
  Bit_SET
}BitAction;

(6)GPIO初始化结构体

typedef struct
{
  uint32_t GPIO_Pin;              
  GPIOMode_TypeDef GPIO_Mode;     
  GPIOSpeed_TypeDef GPIO_Speed;   
  GPIOOType_TypeDef GPIO_OType;  
  GPIOPuPd_TypeDef GPIO_PuPd;                                     
}GPIO_InitTypeDef;

3、库函数

(1)去初始化函数/默认模式

void GPIO_DeInit(GPIO_TypeDef* GPIOx);

(2)初始化函数

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

(3)GPIO读写函数

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

(4)时钟使能函数

void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);

STM32F407ZGT6的GPIO资源都是挂载在AHB1上的,所以时钟使能函数使用RCC_AHB1PeriphClockCmd()。

4、例程

(1)电路资源

(2)端口资源

用户标签引脚名称引脚功能GPIO模式上拉或下拉
LED1PF9GPIO_Output推挽输出
LED2PF10GPIO_Output推挽输出
KeyRightPE2GPIO_Input输入上拉
KeyDownPE3GPIO_Input输入上拉
KeyLeft4PE4GPIO_Input输入上拉
KeyUpPA0GPIO_Input输入下拉

(3)例程

#include "gpio_keyled.h"
​
void led_key_init()
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF,ENABLE);
    
    GPIO_InitStructure.GPIO_Pin = Led1_Pin | Led2_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOF,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = KeyDown_Pin | KeyLeft_Pin | KeyRight_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOE,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = KeyUp_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
}
​
void led1_on()
{
    GPIO_WriteBit(GPIOF,Led1_Pin,Bit_RESET);
}
void led2_on()
{
    GPIO_WriteBit(GPIOF,Led2_Pin,Bit_RESET);
}
void led1_off()
{
    GPIO_WriteBit(GPIOF,Led1_Pin,Bit_SET);
}
void led2_off()
{
    GPIO_WriteBit(GPIOF,Led2_Pin,Bit_SET);
}
​
KEYS ScanKey()
{
    KEYS key = KeyNone;
    if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyRight_Pin))
    {
        Delay2();
        if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyRight_Pin))
            key = KeyRight;
    }
    if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyLeft_Pin))
    {
        Delay2();
        if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyLeft_Pin))
            key = KeyLeft;
    }
    if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyDown_Pin))
    {
        Delay2();
        if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyDown_Pin))
            key = KeyDown;
    }
    if(Bit_SET == GPIO_ReadInputDataBit(GPIOA,KeyUp_Pin))
    {
        Delay2();
        if(Bit_SET == GPIO_ReadInputDataBit(GPIOA,KeyUp_Pin))
            key = KeyUp;
    }
    return key;
}

5、库使用流程

6、注意事项

  • AHB1的时钟使能需要写在GPIO口初始化之前。

  • 标准库中的 SystemInit 函数把 STM32 芯片的系统时钟设置成了 168MHz,即此时 AHB1 时钟频率为 168MHz,APB2 为 84MHz,APB1 为 42MHz。

<think>好的,我现在需要帮助用户找到关于GPIO上拉输入标准库函数或实现方法,特别是在嵌入式C/C++环境中。首先,我要确认用户的需求是什么。他们可能在使用微控制器,比如STM32,需要配置GPIO引脚为上拉输入模式。这可能涉及到标准库(如STM32标准外设库)或HAL库的函数调用。 首先,我需要回忆不同厂商的库函数命名规范,比如STMicroelectronics的STM32系列。他们的标准库通常有特定的函数来配置GPIO。例如,GPIO_InitTypeDef结构体用来设置引脚的模式和参数,然后调用GPIO_Init函数来应用配置。 用户提到“上拉输入”,这指的是GPIO引脚内部上拉电阻使能的输入模式。在STM32标准库中,GPIO_Mode_IPU可能对应的模式是上拉输入。需要确认这一点是否正确,比如查看STM32的参考手册或库文档。 另外,可能需要考虑其他厂商的MCU,比如NXP或Microchip,但用户的问题中没有具体说明,所以假设是STM32,因为标准库的例子比较常见。此外,用户提到了嵌入式C/C++,所以代码示例应该用C语言。 接下来,我需要确保提供的代码示例正确无误,包括正确的函数名和参数设置。例如,使用GPIO_InitTypeDef结构体,设置Pin为某个引脚,Mode为GPIO_Mode_IPU,然后调用GPIO_Init。 另外,用户可能需要知道如何通过寄存器直接配置,这在没有标准库的情况下有用。这涉及到设置相应的寄存器位,比如配置CRL或CRH寄存器,以及设置ODR位来使能上拉电阻。 同时,需要注意不同的STM32系列可能有不同的寄存器结构,比如F1系列和F4系列的配置方式可能不同。因此,在提供寄存器级代码时,需要指明适用的型号,或者建议用户查阅对应数据手册。 还要考虑用户可能的错误,比如忘记使能GPIO端口的时钟,这在配置GPIO前是必须的。因此,在步骤中应该包括启用时钟的代码,例如RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE)。 最后,生成相关问题时要覆盖常见的问题,比如不同模式的区别、如何配置下拉输入、HAL库的使用方法,以及调试技巧等。这些问题可以帮助用户进一步理解和应用GPIO配置。</think>在嵌入式C/C++开发中,配置GPIO为上拉输入模式需通过寄存器操作或调用标准库函数。以STM32标准外设库为例,具体实现步骤如下: ### 一、标准库函数实现 ```c #include "stm32f10x_gpio.h" void GPIO_PullUp_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能时钟 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; // 选择PA0引脚 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入模式[^1] GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); // 应用配置 } ``` ### 二、寄存器级实现 ```c #define GPIOA_CRL *(volatile uint32_t*)(0x40010800) // PA0-PA7配置寄存器 #define GPIOA_ODR *(volatile uint32_t*)(0x4001080C) // 输出数据寄存器 void GPIO_PullUp_Hardware(void) { RCC->APB2ENR |= 0x04; // 开启GPIOA时钟 GPIOA_CRL &= ~(0xF << 0); // 清除PA0原有配置 GPIOA_CRL |= 0x8 << 0; // 设置为输入模式(0b1000) GPIOA_ODR |= 1 << 0; // 使能上拉电阻[^1] } ``` ### 三、关键参数说明 1. `GPIO_Mode_IPU`:STM32标准库中表示上拉输入模式 2. 寄存器配置中: - CRL寄存器位含义:`CNF[1:0]=10`(输入模式) + `MODE[1:0]=00`(输入模式) - ODR寄存器置1启用上拉电阻
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

星顶照

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

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

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

打赏作者

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

抵扣说明:

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

余额充值