☰
【嵌入式外设精学】Day01|GPIO 输入:上拉、下拉、浮空怎么选
2026/9/25 22:02:35 网站建设 项目流程

【嵌入式外设精学】Day01|GPIO 输入:上拉、下拉、浮空怎么选

今天解决:按键和空闲线到底该上拉还是下拉?为什么悬空脚会“乱跳”?


目录

  1. 今天解决什么问题
  2. 原理
  3. 代码示例
  4. 常见误区
  5. 自测
  6. 答案

1. 今天解决什么问题

  • 按键有时灵、有时不灵
  • 没接东西的引脚读数乱跳
  • 不知道“上拉/下拉/浮空”在电路上到底意味着什么

一句话:输入脚在空闲时必须有确定电平(高或低),不能靠运气。


2. 原理

2.1 三种输入方式

方式空闲时脚上的电平适合
上拉被电阻拉到高键按下接地时读到 0
下拉被电阻拉到低键按下接电源时读到 1
浮空没人定电平仅当外部一直有器件驱动

浮空 = 高阻抗,像一根天线,噪声会当信号,中断可能误触发。

2.2 和按键怎么配对

硬件上按键把脚短接到哪一端,输入就配相反的默认电平:

硬件配置按下松开
键一端接地上拉输入读 0读 1
键一端接 3.3V下拉输入读 1读 0

配反了:怎么按读数都不变。

2.3 内部上拉 vs 外部上拉

内部外部
优点省元件,软件开一下就行更“有力”,抗干扰好
缺点电阻偏大,力偏弱要焊电阻
建议板载短按键长线、噪声大、I2C 等

I2C 这类开漏总线,一般必须外部上拉,不能只靠内部。

2.4 为什么有时“阈值边上”会抖

脚电压刚好落在芯片认 0 / 认 1 的交界区时,轻微噪声就会来回判。
所以:电压要尽量靠“确定的高”或“确定的低”,并留出噪声余量。


3. 代码示例

#include"stm32f4xx.h"#include<stdbool.h>voidkey_gpio_init(void){GPIO_InitTypeDef g;GPIO_StructInit(&g);g.GPIO_Pin=GPIO_Pin_0;g.GPIO_Mode=GPIO_Mode_IN;g.GPIO_PuPd=GPIO_PuPd_UP;/* 键接地 → 上拉 */GPIO_Init(GPIOA,&g);}/* 读原始电平:1=高,0=低 */boolkey_raw_is_low(void){returnGPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==Bit_RESET;}/* 极性统一:1 = 按下 */boolkey_is_pressed(void){returnkey_raw_is_low();/* 上拉+接地,按下为低 */}

消抖(在定时器里周期调用,不要在死循环里delay):

#include<stdbool.h>#include<stdint.h>typedefstruct{bool raw_last;bool stable;uint8_tcnt;}key_filter_t;/* 1ms 调一次;true 表示稳定按下 */boolkey_filter_update(key_filter_t*f,bool pressed_now){if(pressed_now==f->raw_last){if(f->cnt<15u){f->cnt++;}}else{f->raw_last=pressed_now;f->cnt=0u;}if(f->cnt>=10u){f->stable=f->raw_last;}returnf->stable;}

4. 常见误区

误区正解
空脚不用配,放着就行要上下拉或设为输出确定电平
内部上拉一定能替代 I2C 上拉不行
读键直接if(pin)就完事要消抖,并统一“按下=1”
5V 器件随便接 3.3V 脚可能损坏,先看是否 5V-tolerant

5. 自测

  1. 按键一端接 3.3V,希望松开读 0、按下读 1,输入怎么配?
  2. 为什么中断唤醒的键,更建议硬件上拉而不是只靠内部?

6. 答案

  1. 下拉输入。
  2. 空闲电平更确定,抗干扰更好,上电/睡眠阶段也不容易误唤醒。

作者:shuifanyu
标签:GPIO上拉下拉按键嵌入式

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询