#!/usr/bin/python
import RPi.GPIO as GPIO  #导入GPIO
 GPIO.setmode(GPIO.BOARD) #将GPIO引脚设置为BOARD模式
 GPIO.setmode(GPIO.BCM)   #将GPIO引脚设置为BCM引脚方式

 GPIO.setup(pin,GPIO.IN)  #设置GPIO引脚通道 作为输入
 GPIO.setup(pin,GPIO.OUT) #作为输出
 GPIO.setup(pin,GPIO.OUT,initial=GPIO.HIGH) #设置初始化为高电平



#多通道设置方式 

pinlist=[pin1,pin2,pin3,pinx]
 GPIO.setup(pinlist,GPIO.OUT)
 GPIO.setup(pinlist,GPIO.IN)
 


 /**********************读取GPIO的输入值/中断(interrupt)和边沿检测(edge detection)***************/ 

 #读取一个GPIO口的值 

GPIO.input(pin)
 input()方法可以读取目前通道的输出 

 #中断的边沿检测可以为上升沿/上升临界值(rising edge)或者下降沿/下降临界值(falling edge)



如果您在输入针脚上没有连接任何元件,那么它将是“浮动(float)”的。换句话说,因为
您没有连接任何元件,在按下按钮或开关之前,读取的值是没有意义的。由于电源的波动,
获取到的值可能会有很大的变化。
/*********************上下拉方式***********************************/
1.硬件方式:接上/下拉电阻:
将一个 10K 的电阻连接在输入通道与 3.3V(上拉)或 0V(下拉)之间是常用的做法

2.软件实现上/下拉:
RPi.GPIO 也允许您通过软件的方式对配置 Broadcom SOC 来达到目的:

GPIO.setup(pin,GPIO.IN,pull_up_down=GPIO.PUD_UP)
 GPIO.setup(pin,GPIO.IN,pull_up_down=GPIO.PUD_DOWN)



/****************************轮询检测/中断和边沿检测******************************/
一.轮询(polling)检测:

if GPIO.input(pin):
     print 'Input is High'
 else:
     print 'Input is Low'




二.中断和边沿检测:
为了避免您的程序在忙于处理其它的事物时而错过了您按下按钮的操作,这里有两种方法可以解决:
wait_for_edge()函数
add_event_detect() 函数  --该函数对一个引脚进行监听,一旦引脚输入状态发生了改变,调用event_detected()函数会返回true
event_detected()函数   -----在检测到边缘时执行线程回调函数

1.wait_for_edge函数:函数被设计用于在检测到边沿之前阻止程序的运行:
wait_for_edge()函数被设计用于在检测到边沿之前阻止程序的运行:

实例:

GPIO.wait_for_edge(pin,GPIO.RISING)--可以使用GPIO.RISING,GPIO.FALLING,GPIO.BOTH


                                           对边沿进行检测。这种方式占用的CPU资源少。


实例:

# wait for up to 5 seconds for a rising edge (timeout is in milliseconds)
 
channel = GPIO.wait_for_edge(channel, GPIO_RISING, timeout=5000)
 if channel is None:
     print('Timeout occurred')
 else:
     print('Edge detected on channel', channel)

#设置一个超时参数,如果超时,程序将继续运行。如果没有超时参数,程序将一直等待边沿。


2.add_event_detect() 函数  --该函数对一个引脚进行监听,


一旦引脚输入状态发生了改变,调用event_detected()函数会返回True


实例:



GPIO.add_event_detect(channel, GPIO.RISING)  # add rising edge detection on a channel
 do_something()
 // 下面的代码放在一个线程循环执行。
 if GPIO.event_detected(channel):
   print('Button pressed')


注:event_detected()/***多用于循环****/


event_detected()函数被用于循环中有其他东西时使用,不同于轮询的是,他不会错过当cpu忙于其他事物时的输入状态的


改变。这在类似使用Pygame或PyQt时主循环实时监听和响应GUI的时间是很有用的。




线程回调:


RPi.GPIO为回调函数另外开启一个线程。这意味这回调函数可以和你的主程序同时运行,及时的对边沿做出响应。


实例:


def my_callback(pin):
     print '这是一个边沿事件的回调函数'
     print '在%d通道上进行的边沿检测'%pin
     print '该程序与我的主程序在不同的进程中'
 GPIO.add_event_detect(pin,GPIO.RISING,callback=my_callback)

pass#其他代码



 2中的的代码需要自己新建一个线程去循环检测event_detected()的值,还算是比较麻烦的。


不过可采用另一种办法轻松检测状态,这种方式是直接传入一个回调函数:

def my_callback(channel):
     print('This is a edge event callback function!')
     print('Edge detected on channel %s'%channel)
     print('This is run in a different thread to your main program')
 GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback)

如果你想设置多个回调函数,可以这样:

def my_callback_one(channel):
     print('Callback one')

 def my_callback_two(channel):
     print('Callback two')

 GPIO.add_event_detect(channel, GPIO.RISING)
 GPIO.add_event_callback(channel, my_callback_one)
 GPIO.add_event_callback(channel, my_callback_two)

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



/**************************************************/


实例应用:

import RPi.GPIO as GPIO  //引入函数库
 import time

 RPi.GPIO.setmode(GPIO.BOARD)  //设置引脚编号规则
 RPi.GPIO.setup(11, RPi.GPIO.OUT)    //将11号引脚设置成输出模式

 while True
     GPIO.output(channel, 1)   //将引脚的状态设置为高电平,此时LED亮了
     time.sleep(1)   //程序休眠1秒钟,让LED亮1秒
     GPIO.output(channel, 0)   //将引脚状态设置为低电平,此时LED灭了
     time.sleep(1)   //程序休眠1秒钟,让LED灭1秒

 GPIO.cleanup()    //程序的最后别忘记清除所有资源
 /*****************************************************/

 



GPIO.output(pin1,not GPIO.input(pin2))
 #返回0 / GPIO.LOW /False  或 1 / GPIO.HIGH  /True
 

 /**********************************************************************/ 


 #设置一个GPIO口的输出值 

 GPIO.output(pin,state) 

 #state的之可以为0 / GPIO.LOW /False  或 1 / GPIO.HIGH  /True 


 #设置多个通道的输出 

 pinlist=[pin1,pin2,pin3,pinx] 

 GPIO.output(pinlist,GPIO.LOW) 

 GPIO.output([pin1,pin2],(GPIO.HIGH,GPIO.LOW)) 


 ##清空 

 GPIO.cleanup() 


 /*****time.sleep(t)延时函数***********/ 

 time.sleep(t) #t是推迟执行的秒数 

 Python time sleep() 函数推迟调用线程的运行,可通过参数secs指秒数,表示进程挂起的时间。 






 /*****************PWM(脉冲宽度调制)**********************************/ 

 创建PWM实例 

 Pwm=GPIO.PWM(pin,frequence) 


 启动PWM 

 Pwm.start(dc)  0.0<dc<100.0 


 改变PWM频率 

 Pwm.ChangeFrequency(freq)  #where freq is the new frequency in HZ 


 改变PWM的占空比 

 Pwm.ChangeDutyCycle(dc)    #where 0.0<=dc <=100.0 


 停止PWM 

 Pwm.stop()