尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

【STM32基础篇】GPIO 工作原理、8种模式深度剖析

【STM32基础篇】GPIO 工作原理、8种模式深度剖析 1. GPIO 概述与硬件结构解析GPIOGeneral Purpose Input/Output通用输入输出端口是单片机最基础的外设任何按键输入、LED 控制、Sensor 传感器读取或通信总线如 I2C、SPI 模拟都建立在 GPIO 基础之上。STM32 的每一个 GPIO 引脚内部结构都非常精密支持独立配置GPIO 引脚结构包含以下核心部件保护二极管防止引脚输入电压过高或过低损坏芯片内部电路输入电压限制在 $V_{DD} 0.3\text{V}$ 和 $V_{SS} - 0.3\text{V}$ 之间。上拉/下拉电阻内部开关控制接上拉电阻接 $V_{DD}$或下拉电阻接 $V_{SS}$。施密特触发器Schmitt Trigger将输入的模拟电平整形转换为逻辑数字信号 $0$ 或 $1$。P-MOS 和 N-MOS 管构成输出驱动电路实现推挽或开漏输出。2. GPIO 的 8 种工作模式详解STM32 的 GPIO 模式可以通过软件配置为以下 8 种2.1 输入模式Input输入浮空GPIO_MODE_INPUT不接上拉也不接下拉电阻引脚电平完全由外部输入决定。适用场景USART 接收引脚RX、外部按键外部已有上下拉。输入上拉GPIO_MODE_INPUT Pull-up内部连接上拉电阻默认无输入时保持高电平。适用场景低电平有效的按键检测。输入下拉GPIO_MODE_INPUT Pull-down内部连接下拉电阻默认无输入时保持低电平。适用场景高电平有效的按键检测。模拟输入GPIO_MODE_ANALOG关闭施密特触发器和数字通道输入直接连到 ADC 转换器。适用场景ADC 电压采集、低功耗省电模式。2.2 输出模式Output开漏输出GPIO_MODE_OUTPUT_OD上管 P-MOS 始终关闭仅 N-MOS 导通。输出 $0$ 时接 GND输出 $1$ 时呈现高阻态。适用场景需要线与逻辑的通信总线如 I2C、或者需要通过外部上拉驱动不同电压等级驱动如 5V 逻辑。推挽输出GPIO_MODE_OUTPUT_PPP-MOS 和 N-MOS 交替导通。输出 $1$ 时强拉高输出 $0$ 时强拉低驱动能力强通常最大可达 20mA。适用场景驱动 LED、蜂鸣器、开关管、SPI 时钟线等。复用开漏GPIO_MODE_AF_OD由片上外设如 I2C直接控制引脚硬件自动切换开漏输出模式。复用推挽GPIO_MODE_AF_PP由片上外设如 USART_TX、PWM、SPI_SCK控制推挽输出。3.完整代码实现基于 STM32CubeMX HAL 库3.1 STM32CubeMX 配置步骤打开 CubeMX选择STM32F103C8T6。将PC13引脚配置为GPIO_Output默认 High推挽模式。将PA0引脚配置为GPIO_Input并在 GPIO 配置栏将GPIO Pull-up/Pull-down设置为Pull-up。在SYS中将 Debug 设置为Serial Wire。生成工程并在 Keil 中打开。3.2 C 语言代码实现 (main.c)#include main.h /* 私有函数声明 */ void SystemClock_Config(void); static void MX_GPIO_Init(void); /** * brief 应用程序入口 */ int main(void) { /* 复位所有外设初始化 Flash 接口和 SysTick */ HAL_Init(); /* 配置系统时钟 (72MHz) */ SystemClock_Config(); /* 初始化所有已配置的 GPIO 引脚 */ MX_GPIO_Init(); /* 初始化 LED 状态设置为高电平灭 */ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); /* 主循环 */ while (1) { /* 读取 PA0 引脚的电平状态 */ if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) GPIO_PIN_RESET) { /* 软件消抖延时 20ms */ HAL_Delay(20); /* 再次确认按键是否依然被按下 */ if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) GPIO_PIN_RESET) { /* 翻转 PC13 引脚电平实现 LED 亮灭切换 */ HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); /* 等待按键释放 (松手检测) */ while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) GPIO_PIN_RESET) { // 空等待 } } } } }
返回列表