当前位置:首页 > 飞机Telegram算计机器人 > 正文内容

飞机Telegram算计机器人 按键接到 STM32 后:GPIO 输入到底读到了什么

---

按键接到 STM32 后:GPIO 输入到底读到了什么

2026 年 9 月 22 日 | 作者:Zw-awa


---

核心洞察

按键没有把"我被按了一次"直接送进芯片,它只改变了 GPIO 引脚上的电平。 芯片读到的是高电平或低电平,不是"按钮"或"按了一次"这些带有含义的动作。[citation:72.48]


---

一、按键的物理接线


最基础的接法:


PB11 ──┬── 按键 ── GND

 │

 [内部上拉电阻] → VCC(3.3V)


| 按键状态 | 电气连接 | GPIO 读到的电平 |

|:--------:|:---------|:--------------:|

| 松开 | 内部上拉维持高电平 | 1 |

| 按下 | 通过按键接到 GND | 0 |

没有"按下=1"的规定。 1 和 0 只描述引脚电平,哪个代表"按下"由接线方式决定。当前接法是低电平有效。[citation:72.48]


---

二、GPIO 输入配置


#include "stm32f10x.h"


void Key_Init(void)

{

 GPIOInitTypeDef GPIOInitStructure;


 RCCAPB2PeriphClockCmd(RCCAPB2Periph_GPIOB, ENABLE);


 GPIOInitStructure.GPIOMode = GPIOModeIPU; // 上拉输入

 GPIOInitStructure.GPIOPin = GPIOPin1 | GPIOPin11;

 GPIOInitStructure.GPIOSpeed = GPIOSpeed50MHz;

 GPIOInit(GPIOB, &GPIOInitStructure);

}


GPIOModeIPU 的作用:在按键松开、外部没把引脚拉到地时,给引脚一个确定的默认高电平。 [citation:72.48]


---

三、读取电平 vs 翻译成"按下"

读电平——只回答"这一刻是高还是低"


uint8t KeyA_ReadLevel(void)

{

 return (uint8t)GPIOReadInputDataBit(GPIOB, GPIOPin11);

}

翻译成"按下"


uint8t KeyA_IsPressed(void)

{

 return KeyAReadLevel() == Bit_RESET;

}


电路细节留在按键模块里面,主循环只需要判断 KeyAIsPressed()。[citation:72.48]


---

四、从"当前电平"到"一次按键"


直接读电平的问题是:按住按键时,函数会一直返回"按下"。实际工程通常需要把"持续的低电平"整理成"一次按下事件":


uint8t KeyGetNum(void)

{

 uint8_t KeyNum = 0;

 volatile uint32_t i;


 if (GPIOReadInputDataBit(GPIOB, GPIOPin1) == BitRESET)

 {

 // 消抖延时

 for (i = 0; i < 72000U; i++) { }


 // 等松手

 while (GPIOReadInputDataBit(GPIOB, GPIOPin1) == BitRESET) { }


 // 松手消抖

 for (i = 0; i < 72000U; i++) { }


 KeyNum = 1;

 }

 return KeyNum;

}


关键:确认按下 → 小延时 → 等松手 → 再延时 → 返回编号。避免手指一直按着时反复返回同一个值。[citation:72.48]


---

五、四种输入模式


| 模式 | 引脚内部 | 什么时候用 |

|:----|:---------|:-----------|

| GPIOModeIPU 上拉输入 | 内部接上拉电阻,没人驱动时读到高 | 按键另一端接 GND(最常见) |

| GPIOModeIPD 下拉输入 | 内部接下拉电阻,没人驱动时读到低 | 按键另一端接 VCC |

| GPIOModeIN_FLOATING 浮空输入 | 内部什么都不接,完全由外部决定 | 外部已有明确上拉/下拉,或由推挽输出驱动 |

| GPIOModeAIN 模拟输入 | 关掉数字输入通路 | ADC 采样模拟电压 |

浮空输入的陷阱


把 GPIOModeIPU 改成 GPIOModeIN_FLOATING,松开按键时 PB11 就没有内部上拉提供默认电平。此时引脚既没有明确接高也没有明确接低——周围的电线、手指和电磁干扰都可能影响它。 [citation:72.48]

浮空输入不是"自动随机数",而是电路没有为引脚规定稳定的 0 或 1。输入模式的选择必须和接线一起看。


---

六、常见排查链路


当按键读值不对时,按这条链路检查:[citation:72.48]


① 按键有没有把引脚接到正确的位置?

② 输入有没有配置默认上拉或下拉?

③ 读取的引脚是否和接线一致?

④ 上层动作有没有重复执行?(消抖处理了吗?)


---

七、关键差异速查


| 方向 | 芯片做的事 | 典型对象 |

|:----:|:----------|:---------|

| GPIO 输出 | 芯片主动改变引脚电平 | LED、继电器使能、电机方向 |

| GPIO 输入 | 芯片读取引脚当前电平 | 按键、开关、传感器 DO |


同一个引脚不能只看代码里的函数名判断功能,最终还要看它连接的电路。 [citation:72.48]


---

八、一句话总结

GPIO 输入读到的是瞬时电平,不是按键事件。 把电平翻译成"按下/松开"是程序的工作——上拉输入给引脚一个确定的默认状态,消抖逻辑把机械噪声过滤成干净的事件,状态机把连续电平整理成单次触发。读值不对先查接线和输入模式,不要盲目调代码。[citation:72.48]


相关文章

飞机Telegram算计机器人 用 | 代替 / 做分隔符——路径里全是 /,再用 / 当分隔符就得疯狂转义。

  不用检索,sed 批处理是稳定知识。这道题正好是今天博客园同一天发的文章标题 [citation:26.9],我直接讲最常用的几种模式。---核心命令sed -i 's...

飞机Telegram算计机器人 C# .NET 周刊 |2026 年 9 月 1 期

C# .NET 周刊 |2026 年 9 月 1 期合集 - .NET周刊(122)1..NET周刊【8月第1期 2023-08-06】2023-08-102..NET周刊【8月第2期 2023-08...

飞机Telegram算计机器人 堡垒机对高危命令或敏感用户切换进行拦截,主要基于以下安全

在堡垒机环境中,su - oracle 被拦截通常是出于安全合规与审计控制的考虑,旨在防止越权操作、确保操作可追溯以及保护关键业务账户(如 Oracle 数据库账户)。‌直接“绕过”限制不仅违反运维安...

飞机Telegram算计机器人 平方阶迭代算法的优化核心在于‌降低时间复杂度‌,通常通过“空间换时间”

平方阶迭代算法的优化核心在于‌降低时间复杂度‌,通常通过“空间换时间”、“利用数据有序性”或“数学性质简化”等手段,将其优化为线性阶 𝑂(𝑛)O(n) 或对数阶 𝑂(log⁡𝑛)O...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。