作者:陳拓 chentuo@ms.xab.ac.cn 2018.06.09/2018.07.05
0. 概述
本文介紹樹莓派 Zero W的GPIO控制,並用LED看效果。
0.1 樹莓派GPIO編號方式
- 功能物理引腳
從左到右,從上到下:左邊奇數,右邊偶數:1-40
- BCM
編號側重CPU寄存器,根據BCM2835的GPIO寄存器編號。
- wiringPi
編號側重實現邏輯,把擴展GPIO端口從0開始編號,這種編號方便編程。如圖 WiringPi一欄。
操作GPIO時一定先要清楚使用那一套編號。
1. 准備
1.1 硬件
- 樹莓派Pi Zero W
- LED(3mm或5mm)
- 1KΩ電阻
- 杜邦線3根
- 電腦(我用Windows 7)
1.2 GPIO接口
1.3 接線
首先我們把LED和樹莓派連接。LED的正極串聯一個1KΩ電阻接樹莓派的GPIO18(pin12),負極接地。(注意,下面借用了別人一張圖,圖中LED正極接在pin11上,我們是接在pin12上)
2. 測試
2.1 連接電腦和Pi Zero W
用putty連接電腦和Pi Zero W,看本文最后的參考文檔。Host Name填raspberrypi.local,端口22,用戶名pi,密碼raspberry。
注意:boot分區有一個名為ssh的空文本文件,這個ssh文件容易丟失,如果ssh不能登錄了,先檢查ssh是否丟失。
2.2 用Shell命令直接控制GPIO
- 使GPIO18從內核空間暴露到用戶空間中
pi@raspberrypi:~ $ sudo echo 18 > /sys/class/gpio/export
> 是IO重定向符號,IO重定向是指改變linux標准輸入和輸出的默認設備,指向一個用戶定義的設備。echo 18 > export就是把18寫入到export文件中。
執行該操作之后,/sys/class/gpio目錄下會增加一個gpio18文件夾。
- 查看GPIO18引腳(在Liunx中設備都以文件的形式,引腳也是設備)
pi@raspberrypi:~ $ cd /sys/class/gpio/gpio18
pi@raspberrypi:/sys/class/gpio/gpio18 $ ls
- 設置GPIO18為輸出模式
pi@raspberrypi:/sys/class/gpio/gpio18 $ sudo echo out > direction
- 向value文件中輸入1,GPIO輸出高電平,LED點亮
pi@raspberrypi:/sys/class/gpio/gpio18 $ sudo echo 1 > value
- 向value文件中輸入0,GPIO輸出低電平,LED熄滅
pi@raspberrypi:/sys/class/gpio/gpio18 $ sudo echo 0 > value
- 返回家目錄
pi@raspberrypi:/sys/class/gpio $ cd ~
- 注銷GPIO18接口
pi@raspberrypi:~ $ sudo echo 18 > /sys/class/gpio/unexport
2.3 用Shell腳本控制GPIO
- 新建一個名為ledonoff.sh的腳本。
pi@raspberrypi:~ $ sudo nano ledonoff.sh
腳本寫下面的內容:
echo $1 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio$1/direction
echo 1 > /sys/class/gpio/gpio$1/value
sleep 5 #延時5秒
echo 0 > /sys/class/gpio/gpio$1/value
echo $1 > /sys/class/gpio/unexport
說明:shell腳本可傳入參數,例如$1代表第1個參數,$2代表第2個參數,以此類推。
- 為ledonoff.sh添加可執行權限
pi@raspberrypi:~ $ sudo chmod +x ledonoff.sh
- 運行腳本
pi@raspberrypi:~ $ sudo ./ledonoff.sh 18
運行結果:LED點亮,持續5秒鍾關閉。
2.4 用Python通過PRI.GPIO命令控制GPIO
用Python控制GPIO,最便捷的方法就是使用python類庫,比如樹莓派系統本身集成的RPi.GPIO。
在putty的ssh終端輸入命令:
- 進入python交互界面
pi@raspberrypi:~ $ python
>>> 這是python的提示符。
- 導入python類庫RPi.GPIO,命名為別名為GPIO
>>> import RPi.GPIO as GPIO
引入之后,就可以使用 GPIO 模塊的函數了。
- 設置BOARD編碼方式,基於BCM
樹莓派3 GPIO分為如下的三種編碼方式:物理引腳BOARD編碼,BCM編碼,以及 wiringPi 編碼。
>>> GPIO.setmode(GPIO.BCM)
- 輸出模式
>>> GPIO.setup(18,GPIO.OUT)
- GPIO18輸出高電平,LED點亮
>>> GPIO.output(18,GPIO.HIGH)
- GPIO18輸出低電平,LED熄滅
>>> GPIO.output(18,GPIO.LOW)
- 用完后進行清理
>>> GPIO.cleanup()
- 退出python交互界面
>>> Ctrl+D
2.5 用Python腳本控制GPIO
- 新建一個名為blinky.py的腳本。
pi@raspberrypi:~ $ sudo nano blinky.py
腳本寫下面的內容:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(18,GPIO.OUT)
while True:
GPIO.output(18,GPIO.HIGH)
time.sleep(1)
GPIO.output(18,GPIO.LOW)
time.sleep(1)
GPIO.cleanup()
說明:while True下面的循環體要縮進,用空格或Tab(但不能混用)鍵縮進就行。
- 為blinky.py添加可執行權限
pi@raspberrypi:~ $ sudo chmod +x blinky.py
- 運行Python腳本
pi@raspberrypi:~ $ sudo python blinky.py
LED閃爍。
- 停止運行
用 Ctrl+C 來中斷循環。
3. 借助wiringPi GPIO用C語言控制GPIO
樹莓派內核中已經編譯自帶了gpio的驅動,我們常通過一些第三方寫好的庫函數來完成具體的操作,比較常見的操作庫函數有:
- Python GPIO
Python GPIO已經集成到了樹莓派內核,為樹莓派官方資料中推薦且容易上手。python GPIO是一個小型的python庫,可以幫助用戶完成raspberry相關IO口操作,但是python GPIO庫還沒有支持SPI、I2C或者1-wire等總線接口。
常見C語言庫有:
- wiringPi (http://wiringpi.com/)
wiringPi適合那些具有C語言基礎,在接觸樹莓派之前已經接觸過單片機或者嵌入式開發的人群。wiringPi的API函數和arduino非常相似,這也使得它廣受歡迎。作者給出了大量的說明和示例代碼,這些示例代碼也包括UART設備,I2C設備和SPI設備等。
- BCM2835 C Library (http://www.airspayce.com/mikem/bcm2835/)
BCM2835 C Library可以理解為使用C語言實現的相關底層驅動,BCM2835 C Library的驅動庫包括GPIO. SPI和UART等,可以通過學習BCM2835 C Library熟悉BCM2835相關的寄存器操作。如果有機會開發樹莓派上的linux驅動,或自主開發python或PHP擴展驅動,可以從BCM2835 C Library找到不少的“靈感”。
3.1 WiringPi GPIO安裝
WiringPi是應用於樹莓派平台的GPIO控制庫函數,WiringPi遵守GUN Lv3。wiringPi使用C或者C++開發並且可以被其他語言包轉,例如python、ruby或者PHP等。
wiringPi包括一套gpio控制命令,使用gpio命令可以控制樹莓派GPIO管腳。用戶可以利用gpio命令通過shell腳本控制或查詢GPIO管腳。
- wiringPi安裝
更新列表:
pi@raspberrypi:~ $ sudo apt-get update
更新軟件:
pi@raspberrypi:~ $ sudo apt-get upgrade
安裝:
pi@raspberrypi:~ $ sudo apt-get install wiringpi
- 測試
wiringPi包括一套gpio命令,使用gpio命令可以控制樹莓派上的各種接口,通過以下指令可以測試wiringPi是否安裝成功。
pi@raspberrypi:~ $ gpio -v
- 查看GPIO圖
pi@raspberrypi:~ $ gpio readall
3.2 編寫代碼
- 新建一個名為led_blink.c的源程序
pi@raspberrypi:~ $ sudo nano led_blink.c
- 內容如下
#include <wiringPi.h>
int main(void) {
wiringPiSetup();
pinMode (1, OUTPUT);
for(;;) {
digitalWrite(1, HIGH);delay (500);
digitalWrite(1, LOW);delay (500) ;
}
}
說明:看看上一小節的圖,BCM編號的GPIO18引腳在wiringPi編號中是1。
3.3 編譯運行
- 編譯
pi@raspberrypi:~ $ gcc led_blink.c -o led_blink -l wiringPi
-l wiringPi表示動態加載wiringPi共享庫。
- 運行
pi@raspberrypi:~ $ sudo ./led_blink
用 Ctrl+C 來中斷循環。
4. 借助BCM2835 C Library用C語言控制GPIO
4.1 下載安裝
先看看最新版本:http://www.airspayce.com/mikem/bcm2835
- 下載bcm2835-1.56.tar.gz
pi@raspberrypi:~ $ wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.56.tar.gz
- 解壓縮
pi@raspberrypi:~ $ tar xvzf bcm2835-1.56.tar.gz
- 配置編譯
進入壓縮之后的目錄:
pi@raspberrypi:~ $ cd bcm2835-1.56
執行配置命令:
pi@raspberrypi:~/bcm2835-1.56 $ ./configure
pi@raspberrypi:~/bcm2835-1.56 $ make
- 執行檢查
pi@raspberrypi:~/bcm2835-1.56 $ sudo make check
- 安裝bcm2835庫:
pi@raspberrypi:~/bcm2835-1.56 $ sudo make install
4.2 編寫代碼
- 新建一個名為blink_led.c的源程序
pi@raspberrypi:~/bcm2835-1.56 $ cd ~
pi@raspberrypi:~ $ sudo nano blink_led.c
- 內容如下
#include <bcm2835.h>
#define PIN RPI_GPIO_P1_12
int main(int argc, char **argv) {
if (!bcm2835_init())
return 1;
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_OUTP);
while (1) {
bcm2835_gpio_write(PIN, HIGH);
bcm2835_delay(500);
bcm2835_gpio_write(PIN, LOW);
bcm2835_delay(500);
}
bcm2835_close();
return 0;
}
說明:GPIO的編號方式不同,采用PCB板的物理接口編號,led連在樹莓派Zero W板子的12引腳上。
4.3 編譯運行
- 編譯
pi@raspberrypi:~ $ gcc blink_led.c -o blink_led -l bcm2835
-l bcm2835表示動態加載bcm2835共享庫
- 運行
sudo ./blink_led
用 Ctrl+C 來中斷循環。
參考文檔
- 樹莓派介紹
- 電腦連接樹莓派PiZeroW
- 樹莓派+溫度傳感器DS18B20
- 樹莓派GPIO控制--C語言篇https://blog.csdn.net/hu7850/article/details/51785560
- 遠程控制通訊——基於樹莓派 Python gpiozero 遠程控制LED燈並返回控制結果https://blog.csdn.net/NCTU_to_prove_safety/article/details/65446454
- RPi Low-level peripherals
https://elinux.org/RPi_Low-level_peripherals - 樹莓派+溫度感測器實現室內溫度監控:http://shumeipai.nxez.com/2013/10/03/raspberry-pi-temperature-sensor-monitors.html
- Raspberry Pi Temperature Sensor
http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/temperature/