先搞懂它是什么
- GPIO(通用输入输出):芯片引脚里“既能读又能写”的那一类,可以输出高/低电平去点亮 LED,也可以读取外部按键按下与否,是嵌入式里最基础的“开关”和“眼睛”。
- 读与写:写引脚 = 控制输出电平(相当于拨开关);读引脚 = 采样外部电平(相当于看开关状态)。
- 为什么要点灯/按键入门:GPIO 覆盖了“输出、输入、上拉、中断”四大基本功,后面所有外设都建立在同样的引脚控制思路上。
层层拆解原理
1. 引脚内部结构:输出驱动器与输入采样
每个 GPIO 引脚内部大致由“输出驱动器 + 输入采样器 + 上下拉电阻”组成,配置不同模式就是切换这些内部电路:
2. 输出模式:推挽与开漏
| 模式 | 结构 | 特点 | 典型用途 |
|---|---|---|---|
| 推挽输出 | 高电平由管子“推”上去,低电平“拉”下来 | 驱动能力强、速度快 | 点亮 LED、驱动蜂鸣器 |
| 开漏输出 | 只能拉低,高电平靠外部上拉电阻 | 可接不同电压、可“线与” | I2C、共享总线、电平转换 |
开漏输出的“线与”特性:多个开漏输出并联时,只要有一个输出低电平,总线就是低——这是 I2C 能一主多从共线的物理基础。
3. 输入模式:浮空 / 上拉 / 下拉
- 浮空输入:引脚悬空时电平不确定,易受干扰,一般不用。
- 上拉输入:内部/外部电阻把默认电平拉到高,按键接地时按下变低——最常用的按键接法。
- 下拉输入:默认电平为低,按键接电源时按下变高。
判断“按键按下是高还是低”,取决于按键另一端接的是地还是电源,以及引脚默认电平,接反了就会出现“没按像按了、按了没反应”。
4. 复用功能(Alternate Function)
GPIO 不只是 GPIO:串口 TX/RX、SPI 时钟、PWM 输出等都要占用引脚。每个引脚可以“复用”成多种外设功能,通过引脚复用配置(SDK 里常见 GLB_GPIO_Func_Init 一类接口)选择。这也是“引脚不够用、想换脚”时首先要查的东西:先看该引脚支持哪些复用。
5. 电平与驱动能力
- 高电平/低电平是相对的:3.3V 系统里“1”≈ 3.3V、“0”≈ 0V,但“1”的判定阈值通常低于 3.3V(如 ≥2.0V 就视为 1)。
- 驱动能力决定能带多少负载:点亮一个 LED 需要几毫安,直接驱动继电器/电机则必须加三极管或驱动芯片,否则引脚会被“拖垮”。
结合 SDK 看实现
以点灯例程为例,SDK 初始化一个 GPIO 输出口的典型过程是“定义设备结构体 → 配置模式 → 写电平”(WB2 SDK 使用 HOSAL 统一外设层,直接定义 hosal_gpio_dev_t 结构体变量传给 init,没有旧设备模型那种“取设备句柄”的写法):
hosal_gpio_dev_t led; /* 直接定义设备结构体,无需 get_by_name */
/* 配置 GPIO3 为 GPIO 输出(Ai-WB2-32S-Kit 板载蓝色 LED,高电平点亮) */
led.config = HOSAL_GPIO_OUTPUT_PUSH_PULL; /* 推挽输出 */
hosal_gpio_init(&led);
hosal_gpio_output_set(&led, 1); /* 输出高电平,灯亮 */按键输入则先配成输入模式并打开上拉,再在循环里读电平,或者配成中断:
hosal_gpio_dev_t btn; /* 直接定义设备结构体,无需 get_by_name */
/* 按键一端接地,配成上拉输入:默认高,按下为低 */
btn.config = HOSAL_GPIO_INPUT_PULL_UP;
hosal_gpio_init(&btn);
uint8_t val;
hosal_gpio_input_get(&btn, &val); /* 读到 0 表示按下 */(HOSAL 底层也封装了寄存器层 API,如 bl_gpio_enable_output(pin, pullup, pulldown)、bl_gpio_output_set(pin, value),SDK 的基础例程里同样常见这种写法。)
常见考点 / 面试题
推挽输出和开漏输出有什么区别?什么场景用开漏?
推挽能主动输出高低电平、驱动强;开漏只能拉低,高电平靠上拉电阻。I2C、多设备共享总线、跨电压电平转换时用开漏。
按键为什么常配上拉电阻?
上拉让引脚默认是高电平,按键接地按下时才变低,这样“松开=1、按下=0”状态明确,避免悬空导致电平不确定。
什么是引脚复用?为什么要复用?
一个引脚可在 GPIO 与多种外设功能之间切换,这就是复用。芯片引脚有限,复用让串口、SPI、PWM 等共享引脚,通过配置选择当前功能。
GPIO 能直接驱动继电器/电机吗?
不能。继电器/电机需要较大电流,必须用三极管、MOS 管或专用驱动芯片(必要时加续流二极管),否则会损坏引脚或导致系统复位。
软件消抖和硬件消抖分别怎么做?
软件:检测到电平变化后延时几毫秒再确认,或周期性采样;硬件:按键并联电容或加 RC 滤波。两者都是为了防止机械抖动产生多次触发。
遇到问题?
如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

