一、GPIO配置
一个GPIO口的需要操作7个寄存器,分别是CRL,CRH,IDR,ODR,BRR,BSRR,LCKR 我们对GPIO的操作本质上就是在对这些寄存器进行读写操作
GPIO管脚关系:芯片的 PA、PB、PC、PD 等均属于 GPIO 端口。
GPIO 占用了 STM32 芯片大部分的端口引脚。并且每一个端口都有 16 个引脚,比如 PA 端口,它有 PA0-PA15。其他的 PB、PC 等端口是一样的。
如下为GPIO端口配置函数信息 :
GPIOx_CRL(x = A..E)端口配置低寄存器 32位寄存器
GPIOx_CRH(x = A..E)端口配置高寄存器 32位寄存器
GPIOx_IDR(x = A..E)端口输入数据寄存器 32位寄存器但仅用低16位
GPIOx_ODR(x = A..E)端口输出数据寄存器 32位寄存器但仅用低16位
GPIOx_BRR(x = A..E)端口位清除寄存器 16位寄存器
GPIOx_BSRR(x = A..E)端口位设置/清除寄存器 16位寄存器
GPIOx_LCKR(x = A..E)端口配置锁定寄存器 32位寄存器
二、GPIO输出输入模式

① 保护二极管 ② 内部上拉、下拉电阻 ③ 施密特触发器 P-MOS & N-MOS管
分别是:上拉输入、下拉输入、浮空输入、模拟输入、开漏输出、推挽输出、开漏复用输出、推挽复用输出 等模式,以下是对应的函数:
-
上拉输入:
GPIO_Mode_IPU -
下拉输入:
GPIO_Mode_IPD -
浮空输入:
GPIO_Mode_IN_FLOATING -
模拟输入:
GPIO_Mode_AIN -
开漏输出:
GPIO_Mode_Out_OD -
推挽输出:
GPIO_Mode_Out_PP -
开漏复用:
GPIO_Mode_AF_OD -
推完复用:
GPIO_Mode_AF_PP
1.上拉输入(GPIO_Mode_IPU):
- 特点:空闲时,IO呈现高电平
- 原件开关情况:上拉电阻接通,下拉电阻断开,施密特触发器打开,输出模块被禁止
- 应用:需要**“弱上拉”**的情况,可节省一个外部电阻
I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平保持在高电平。
2.输入下拉模式(GPIO_Mode_IPD):
- 特点:空闲时,IO呈现低电平
- 原件开关情况:上拉电阻断开,下拉电阻导通,施密特触发器打开,输出模块被禁止
- 应用:可节省一个外部电阻
I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平保持在低电平。

3.输入浮空模式(GPIO_Mode_IN_FLOATING)
- 特点:IO口电平完全由外部电路决定
- 原件开关情况:上下拉电阻断开,施密特触发器打开,输出模块被禁止
- 应用:常用于按键检测
- 浮空输入模式下,
I/O端口的电平信号直接进入输入数据寄存器。也就是说,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的,通常用于IIC、USART等总线设备上

4.模拟输入模式(GPIO_Mode_AIN)
- 特点:(1)走的路比较独特。数据输入不经过数据输入寄存器,而是直接走模拟输入通道(2)该模式下需要用到芯片内部的模拟电路单元
- 原件开关情况:上拉电阻断开,下拉电阻断开,施密特触发器关闭,输出模块被禁止
- 应用:用于模拟信号输入或输出场景,如:ADC和DAC

