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-8
import RPi.GPIO as GPIO
import time
GPIO.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:
#清空GPIO
GPIO.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 GPIO
import time
# 设置GPIO模块的警告提示,取消
GPIO.setwarnings(False)
# 设置为BCM引脚
GPIO.setmode(GPIO.BCM)
# 设置引脚号,IN18
IN = 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:
# 清空GPIO
GPIO.cleanup()
无论是哪种模式,明明按了1次,却输出很多次,这是为什么呢?轮询模式的编程错误,以及没有顾虑到按键的防抖。实际上,按键按下的一瞬间,会有多个脉冲,故会判定多次按下,需要通过代码进行防抖。
6、输入防抖
#!/usr/bin/python
#-*- coding: utf-8 -*
# 导入模块
import RPi.GPIO as GPIO
import time
# 设置GPIO模块的警告提示,取消
GPIO.setwarnings(False)
# 设置为BCM引脚
GPIO.setmode(GPIO.BCM)
# 设置引脚号,IN18
IN = 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:
# 清空GPIO
GPIO.cleanup()