一 本章简介
本章介绍 MicroPython 中按键检测的各种方式:轮询检测、软件消抖、中断响应,以及按键与 LED 联动的综合应用。天空星核心板有 1 个用户按键(PA0),筑基学习板额外提供 2 个按键(PE8、PC13),共 3 个可用按键,虽然 PC13 接在一个旋转编码器上,但它也可以直接被按下。
IMPORTANT
如果你把天空星核心板安装到了筑基学习板上,请直接按筑基学习板上面的 PA0 按键,此时核心板上的按键有可能不生效,因为电路上存在分压问题。

1.1 学习目标
| 序号 | 学习目标 | 重要程度 |
|---|---|---|
| 1 | 掌握使用 pyb.Switch 检测 PA0 板载按键的方法 | ⭐⭐⭐⭐⭐ |
| 2 | 掌握使用 Pin 读取 PE8、PC13 按键的通用方法 | ⭐⭐⭐⭐⭐ |
| 3 | 理解按键抖动的原因,掌握软件消抖方法 | ⭐⭐⭐⭐⭐ |
| 4 | 掌握使用外部中断(ExtInt)响应按键事件 | ⭐⭐⭐⭐ |
| 5 | 能够实现三键联动、长按短按等进阶功能 | ⭐⭐⭐ |
1.2 重点提示
- PA0、PE8、PC13 三个按键全部都是按下为高电平,未按下为低电平(外部下拉)。
- 机械按键在按下和松开的瞬间,由于触点的物理弹性,会产生几毫秒到几十毫秒的电平抖动,必须进行消抖处理,否则一次按键会被误判为多次。使用中断方式时同样需要消抖,否则一次按下可能触发多次中断。
- 轮询方式简单直观,但 CPU 需要不断检查按键状态;中断方式效率高,但回调函数有严格限制。
- 在中断回调函数中不能调用
print()、time.sleep()等耗时函数,只能设置标志位,在主循环中处理实际逻辑。
1.3 硬件说明
1.3.1 三个按键的电路特性
三个按键的接法相同,均为按下接 3.3V,内部下拉,按下为高电平(1):
原理图如下: 
- 未按下:引脚通过内部下拉接 GND → 低电平(0)
- 按下:引脚通过按键连接到 3.3V → 高电平(1)
1.3.2 按键资源汇总
| 按键 | 引脚 | 按下电平 | 未按下电平 | 上下拉 | pyb.Switch 支持 |
|---|---|---|---|---|---|
| 核心板用户按键(筑基学习板按键1) | PA0 | 高电平(1) | 低电平(0) | 内部下拉 | ✅ |
| 筑基学习板按键2 | PE8 | 高电平(1) | 低电平(0) | 内部下拉 | ❌ |
| 筑基学习板按键3(编码器按下) | PC13 | 高电平(1) | 低电平(0) | 内部下拉 | ❌ |
1.3.3 按键抖动示意
机械按键在按下瞬间,触点会发生弹跳,产生如下波形:

