stm32f10x_gpio

STM32F10x GPIO(通用输入输出)标准库提供了丰富的函数接口,用于配置和控制GPIO引脚。本文档详细介绍了所有相关的函数、结构体和枚举类型。

数据类型定义

GPIO_InitTypeDef 结构体

typedef struct
{
  uint16_t GPIO_Pin;             /*!< 指定要配置的GPIO引脚
                                      此参数可以是 @ref GPIO_pins_define 中的任何值 */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< 指定所选引脚的速度
                                      此参数可以是 @ref GPIOSpeed_TypeDef 中的值 */

  GPIOMode_TypeDef GPIO_Mode;    /*!< 指定所选引脚的工作模式
                                      此参数可以是 @ref GPIOMode_TypeDef 中的值 */
}GPIO_InitTypeDef;

成员说明:

  • GPIO_Pin:要配置的GPIO引脚,可以是单个引脚或多个引脚的组合
  • GPIO_Speed:GPIO引脚的输出速度设置
  • GPIO_Mode:GPIO引脚的工作模式设置

GPIOSpeed_TypeDef 枚举

typedef enum
{ 
  GPIO_Speed_10MHz = 1,  /*!< 10MHz输出速度 */
  GPIO_Speed_2MHz,       /*!< 2MHz输出速度 */
  GPIO_Speed_50MHz       /*!< 50MHz输出速度 */
}GPIOSpeed_TypeDef;

GPIOMode_TypeDef 枚举

typedef enum
{ 
  GPIO_Mode_AIN = 0x0,        /*!< 模拟输入模式 */
  GPIO_Mode_IN_FLOATING = 0x04, /*!< 浮空输入模式 */
  GPIO_Mode_IPD = 0x28,       /*!< 下拉输入模式 */
  GPIO_Mode_IPU = 0x48,       /*!< 上拉输入模式 */
  GPIO_Mode_Out_OD = 0x14,    /*!< 开漏输出模式 */
  GPIO_Mode_Out_PP = 0x10,    /*!< 推挽输出模式 */
  GPIO_Mode_AF_OD = 0x1C,     /*!< 复用开漏输出模式 */
  GPIO_Mode_AF_PP = 0x18      /*!< 复用推挽输出模式 */
}GPIOMode_TypeDef;

BitAction 枚举

typedef enum
{ 
  Bit_RESET = 0,  /*!< 位复位 */
  Bit_SET         /*!< 位置位 */
}BitAction;

标准库函数详解

1.GPIO_DeInit

/**
 * @brief  将指定 GPIO 端口寄存器恢复为复位默认值,用于切换引脚用途或重新配置前清空旧模式
 * @param  GPIOx: 选择要重置的GPIO外设
 * @retval
 * @example
 *     GPIO_DeInit(GPIOA);
 */
void GPIO_DeInit(GPIO_TypeDef* GPIOx);

功能说明:

  • 整端口回到浮空输入等默认状态,不会自动关闭 RCC 时钟
  • 从输出改为复用/模拟输入等场景,可先 DeInit 再 GPIO_Init
  • 仅影响 GPIOx 对应端口,AFIO 重映射需单独处理

2.GPIO_AFIODeInit

/**
 * @brief  将 AFIO 寄存器恢复为默认值,清除引脚重映射与 EXTI 端口选择等复用配置
 * @param
 * @retval
 * @example
 *     GPIO_AFIODeInit();
 */
void GPIO_AFIODeInit(void);

