1、相关术语
树莓派装载的芯片:BCM2835是一个MCU微处理器,它可以理解为CPU+其它模块的组合。
GPIO:General-purpose input/output,通用型输入输出,其接脚可以供使用者由程控自由使用,PIN脚依现实考量可作为通用输入(GPI)或通用输出(GPO)或通用输入与输出(GPIO)。
GPIO输入:就是输入一个电压信号,可以理解为开关打开后电流可以注入的端口。
GPIO输出:让这个端口输出电,让外接设备通电。当然也可以控制断电。
编程使用时,需要导入RPI包中的GPIO模块, as 将此导入的结果用GPIO表示。
#导入模块
import RPi.GPIO as GPIO
查看GPIO情况:
sudo gpio readall
注意引脚号,用python编程使用的都是BCM编号。 树莓派外接40引脚,排列在板子的一侧。 引脚可以插入拓展模块,方便操作。
2、常见使用(输出)
#设置是否打印警告
GPIO.setwarnings(True/False)#GPIO编号格式,我们选择BCM
GPIO.setmode(GPIO.BOARD/GPIO.BCM)#设置引脚为输出,初始化高电平还是低电平,默认低电平。
GPIO.setup(channel,GPIO.OUT,initial=GPIO.HIGH/GPIO.LOW)#输出引脚高电平或低电平。
GPIO.output(channel,GPIO.HIGH/GPIO.LOW)
3、简单使用(输出)
#!/usr/bin/env python
#coding:utf-8import RPi.GPIO as GPIO
import timeGPIO.setwarnings(False)#设置为BCM引脚
GPIO.setmode(GPIO.BCM)#设置引脚号,LED18
LED=18#将引脚设置为输出,初始化为低电平
GPIO.setup(LED,GPIO.OUT,initial=GPIO.LOW)#设置PWM,设置频率0.5hz
pwm=GPIO.PWM(LED,0.5)#设置占空比50,即50%高电平,50%低电平
pwm.start(50)#闪烁
try:while True:time.sleep(1)
except KeyboardInterrupt:#清空GPIOGPIO.cleanup()
4、常风方法(输入)
轮询、边缘检测、线程回调。
#设置引脚为输入。
GPIO.setup(channel,GPIO.IN,pullupdown=GPIO.PUDUP/GPIO.PUDDOWN)#读取引脚高电平或低电平。
GPIO.input(channel)#读取引脚上升沿、下降沿或都获取
GPIO.waitforedge(channel,GPIO.RISING/GPIO.FALLING/GPIO.BOTH)#加入线程事件循环
GPIO.addeventdetect(channel,GPIO.RISING/GPIO.FALLING/GPIO.BOTH)#添加回调函数
GPIO.addeventcallback(channel, callback)#添加线程事件循环,防抖200毫秒
GPIO.addeventdetect(channel,GPIO.RISING/GPIO.FALLING/GPIO.BOTH, callback=callback, bouncetime=200)#停止线程事件循环
GPIO.removeeventdetect(channel)
5、简单使用输入
#!/usr/bin/python
#-*- coding: utf-8 -*# 导入模块
import RPi.GPIO as GPIOimport time# 设置GPIO模块的警告提示,取消
GPIO.setwarnings(False)# 设置为BCM引脚
GPIO.setmode(GPIO.BCM)# 设置引脚号,IN18IN = 18# 将引脚设置为输入
GPIO.setup(IN,GPIO.IN,pull_up_down=GPIO.PUD_UP)# 轮询输入
def inputPolling():while True:while GPIO.input(IN) == GPIO.LOW:time.sleep(0.1)print '按键轮询输入获取成功'# 边缘检测
def inputEdge():while True:GPIO.wait_for_edge(IN,GPIO.RISING)print '按键边缘检测输入成功'# 边缘检测
def myCallback(channel):print '按键线程回调输入成功'# 线程回调
def inputEvent():GPIO.add_event_detect(IN,GPIO.BOTH)GPIO.add_event_callback(IN,callback=myCallback)while True:time.sleep(0.01)try:inputPolling();#inputEdge();#inputEvent();except KeyboardInterrupt:# 清空GPIOGPIO.cleanup()
无论是哪种模式,明明按了1次,却输出很多次,这是为什么呢?轮询模式的编程错误,以及没有顾虑到按键的防抖。实际上,按键按下的一瞬间,会有多个脉冲,故会判定多次按下,需要通过代码进行防抖。
6、输入防抖
#!/usr/bin/python#-*- coding: utf-8 -*# 导入模块
import RPi.GPIO as GPIOimport time# 设置GPIO模块的警告提示,取消
GPIO.setwarnings(False)# 设置为BCM引脚
GPIO.setmode(GPIO.BCM)# 设置引脚号,IN18IN = 18# 将引脚设置为输入
GPIO.setup(IN,GPIO.IN,pull_up_down=GPIO.PUD_UP)# 轮询输入,防抖
def inputPolling():while True:if GPIO.input(IN)==GPIO.HIGH:time.sleep(0.01)if GPIO.input(IN)==GPIO.HIGH:print '按键轮询输入获取成功'while GPIO.input(IN)==GPIO.HIGH:time.sleep(0.01)# 边缘检测,防抖
def inputEdge():while True:GPIO.wait_for_edge(IN,GPIO.RISING)time.sleep(0.01)if GPIO.input(IN)==GPIO.HIGH:print '按键边缘检测输入成功'# 边缘检测
def myCallback(channel):print '按键线程回调输入成功'# 线程回调
def inputEvent():GPIO.add_event_detect(IN,GPIO.BOTH)GPIO.add_event_callback(IN,GPIO.RISING,callback=myCallback,bouncetime=10)while True:time.sleep(0.01)try:inputPolling();#inputEdge();#inputEvent();except KeyboardInterrupt:# 清空GPIOGPIO.cleanup()