一直都據說樹莓派功能很強大,這幾天就買了個pi3試玩一下。拿到手裝好系統,就開始測試GPIO口,點亮一個LED。直接用python去操做GPIO好像不行,還好網上有不少python封裝包能夠用。RPi.GPIO使用比較簡單,官方主頁也給比較詳細的介紹也附帶了例子。python
RPi.GPIO主頁:https://sourceforge.net/p/raspberry-gpio-python/wiki/Home/git
官網介紹的是英文了,我本身寫了箇中文的使用手冊:函數
https://git.oschina.net/null_693_8693/RPi.GPIO-use-introduction/attach_files測試
RPi.GPIO是python調用包,提供了一些方法來操做樹莓派上GPIO引腳。使用python程序能夠很方便的調用這些方法。目前RPi.GPIO提供了GPIO輸入、輸出和軟件模擬PWM方法,惋惜的是暫不提供SPI、I2C、UART和硬件PWM方法。.net
使用不難,接下來我就來介紹下使用它的一些感覺吧。code
首先,既然是控制GPIO口,那就得看看它操做的速度了,雖然python是出了名的慢。token
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) GPIO.setup(35, GPIO.OUT) start_time = time.time() for i in range(0, 1000000): GPIO.output(35, 1) pass end_time = time.time() print(end_time - start_time) GPIO.cleanup()
上面代碼我運行了五次,平均下來每次時間爲2.4396s。而後去除GPIO.output(35, 1),運行五次,每次平均時間爲0.5222s。有這些數據就能夠計算出執行1000000次GPIO.output(35, 1)的時間爲1.9174s,則每次執行GPIO.output(35, 1)時間是1.9us。個人個神啊太慢了吧,後面我又對輸出0和改爲輸入模式,測試的時間都基本同樣,一個字「慢」。如今不少8位單片機都比這速度快了。估計用這速度去軟件模擬SPI、I2C傳大點的數據是不行了。原本還想模擬個SPI驅動下TFT顯示屏,看到這速度只能放棄了。事件
RPi.GPIO有個相似硬件中斷的函數,挺好玩的。文檔
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) GPIO.setwarnings(False) GPIO.setup(35, GPIO.IN, GPIO.PUD_DOWN) def my_callback(channel): print('--my_callback start--') for i in range(0, 10000000): pass print('--my_callback end--') GPIO.add_event_detect(35, GPIO.RISING, my_callback, bouncetime=200) while True: time.sleep(1) GPIO.cleanup()
GPIO.add_event_detect添加事件檢測,GPIO.RISING上升沿觸發,my_callback回調函數,它還有個防抖延時bouncetime(單位ms),免得咱們本身去軟件防抖。爲何我要加for i in range(0, 10000000)呢?我是想知道當中斷被觸發後但尚未退出來,再次給它個上升沿,它會不會再次進入回調函數呢?答案是不會。get
硬件中的中斷有嵌套關係,須要給每一箇中斷設定優先級。51類的需設定一個(不設定就默認),stm32要設置兩個:搶佔優先級和子優先級。RPi.GPIO主頁文檔中沒有說明這一點,我想經過一段代碼測試一下。
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) GPIO.setwarnings(False) GPIO.setup([35,37], GPIO.IN, GPIO.PUD_UP) def my_callback_one(channel): print('--my_callback_one start--') for i in range(0, 100000): pass print('--my_callback_one end--') def my_callback_two(channel): print('--my_callback_two start--') for i in range(0, 100000): pass print('--my_callback_two end--') GPIO.add_event_detect(35, GPIO.FALLING, my_callback_one, bouncetime=200) GPIO.add_event_detect(37, GPIO.FALLING, my_callback_two, bouncetime=200) while True: time.sleep(1) GPIO.cleanup()
我先是把35和37引腳連在一塊兒,同時給降低沿,發現它們雖然都被觸發了,但仍是會先執行一個,執行完後再執行下一個,而不會出現嵌套現象。而後我再嘗試先給35引腳一個降低沿,當35引腳的中斷被觸發,開始執行回調函數時但尚未退出回調的時候我立刻給37引腳一個降低沿,此時37引腳並無立刻被觸發去調用它的回調函數而是等35引腳的回調函數執行完才被觸發。把35引腳和37引腳順序調過來狀況也同樣。按理說樹莓派用3的BCM2837處理器的GPIO口中斷應該有嵌套、優先級的,估計已經被RPi.GPIO默認設置好了。可能被測試的引腳恰好被RPi.GPIO設置成優先級一個高一個低,不能被搶佔。
綜合上訴測試,RPi.GPIO能夠被利用到一些時序要求不高、小量數據傳輸、簡單IO操做的項目上。
RPi.GPIO還有其餘的一些用法,若是感興趣能夠下載我寫的 《RPi.GPIO使用手冊》或者到 RPi.GPIO主頁 查看。