功能说明:

  • 清除所有重映射与 EXTI 线到端口的映射关系
  • 系统级复位或调试时恢复引脚默认功能
  • 调用前需使能 AFIO 时钟(RCC_APB2Periph_AFIO

3.GPIO_Init

/**
 * @brief  按结构体一次性配置引脚模式、速度与方向,是 LED、按键、外设复用等应用的基础步骤
 * @param  GPIOx: 选择要初始化的GPIO外设
 * @param  GPIO_InitStruct: 指向GPIO_InitTypeDef结构的指针,包含指定GPIO外设的配置信息
 * @retval
 * @example
 *     GPIO_InitTypeDef GPIO_InitStructure;
 *     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
 *     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 *     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 *     GPIO_Init(GPIOA, &GPIO_InitStructure);
 */
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

功能说明:

  • GPIO_Pin 可位或组合,一次配置多引脚
  • 输出模式需根据负载与边沿速率选 GPIO_Speed
  • 使用前必须先 RCC_APB2PeriphClockCmd 使能对应 GPIO 时钟

4.GPIO_StructInit

/**
 * @brief  将 GPIO_InitTypeDef 填为库默认安全值,避免未初始化字段导致随机引脚配置
 * @param  GPIO_InitStruct: 指向GPIO_InitTypeDef结构的指针,将被初始化
 * @retval
 * @example
 *     GPIO_InitTypeDef GPIO_InitStructure;
 *     GPIO_StructInit(&GPIO_InitStructure);
 */
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);

功能说明:

  • 默认浮空输入、2MHz,适合作为模板再改个别字段
  • 推荐在 GPIO_Init 前调用,减少遗漏成员的风险
  • 不会修改硬件,仅填充结构体

5.GPIO_ReadInputDataBit

/**
 * @brief  读取单路输入引脚电平,用于按键检测、传感器数字量采样等场景
 * @param  GPIOx: 选择GPIO外设
 * @param  GPIO_Pin: 选择要读取的GPIO引脚
 * @retval 输入端口位值(Bit_SET或Bit_RESET)
 * @example
 *     uint8_t pinState = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
 */
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

功能说明:

  • 读 IDR 寄存器对应位,引脚须先配置为输入模式
  • 返回 Bit_SET/Bit_RESET,便于与逻辑电平比较
  • 比读整端口再掩码更直观,适合单键轮询

6.GPIO_ReadInputData

/**
 * @brief  一次性读取整端口 16 路输入状态,适合矩阵键盘或并行总线批量采样
 * @param  GPIOx: 选择GPIO外设
 * @retval GPIO输入数据端口值
 * @example
 *     uint16_t portData = GPIO_ReadInputData(GPIOA);
 */
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

功能说明:

  • 返回 16 位 IDR 值,每位对应一个引脚
  • 多引脚同时扫描时比逐位读取更高效
  • 读后自行用位掩码解析各引脚

7.GPIO_ReadOutputDataBit

/**
 * @brief  回读输出锁存器中单引脚状态,用于确认写操作是否生效或做读-改-写前检查
 * @param  GPIOx: 选择GPIO外设
 * @param  GPIO_Pin: 选择要读取的GPIO引脚
 * @retval 输出端口位值(Bit_SET或Bit_RESET)
 * @example
 *     uint8_t outputState = GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_5);
 */
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

功能说明:

  • 读 ODR 而非引脚实际电平(开漏外接上拉时可能不同)
  • 翻转单 bit 前可先读再写,避免影响同端口其他引脚
  • 输出模式下常用

8.GPIO_ReadOutputData

/**
 * @brief  读取整端口输出锁存值,便于批量保存或恢复 IO 状态
 * @param  GPIOx: 选择GPIO外设
 * @retval GPIO输出数据端口值
 * @example
 *     uint16_t outputData = GPIO_ReadOutputData(GPIOA);
 */
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

功能说明:

  • 返回 ODR 完整 16 位,反映上次写入的输出值
  • 配合 GPIO_Write 可实现端口级快照与恢复
  • 调试时核对软件期望输出与实际锁存

9.GPIO_SetBits

/**
 * @brief  将指定引脚驱动为高电平,常用于点亮 LED、置位控制线或片选有效
 * @param  GPIOx: 选择GPIO外设
 * @param  GPIO_Pin: 选择要设置的GPIO引脚
 * @retval
 * @example
 *     GPIO_SetBits(GPIOA, GPIO_Pin_5);
 */
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