5.开漏输出模式(GPIO_Mode_Out_OD)
-
特点:该模式下,引脚只能输出低电平仅有低电平时有驱动能力,
-
高电平时为高阻态,要输出高电平需要通过外部上拉电阻或其他方式。
-
应用:通常用于与外部器件连接,常用于 IIC 通讯或其它需要进行电平转换的场景。
-
首先要明确三点:
(1)在开漏输出模式下,P-MOS管永远处于截止状态(即不导通),因此 IO 的状态取决于 N-MOS 的导通状况
(2)输出数据寄存器的输出数据都会进行一次“输出控制”的取反操作
(3)施密特触发器仍然工作,但上下拉电阻不工作,所以输入部分可以看成浮空输入,可以读取到IO口的工作状态 
// 初始化开漏输出模式的GPIO
GPIO_InitStruct.Pin = GPIO_Pin_13;
GPIO_InitStruct.Mode = GPIO_Mode_Out_OD; // 开漏输出模式
GPIO_InitStruct.Speed = GPIO_Speed_50Mhz; // GPIO速度设置为50HZ
GPIO_Init(GPIOC, &GPIO_InitStruct);
6.推免输出模式(GPIO_Mode_Out_PP)常用
GPIO_Mode_Out (表示输出模式)
GPIO_Mode_Out_PP (表示推免输出模式)
GPIO_Mode_Out_OD (表示开漏输出模式)
- 特点:该模式下,引脚可以输出高电平或低电平,同时具有一定的驱动能力。
- 引脚在输出低电平时形成低阻抗,输出高电平时形成高阻抗,可以驱动外部电路。

// 初始化推挽输出模式的GPIO
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_Pin_13; // GPIO引脚号
GPIO_InitStruct.Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStruct.Speed = GPIO_Speed_50Mhz; // GPIO速度设置为50HZ
GPIO_Init(GPIOC, &GPIO_InitStruct); // 初始化GPIOC
7. 复用推挽输出(GPIO_Mode_AF_PP):
- 特点:允许将GPIO引脚用作特定外设功能。
- 该模式下,引脚可以输出高电平或低电平,并具有一定的驱动能力
// 初始化复用推挽输出模式的GPIO
//GPIO_InitStruct.Pull()函数来初始化GPIO引脚,并设置其上拉(GPIO_NOPULL)、下拉(GPIO_PULLDOWN)或无拉电阻(GPIO_NOPULL)状态
GPIO_InitStruct.Pin = GPIO_Pin_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 复用推挽输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL; // 不设置上拉或下拉
GPIO_InitStruct.Speed = GPIO_Speed_50Mhz; // GPIO速度设置为50HZ
GPIO_Init(GPIOC, &GPIO_InitStruct);
8.复用开漏输出(GPIO_Mode_AF_OD):
- 允许将GPIO引脚用作特定外设功能。
- 该模式下,引脚只能输出低电平,要输出高电平需要通过外部上拉电阻或其他方式。
// 初始化模拟输入模式的GPIO
GPIO_InitStruct.Pin = GPIO_Pin_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; // 模拟输入模式
GPIO_InitStruct.Pull = GPIO_NOPULL; // 不设置上拉或下拉
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
端口初始化示例
#include "stm32xxx.h"
/**
GPIOX.XX端口配置函数
**/
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //建立端口结构体,用于配置端口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_xx; //xx为引脚模式,如GPIO_Mode_IN、GPIO_Mode_OUT等
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_xxx; //xxx为速度选择,如GPIO_Speed_2MHz、10MHz、50MHz
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_xx; //xx为GPIO端口的管脚引脚:可选0-15
//端口可以一次初始化多个 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 等等
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_x; // x为上下拉配置,如GPIO_PuPd_NOPULL(无上下拉)、GPIO_PuPd_UP(上拉)等
//当已经设定GPIO_Mode_XX_xx的模式后则不需要该函数设计否则需要
//xx可填如GPIO_OType_PP(推挽输出)、GPIO_OType_OD(开漏输出)等
GPIO_InitStructure.GPIO_OType=GPIO_OType_x;
GPIO_Init(GPIOX,&GPIO_InitStructure); // x为对应的GPIO端口,如GPIOA、GPIOB等指针类型用&取地址
}
int main(void)
{
// 初始化MCU和其他外设
GPIO_Init(); //初始化端口
// 其他代码逻辑
while (1)
{
// 主循环代码
}
}
本文详细介绍了STM32中GPIO口的寄存器操作,包括CRL、CRH、IDR、ODR、BRR、BSRR和LCKR,以及各种输出输入模式如上拉输入、下拉输入、浮空输入、模拟输入和不同类型的输出模式,提供端口初始化示例。
4066





