🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习 🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发 ❄️作者主页:一个平凡而乐于分享的小比特的个人主页 ✨收录专栏:硬件知识,本专栏为记录项目中用到的知识点,以及一些硬件常识总结 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

STM32的每个GPIO引脚都有以下关键寄存器:
模式配置:INPUT + No pull-up/pull-down
电路特点:引脚完全浮空,外部无驱动时为高阻态
应用场景:
- 外部已有确定上/下拉电路
- 通信协议如I2C(配合开漏输出)
注意事项:悬空时易受干扰,功耗可能增加模式配置:INPUT + Pull-up enabled
内部结构:40kΩ左右上拉电阻到VDD
典型应用:
- 按键检测(按键接地)
- 默认需要高电平的输入
特点:无外部信号时保持高电平,节省外部元件模式配置:INPUT + Pull-down enabled
内部结构:40kΩ左右下拉电阻到GND
典型应用:
- 按键检测(按键接VCC)
- 默认需要低电平的输入
特点:无外部信号时保持低电平模式配置:ANALOG MODE
特点:
- 施密特触发器关闭(无数字滤波)
- 上下拉电阻断开
- 输入到ADC/DAC等模拟外设
应用:ADC采样、DAC输出、模拟比较器
注意:此模式下读IDR为0模式配置:OUTPUT + Push-pull
输出结构:
PMOS(上管) | NMOS(下管)
输出1:PMOS导通,NMOS截止 → 输出VDD
输出0:PMOS截止,NMOS导通 → 输出GND
特点:
- 强驱动能力(可输出/吸入电流)
- 电平确定,抗干扰好
应用:LED控制、驱动数字器件、高速信号模式配置:OUTPUT + Open-drain
输出结构:
仅NMOS(下管),无上拉PMOS
输出1:NMOS截止 → 高阻态(需外部上拉)
输出0:NMOS导通 → 输出GND
特点:
- 可实现"线与"功能
- 可输出高于VDD的电压(需外部上拉)
- 驱动能力较弱(上升沿靠外部上拉)
典型应用:
- I2C、SMBUS等通信总线
- 5V兼容电路
- 多设备共享总线模式配置:ALTERNATE FUNCTION + Push-pull
特点:GPIO由片上外设控制(如SPI、USART、TIM)
应用:
- SPI SCK/MOSI(需要强驱动)
- USART TX
- PWM输出
注意:输出信号由外设自动产生模式配置:ALTERNATE FUNCTION + Open-drain
特点:GPIO由外设控制,开漏输出
典型应用:
- I2C SDA/SCL(必须用开漏)
- CAN总线
- 多主机通信系统typedef enum {
GPIO_SPEED_FREQ_LOW = 0, // 2-10MHz
GPIO_SPEED_FREQ_MEDIUM = 1, // 10-50MHz
GPIO_SPEED_FREQ_HIGH = 2, // 50-100MHz
GPIO_SPEED_FREQ_VERY_HIGH = 3 // 100MHz+
} GPIOSpeed_TypeDef;影响:驱动电流、边沿斜率、EMI、功耗
应用场景 | 推荐模式 | 理由 |
|---|---|---|
按键(接地) | 输入上拉 | 默认高电平,按下变低 |
按键(接VCC) | 输入下拉 | 默认低电平,按下变高 |
ADC采样 | 模拟输入 | 关闭数字电路,减少干扰 |
LED控制 | 推挽输出 | 强驱动,电平确定 |
I2C总线 | 开漏输出+上拉 | 线与功能,多主机 |
USART TX | 复用推挽 | 强驱动,高速 |
USART RX | 浮空输入 | 外部已确定电平 |
5V兼容 | 开漏+外部上拉到5V | 电平转换 |
省电模式 | 模拟输入 | 断开上下拉,功耗最低 |
// 1. 推挽输出配置(LED)
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 低速
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// 2. 输入上拉配置(按键)
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入模式
GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 3. 复用开漏(I2C)
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; // 复用开漏
GPIO_InitStruct.Pull = GPIO_PULLUP; // 内部上拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; // 复用功能选择
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// 4. 模拟输入(ADC)
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; // 模拟模式
GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// 使用BSRR实现原子操作(无需读-改-写)
GPIOA->BSRR = GPIO_PIN_5; // 置位PA5(输出1)
GPIOA->BSRR = GPIO_PIN_5 << 16; // 复位PA5(输出0)
// 同时设置多个引脚
GPIOA->BSRR = (1<<5) | (1<<7) | ((1<<6)<<16);// 防止配置被意外修改
GPIOA->LCKR = GPIO_PIN_0 | GPIO_PIN_1; // 要锁定的引脚
GPIOA->LCKR = (1<<16) | GPIO_PIN_0 | GPIO_PIN_1; // 设置LOCK键
GPIOA->LCKR = GPIO_PIN_0 | GPIO_PIN_1; // 再次写入
GPIOA->LCKR = (1<<16) | GPIO_PIN_0 | GPIO_PIN_1; // 确认锁定
// 读取LCKR[16]=1表示锁定成功__HAL_RCC_GPIOx_CLK_ENABLE()模式 | 数字输入 | 数字输出 | 模拟功能 | 上下拉 | 典型应用 |
|---|---|---|---|---|---|
输入浮空 | ✓ | ✗ | ✗ | 可选 | 外部已确定电平 |
输入上拉 | ✓ | ✗ | ✗ | 上拉 | 按键(接地) |
输入下拉 | ✓ | ✗ | ✗ | 下拉 | 按键(接VCC) |
模拟输入 | ✗ | ✗ | ✓ | 断开 | ADC/DAC |
推挽输出 | ✗ | ✓ | ✗ | 可选 | LED、数字输出 |
开漏输出 | ✗ | ✓* | ✗ | 可选 | I2C、电平转换 |
复用推挽 | ✗ | ✓ | ✗ | 可选 | SPI、USART TX |
复用开漏 | ✗ | ✓* | ✗ | 可选 | I2C、CAN |
注:开漏输出高电平需要外部上拉
正确理解并选择GPIO模式对STM32应用的稳定性、功耗和性能至关重要。建议根据具体外设需求参考数据手册的"引脚定义"章节,确认推荐的GPIO配置。