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_SET或Bit_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);
}注意事项
- 时钟使能:在使用GPIO之前,必须先使能对应的GPIO时钟
- 引脚锁定:使用
GPIO_PinLockConfig可以锁定引脚配置,防止意外修改 - 重映射功能:某些引脚支持功能重映射,可以改变引脚的功能
- 速度设置:输出模式下需要根据实际应用选择合适的输出速度
- 输入模式:根据外部电路选择合适的输入模式(浮空、上拉、下拉)
总结
STM32F10x GPIO标准库提供了完整的GPIO控制接口,包括引脚配置、数据读写、中断配置等功能。通过合理使用这些函数,可以实现各种GPIO应用,如LED控制、按键检测、外部中断等。在使用过程中需要注意时钟使能、引脚配置等关键步骤。