如果不做消抖,一次按键可能被检测为多次触发。中断方式也不例外——抖动期间每次电平跳变都会触发一次中断,同样需要在主循环中用时间戳过滤。
三 软件设计
3.1 基础部分
3.1.1 使用 pyb.Switch 检测 PA0
pyb.Switch 是 MicroPython 为板载按键(PA0)提供的专用类:
import pyb
sw = pyb.Switch()
while True:
# 查询按键状态(True=按下,False=未按下)
if sw():
print("PA0 按键被按下")
else:
print("PA0 按键未按下")2
3
4
5
6
7
8
9
10
3.1.2 使用 Pin 读取三个按键
三个按键逻辑相同,均为高电平有效:
from pyb import Pin
import pyb
# 三个按键:内部下拉,按下=高电平
btn_pa0 = Pin('PA0', Pin.IN, Pin.PULL_DOWN)
btn_pe8 = Pin('PE8', Pin.IN, Pin.PULL_DOWN)
btn_pc13 = Pin('PC13', Pin.IN, Pin.PULL_DOWN)
while True:
if btn_pa0.value() == 1:
print("按键1(PA0)按下")
if btn_pe8.value() == 1:
print("按键2(PE8)按下")
if btn_pc13.value() == 1:
print("按键3(PC13)按下")
pyb.delay(50)2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
3.1.3 按键控制 LED
# PA0 控制 PB2,PE8 控制 PB8
from pyb import Pin, LED
import pyb
btn_pa0 = Pin('PA0', Pin.IN, Pin.PULL_DOWN)
btn_pe8 = Pin('PE8', Pin.IN, Pin.PULL_DOWN)
led_pb2 = LED(1) # 板载 LED1
led_pb8 = Pin('PB8', Pin.OUT_PP) # PB8,低电平亮
led_pb8.high() # 初始熄灭
while True:
# PA0 按下:LED1 亮
if btn_pa0.value():
led_pb2.on()
else:
led_pb2.off()
# PE8 按下:PB8 亮(低电平点亮)
if btn_pe8.value():
led_pb8.low()
else:
led_pb8.high()
pyb.delay(20)2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
3.2 进阶部分
3.2.1 软件消抖(通用封装)
将消抖逻辑封装成一个通用类,三个按键均适用:
# 通用按键消抖类(高电平有效)
import pyb
from pyb import Pin
class Button:
"""
通用按键类(高电平有效,内部下拉)
debounce_ms: 消抖时间,默认 30ms
"""
def __init__(self, pin_name, debounce_ms=30):
self.pin = Pin(pin_name, Pin.IN, Pin.PULL_DOWN)
self.debounce_ms = debounce_ms
self._last_press = 0
self._last_state = False
def is_pressed(self):
"""返回当前是否处于按下状态"""
return self.pin.value() == 1
def was_pressed(self):
"""
检测是否发生了一次有效按下(上升沿+消抖)
每次调用只触发一次,适合放在主循环中轮询
"""
current = self.pin.value() == 1
now = pyb.millis()
if current and not self._last_state:
if now - self._last_press > self.debounce_ms:
self._last_press = now
self._last_state = True
return True
elif not current:
self._last_state = False
return False
# 初始化三个按键
btn1 = Button('PA0')
btn2 = Button('PE8')
btn3 = Button('PC13')
led_pb2 = pyb.LED(1)
led_pb8 = Pin('PB8', Pin.OUT_PP)
led_pb8.high()
count1 = count2 = count3 = 0
print("三个按键已就绪,按下任意按键...")
while True:
if btn1.was_pressed():
count1 += 1
led_pb2.toggle()
print("PA0 第 {} 次".format(count1))
if btn2.was_pressed():
count2 += 1
led_pb8.value(not led_pb8.value())
print("PE8 第 {} 次".format(count2))
if btn3.was_pressed():
count3 += 1
print("PC13 第 {} 次".format(count3))
pyb.delay(10)2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
四 常见问题
Q: 按一下按键,触发了好几次?
按键抖动导致。轮询方式参考 3.2.1 节的 Button 类;中断方式参考 3.2.2 节的时间戳消抖方案,消抖时间通常 30~50ms。
Q: 中断方式按键有时没有响应?
检查中断回调函数是否有耗时操作(如 print())。回调只能记录时间戳或设置标志位,实际处理放在主循环中。
Q: 安装到筑基学习板后,核心板上的 PA0 按键没反应?
这是正常现象。核心板安装到筑基学习板后,两块板的 PA0 并联,电路上存在分压问题,核心板上的按键可能不生效。请直接按筑基学习板上的 PA0 按键。
Q: pyb.Switch() 能用于 PE8 或 PC13 吗?
不能。pyb.Switch() 固定对应 PA0,PE8 和 PC13 只能用 Pin 类操作。
五 本节参考文档
- MicroPython pyb.Switch 文档:
- MicroPython pyb.ExtInt 文档:
- MicroPython pyb.Pin 文档:
- 天空星硬件资料(原理图):