教程
STM32系统结构图
GPIO
GPIO(General Purpose Input/Output)是STM32内部的一种外设。
一个STM32芯片内存在多个GPIO外设,每个GPIO外设有16个引脚;
比如GPIOA:PA0~PA15;
GPIOB:PB0~PB15。
每个IO引脚都有输入电路和输出电路。
GPIO8种工作模式
输入模式
由上下拉电阻控制。
上拉模式如何保持高电平
工作原理:
-
当配置为上拉模式时,GPIO内部会连接一个上拉电阻(通常约30-50kΩ)到VDD
-
当没有外部信号驱动时,上拉电阻会将引脚电压拉至高电平
VDD(正电源)
下拉模式如何保持低电平
工作原理:
-
当配置为下拉模式时,GPIO内部会连接一个下拉电阻(通常约30-50kΩ)到GND
-
当没有外部信号驱动时,下拉电阻会将引脚电压拉至低电平
VSS(负电源/地)
输出模式
由正负半导体控制 。
MOS
MOS(金属氧化物半导体)。
PMOS中的"P"
-
P代表Positive(正)
-
当输出高电平时导通
NMOS中的"N"
-
N代表Negative(负)
-
当输出低电平时导通
推挽输出
1上高,0下低;
开漏输出
PMOS断开,无效,只有NMOS在工作。
通用和复用输出
复用输出模式,与通用输出模式很是类似。只是输出的高低电平的来源,不是写程序让CPU直接写输出数据到寄存器,取而代之利用片上(stm32芯片上的)外设模块来输出电平信号。
注意:通用模式和复用模式接线不同。
GPIO编程控制步骤
1,使用RCC开启GPIO的时钟;
2,使用GPIO_Init()函数初始化GPIO;
3,使用输出/输出函数控制GPIO口。
GPIO的库函数
设置GPIO引脚电平
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:设置指定GPIO端口的单个或多个引脚为高电平(置1)
参数:
-
GPIOx
:GPIO端口(如GPIOA、GPIOB等) -
GPIO_Pin
:要设置的引脚(可使用|
组合多个引脚)
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:设置指定GPIO端口的单个或多个引脚为低电平(置0)
参数:
-
GPIOx
:GPIO端口 -
GPIO_Pin
:要清除的引脚(可使用|
组合多个引脚)
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
功能:设置指定GPIO端口的单个引脚状态
参数:
-
GPIOx
:GPIO端口 -
GPIO_Pin
:要设置的引脚(只能单个引脚) -
BitVal
:引脚状态(Bit_SET
或Bit_RESET
)
// 设置GPIOC的Pin4为高电平
GPIO_WriteBit(GPIOC, GPIO_Pin_4, Bit_SET);
// 设置GPIOC的Pin4为低电平
GPIO_WriteBit(GPIOC, GPIO_Pin_4, Bit_RESET);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
功能:一次性设置整个GPIO端口的输出状态
参数:
-
GPIOx
:GPIO端口 -
PortVal
:16位值,表示所有引脚的状态(每个bit对应一个引脚)
// 设置GPIOA所有引脚状态:Pin0=1, Pin1=0, Pin2=1, 其他=0
GPIO_Write(GPIOA, 0x0005); // 二进制 0000 0000 0000 0101
获取引脚输入/输出电平
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);
什么时候使用input,什么时候使用output?
函数类别 | 读取的数据来源 | 典型应用场景 |
---|---|---|
Input系列函数 | 读取GPIO引脚当前输入电平 | 检测外部信号(按键、传感器等) |
Output系列函数 | 读取GPIO输出寄存器的值 | 验证软件配置的输出状态 |
(1) 何时使用Input
函数
当GPIO配置为输入模式或需要读取实际引脚电平时:
检测外部信号:
// 读取PA0引脚电平(配置为输入模式)
if(GPIO_ReadInputDataBit(GPIOA, GPIO_PIN_0) == Bit_SET) {
// 高电平处理(如按键按下)
}
读取多个输入引脚:
uint16_t port_val = GPIO_ReadInputData(GPIOB); // 读取PB0-PB15所有引脚
(2) 何时使用Output
函数
当需要确认输出寄存器的状态(而非实际引脚电平)时:
验证输出配置:
// 检查PC13输出寄存器是否设置为高电平
if(GPIO_ReadOutputDataBit(GPIOC, GPIO_PIN_13) == Bit_SET) {
// 软件设置过输出高电平
}
批量读取输出状态:
uint16_t output_states = GPIO_ReadOutputData(GPIOD); // 读取PD端口输出寄存器
关键注意:
-
输出函数读取的是输出数据寄存器(ODR)的值,不一定等于实际引脚电平!
-
若外部电路拉低/拉高引脚(如短路),实际电平可能与ODR值不同。