功能说明:

  • 通过 BSRR 置位,不影响同端口其他引脚
  • 引脚须已配置为推挽/开漏输出或复用输出
  • 可多引脚位或,一次置高多路

10.GPIO_ResetBits

/**
 * @brief  将指定引脚驱动为低电平,常用于熄灭 LED、释放片选或拉低使能脚
 * @param  GPIOx: 选择GPIO外设
 * @param  GPIO_Pin: 选择要清除的GPIO引脚
 * @retval
 * @example
 *     GPIO_ResetBits(GPIOA, GPIO_Pin_5);
 */
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

功能说明:

  • 通过 BSRR 复位对应位,原子操作不读-改-写
  • GPIO_SetBits 配对实现闪烁、脉冲
  • 开漏输出时低电平为有效驱动

11.GPIO_WriteBit

/**
 * @brief  按 Bit_SET/Bit_RESET 写入单引脚,适合根据布尔变量统一控制高低电平
 * @param  GPIOx: 选择GPIO外设
 * @param  GPIO_Pin: 选择要写入的GPIO引脚
 * @param  BitVal: 选择要写入的值(Bit_SET或Bit_RESET)
 * @retval
 * @example
 *     GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET);
 */
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

功能说明:

  • 等价于条件调用 Set/Reset,接口更统一
  • BitVal 仅接受 Bit_SETBit_RESET
  • 封装驱动层时常用此函数传递开关状态

12.GPIO_Write

/**
 * @brief  向 ODR 整字写入,一次更新端口多路输出,适合并行数据或位图式控制
 * @param  GPIOx: 选择GPIO外设
 * @param  PortVal: 要写入端口输出数据寄存器的值
 * @retval
 * @example
 *     GPIO_Write(GPIOA, 0x00FF);
 */
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

功能说明:

  • 直接覆盖 ODR 低 16 位,未置位引脚会被清零
  • 七段数码管、并行 DAC 等需要整端口图案时常用
  • 若只需改部分位,优先用 Set/Reset 避免误改其他引脚

13.GPIO_PinLockConfig

/**
 * @brief  锁定指定引脚的配置寄存器,防止运行中被误写导致引脚功能漂移
 * @param  GPIOx: 选择GPIO外设
 * @param  GPIO_Pin: 选择要锁定的GPIO引脚
 * @retval
 * @example
 *     GPIO_PinLockConfig(GPIOA, GPIO_Pin_5);
 */
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

功能说明:

  • 锁定后 MODE/CFG 等配置不可再改,直至复位
  • 安全关键或防篡改场景(如 JTAG 引脚)可考虑使用
  • 锁定前须完成最终 GPIO_Init 配置

14.GPIO_EventOutputConfig

/**
 * @brief  选择 EVENTOUT 信号从哪一路 GPIO 输出,用于将内部事件路由到外部观测或触发
 * @param  GPIO_PortSource: 选择用作事件输出的GPIO端口源
 * @param  GPIO_PinSource: 选择用作事件输出的GPIO引脚源
 * @retval
 * @example
 *     GPIO_EventOutputConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
 */
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

功能说明:

  • 需配合 GPIO_EventOutputCmd 才真正输出事件
  • 事件源由其他外设(如 RTC、USB 等)选择,本函数只定引脚
  • 调试时钟或内部事件时可用于示波器抓取

15.GPIO_EventOutputCmd

/**
 * @brief  打开或关闭 EVENTOUT 输出,使能后选定引脚对外送出内部事件脉冲
 * @param  NewState: 事件输出新状态(ENABLE或DISABLE)
 * @retval
 * @example
 *     GPIO_EventOutputCmd(ENABLE);
 */
void GPIO_EventOutputCmd(FunctionalState NewState);

功能说明:

  • 须先 GPIO_EventOutputConfig 指定引脚
  • 失能后引脚恢复普通 GPIO 控制
  • 低功耗或量产时可 DISABLE 避免多余翻转

