购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

6.3 使用RPi.GPIO模块

RPi.GPIO是Python的一个模块,树莓派系统默认已经安装了该模块。本节将详细介绍如何使用Python的RPi.GPIO模块控制GPIO。

6.3.1 基本用法

用下面的代码导引RPi.GPIO模块:

 
     import RPi.GPIO as GPIO

引入之后,就可以使用GPIO模块中的函数了。检查模块是否引入成功的代码如下:

在RPi.GPIO中,同时支持树莓派上的两种GPIO引脚编号:

BOARD编号,它和树莓派开发板上的物理引脚编号相对应。使用这种编号的好处是,硬件将是一直可以使用的,不用担心树莓派的版本问题。因此,在开发板升级后,不需要重写连接器或代码。

BCM编号,使用更底层的工作方式,是指Broadcom SOC上的通道号。在使用一个引脚时,需要查找信道号和物理引脚编号之间的对应规则。对于不同的树莓派版本,编写的脚本文件可能是无法通用的。

使用下列代码(强制的)指定一种编号规则:

或者使用下面代码查看设置的编号规则:

 
     mode = GPIO.getmode()

Raspberry Pi的GPIO上可能有多个脚本/电路,如果RPi.GPIO检测到某个引脚已配置为默认值(输入)以外的其他值,则在尝试配置脚本时会收到警告。可以通过下面代码禁用这些警告:

 
     GPIO.setwarnings(False)

在使用一个引脚前,需要设置引脚作为输入还是输出。配置一个引脚的代码如下所示:

也可以一次设置多个通道(从0.5.8开始),例如:

需要读取引脚的输入状态时可使用如下代码获得:

如果想点亮一个LED,或者驱动某个设备,设置引脚的输出状态即可,代码如下:

如果想一次性设置多个引脚,可使用下面的代码:

一般来说,程序运行到最后都需要释放资源,可以避免损坏树莓派。释放脚本中使用的引脚的代码如下:

最后,如果要查看RPi开发板信息和RPi.GPIO版本,可以使用如下代码:

6.3.2 模块的输入

我们在上一节介绍了可通过下面代码获取引脚的输入状态:

如果输入引脚处于“悬空状态”(没有连接任何元件),引脚的值将是漂动的,即读取到的值是未知的,因为它并没有被连接到任何信号上,直到按下一个按钮或开关。由于干扰的影响,输入的值可能会反复变化。

为了解决这个问题,可以使用硬件或软件对电阻进行上拉/下拉。使用硬件方式,常将一个10kΩ的电阻连接在输入通道与3.3V(上拉)或0V(下拉)之间。RPi.GPIO也可以通过软件的方式配置Broadcom SOC来达到目的,代码如下:

需要注意的是,上面的读取代码只是获取当前一瞬间的引脚输入信号。如果需要实时监控引脚的状态变化,通常有两种方法。

最简单的方式是每隔一段时间检查输入的信号值,这种方式被称为轮询。如果程序读取的时机错误,则很可能会丢失输入信号。轮询是在循环中执行的,这种方式比较占用处理器资源。具体代码如下:

另一种响应GPIO输入的方式是使用中断(边缘检测),这里的边缘是指信号状态的改变,从低到高(上升沿)或从高到低(下降沿)。通常情况下,我们更关心输入状态的改变而不是输入信号的值,这种状态的改变被称为“事件”。为了避免程序忙于做其他事情时按下按钮,有两种方法可以解决这个问题:

使用wait_for_edge()函数。wait_for_edge()用于阻止程序的继续执行,直到检测到一个边沿。也就是说,上面代码中等待按钮按下的实例可以改写为:

使用add_event_detect()函数。该函数对一个引脚进行监听,一旦引脚输入状态发生了改变,调用event_detected()函数返回true,可参考如下代码:

上面的代码需要新建一个线程循环检测event_detected()的值,比较麻烦。可采用另一种办法轻松检测状态,其方式是直接传入一个回调函数:

如果想设置多个回调函数,可以使用如下代码:

注意

回调触发时,并不会同时执行回调函数,而是根据设置的顺序调用它们。

不难发现,每次按下按钮时,回调操作不止一次被调用。这种现象称作开关抖动(switch bounce)。通常有两种方法解决开关抖动问题。第一种是将一个0.1μF的电容连接到开关上,第二种是使用软件防止抖动,在指定的回调函数中添加bouncetime=参数。而大多数情况下,是两种方式一起用。在使用软件去除抖动时,抖动时间需要使用ms为单位进行书写,参考如下代码:

如果不希望程序检测边缘事件,可以将它停止:

 
     GPIO.remove_event_detect(channel)

6.3.3 脉冲宽度调制

脉冲宽度调制(Pulse Width Modulation,PWM)是指用微处理器的数字输出来对模拟电路进行控制,通过控制固定电压的直流电源开关频率,改变负载两端的电压,从而达到控制要求的电压调整方法,其应用非常广泛,可以用于控制直流电机的转速、舵机转角角度等。为更好地理解和使用PWM,我们首先需要了解以下两个概念:

频率。频率以Hz为单位,它是一个脉冲信号时间周期的倒数。如果PWM的输出频率比较低,例如只有5Hz,那么在控制一个LED时,LED就会一闪一闪的,较高的频率可以让运行更为平滑,但PWM的输出频率并不能无限提高,而且在高频情况下,测定的PWM频率与作为树莓派参数提供的频率略有出入。因此,在使用PWM时,应该选择一个合适的频率,对于控制一个LED的亮度,一般100Hz就足够了。

占空比。占空比是输出的PWM脉冲信号中,高电平保持的时间与该PWM的时钟周期之比,如图6.8所示,占空比= t 1/ T = t 1/( t 1+ t 2)。假设PWM脉冲的频率为1000Hz,那么它的时钟周期 T 就是1ms(即1000μs),如果高电平持续时间 t 1为200μs,低电平的时间 t 2为800μs,那么占空比就是200:1000(即1:5)。

图6.8 PWM脉冲信号

从应用的角度,可以简单地将PWM理解为通过改变脉冲信号的频率和高电平的持续时间(或占空比)来实现电压控制的一种方法。图6.9显示了三个由GPIO输出的PWM信号(电压为3.3V),第一个信号是一个占空比为20%的PWM输出,即在信号周期中,20%的时间为高电平(1),其余80%的时间为低电平(0),对应的电压为满幅值的20%(0.66V)。第二、三个信号分别是占空比为50%和80%的PWM输出,对应的电压分别为1.65V和2.64V。

图6.9 GPIO输出PWM信号

在树莓派上,可以通过对GPIO的编程来实现PWM,RPi.GPIO库提供了PWM功能。下面代码为PWM功能的简单应用。

也可以参考以下代码示例,其可使LED每2s闪烁一次:

注意

如果实例中的变量p超出范围,也会导致PWM停止。 fQKUAlbG7ZXJOo34Eb3ZK3kN/EFlYmYYhkILBaEVV/XgnP8yQl+0vTA/l90yISRh

点击中间区域
呼出菜单
上一章
目录
下一章
×