因为觉得之前买的开发板底板的引出接口使用起来不方便(标识不清晰,以及3.3V
和GND
引出的插针太少),我又买了一个开发板底板,这个板子的引出插针很多,且每个引出的GPIO
都“配备”了3.3V
和GND
的插针,方便外接设备,板子上也给了 7V~12V 的直流电源输入口,方便单独接入直流适配器
作为电源。 他的缺点是板子上没有任何外设(只有一个按钮,是复位
按钮)。
从照片中可以看到,我还将树莓派Pico装上了亚克力“铠甲”来保护它。
然后,我将一个轻触按键连接到GP14
上。将按键扩展板上的SW1
接到GP14
的黄色插针(即GPIO14
),GND
接到GP14
的黑色插针(即GND
)。 接好以后,连接USB到电脑。
在 Thonny 中连接树莓派Pico,新建如下代码,并运行。
'''
实验名称:按键(GPIO)
版本:v1.0
日期:2021-1
作者:01Studio
社区:www.01studio.org
'''
from machine import Pin
#构建LED对象
led=Pin(25, Pin.OUT)
#配置按键
key = Pin(14, Pin.IN, Pin.PULL_UP)
while True:
if key.value()==0: #KEY被按下接地
led.high() #点亮LED
else:
led.low() #关闭LED
运行后,按下蓝色按键,Pico上的绿色LED会亮起,松开按键,绿色LED会熄灭。 Pico成功检测到了按键。
需要注意的是,程序中的第15行语句 key = Pin(14, Pin.IN, Pin.PULL_UP)
中 Pin.PULL_UP
参数是配置GPIO14为上拉。上拉的意思是,如果按键没有按下,GPIO检测到的是1
,如果有按键按下,则检测到的是0
。
如果我们希望按一下按键,LED点亮,再按一下熄灭呢?
修改程序代码为如下:
from machine import Pin
import time
#构建LED对象
led=Pin(25, Pin.OUT)
#配置按键
key = Pin(14, Pin.IN, Pin.PULL_UP)
while True:
if key.value()==0: #KEY被按下接地
led.toggle() # 翻转LED的状态,即点亮或熄灭LED
# 如下延迟模拟程序中的其他任务,耗时20ms
time.sleep(0.02)
第13行语句led.toggle()
是翻转LED显示状态的意思。
但是运行这一段程序,会发现,按下按键,LED会非常快速的闪烁很多次,最后可能是亮起,也可能是熄灭。 这是因为处理器运行程序的速度太快了,以至于一次按键的时间内,上面的程序循环运行了很多次,也就看到了LED的亮灭翻转了很多次,并在最后停留在亮或者灭的(不确定)状态。
我们如果反复按下松开按键的同时,用示波器观察GPIO14
接口的波形,可以观察到每次按键的时间。
上图波形中,低电平(0
)代表了按键被按下,高电平(1
)代表了按键被松开。 可以看到某一次按键按下的时间是120ms。
而下图可以看到某一次按键松开后,在下一次按键按下前的高电平时间是145ms。
因此,我们在检测到按键按下后,延迟几十毫秒,再检测一次按键,如果仍然是按下的状态,则判断为一次按键按下。
from machine import Pin
import time
#构建LED对象
led=Pin(25, Pin.OUT)
#配置按键
key = Pin(14, Pin.IN, Pin.PULL_UP)
while True:
if key.value()==0: #KEY被按下接地
time.sleep(0.08) # 等待80ms
if key.value()==0: # 再检测一次按键,如果任然是按键按下的状态则认为检测到一次按下
led.toggle() # 翻转LED的状态,即点亮或熄灭LED
# 如下延迟模拟程序中的其他任务,耗时20ms
time.sleep(0.02)
运行这段程序后,LED的显示对按键的响应基本上是我们希望的情况了,但是有时候仍然会出现按下了按键,LED并不会亮灭变化(按键过快时),或者LED闪烁(按键太慢时)的情况。这说明,这部分按键检测的程序仍然需要加以优化。上面的按键检测程序只是一些最基本的代码,仅仅能演示树莓派Pico基本的按键检测功能(GPIO的输入功能)。
事实上,在成熟产品中,按键的检测程序比上面的代码要复杂很多,以适应按键的短按、长按、双击,按键按下瞬间因为按键触点短时间接触不稳定而发生的信号“抖动”,以及外界的干扰等等各种复杂情况。 今天就没时间做更多的尝试了。