16.GPIO_PinRemapConfig

/**
 * @brief  将 USART/SPI/TIM 等外设映射到备用引脚,解决默认引脚被占用或与 PCB 不符的问题
 * @param  GPIO_Remap: 选择要配置的重映射
 * @param  NewState: 重映射新状态(ENABLE或DISABLE)
 * @retval
 * @example
 *     GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
 */
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);

功能说明:

  • 部分重映射互斥,需查数据手册 Remap 表
  • 使能 AFIO 时钟后调用,并重新 GPIO_Init 复用模式
  • DISABLE 可恢复默认引脚映射

17.GPIO_EXTILineConfig

/**
 * @brief  将 EXTI 线连接到指定端口引脚,是外部中断/事件与 GPIO 之间的桥梁
 * @param  GPIO_PortSource: 选择用作外部中断线的GPIO端口源
 * @param  GPIO_PinSource: 选择用作外部中断线的GPIO引脚源
 * @retval
 * @example
 *     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
 */
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

功能说明:

  • 每条 EXTI 线同一时刻只能连一个端口(如 PA0 与 PB0 二选一)
  • 须配合 EXTI_Init 与 NVIC 完成中断配置
  • 使能 AFIO 时钟;引脚建议配置上/下拉或浮空输入

18.GPIO_ETH_MediaInterfaceConfig

/**
 * @brief  选择以太网 MAC 使用 MII 还是 RMII 与 PHY 通信,决定所需 GPIO 数量与连线方式
 * @param  GPIO_ETH_MediaInterface: 选择以太网媒体接口
 * @retval
 * @example
 *     GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_RMII);
 */
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

功能说明:

  • RMII 引脚更少,多数开发板默认 RMII
  • 须在 ETH 与外设 GPIO 初始化前配置
  • 仅 connectivity 系列(如 STM32F107)具备 ETH 外设

常用宏定义

GPIO引脚定义

#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< 选择引脚0 */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< 选择引脚1 */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< 选择引脚2 */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< 选择引脚3 */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< 选择引脚4 */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< 选择引脚5 */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< 选择引脚6 */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< 选择引脚7 */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< 选择引脚8 */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< 选择引脚9 */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< 选择引脚10 */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< 选择引脚11 */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< 选择引脚12 */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< 选择引脚13 */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< 选择引脚14 */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< 选择引脚15 */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< 选择所有引脚 */

使用示例

基本GPIO配置示例

#include "stm32f10x_gpio.h"

void GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置PA5为推挽输出,50MHz
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置PA0为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void GPIO_Operation(void)
{
    // 设置PA5为高电平
    GPIO_SetBits(GPIOA, GPIO_Pin_5);
    
    // 延时
    for(volatile int i = 0; i < 1000000; i++);
    
    // 设置PA5为低电平
    GPIO_ResetBits(GPIOA, GPIO_Pin_5);
    
    // 读取PA0的状态
    uint8_t pinState = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
}

外部中断配置示例

#include "stm32f10x_gpio.h"
#include "stm32f10x_exti.h"

void EXTI_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    
    // 使能时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
    
    // 配置PA0为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置PA0为外部中断线
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    
    // 配置外部中断
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

注意事项

  1. 时钟使能:在使用GPIO之前,必须先使能对应的GPIO时钟
  2. 引脚锁定:使用GPIO_PinLockConfig可以锁定引脚配置,防止意外修改
  3. 重映射功能:某些引脚支持功能重映射,可以改变引脚的功能
  4. 速度设置:输出模式下需要根据实际应用选择合适的输出速度
  5. 输入模式:根据外部电路选择合适的输入模式(浮空、上拉、下拉)

总结

STM32F10x GPIO标准库提供了完整的GPIO控制接口,包括引脚配置、数据读写、中断配置等功能。通过合理使用这些函数,可以实现各种GPIO应用,如LED控制、按键检测、外部中断等。在使用过程中需要注意时钟使能、引脚配置等关键步骤。