文章目錄
- 一.GPIO介紹
- 二.安裝GPIO庫
-
- python庫
- C++庫
- 三.幾種常用的通信協定
-
- UART
- PWM
- I2C
- I2S
- SPI
- 四.控制函數說明
-
- python([參考](https://pypi.org/project/Jetson.GPIO/))
- C++
- 五.例程
一.GPIO介紹
GPIO(General Purpose Input Output)通用輸入輸出。有時候我們會簡稱為“IO口”。GPIO口在智能硬體開發中是一個比較重要的概念,使用者可以通過GPIO口和硬體進行資料互動(如UART),控制硬體工作(如LED、蜂鳴器等),讀取硬體的工作狀态信号(如中斷信号)等。Jetson TX1、TX2、AGX Xavier和Nano開發闆包含一個40針GPIO接頭,類似于樹莓派中的40針接頭。可以使用Jetson GPIO library包中提供的Python庫或者C++庫控制這些GPIO的數字輸入和輸出。該庫與Raspberry Pi的RPi.GPIO庫具有相同的API,以便提供将在Raspberrry Pi上運作的應用程式移動到Jetson闆的簡單方法。
GPIO四種模式:
- BOARD
- BCM
- CVM
- TEGRA_SOC
提示:四種模式可以分為兩組:BOARD和BCM一組,CVM和TEFRA_SOC一組。其中,前兩種源于RPi.GPIO library,是以Jetson Nano的引腳對照和樹莓派一緻,大家再開發學習時,可以參照樹莓派.
二.安裝GPIO庫
python庫
- jetson nano原版本系統自帶,但是也可以直接pip安裝或者官網下載下傳源代碼安裝
# pip直接安裝 sudo pip install Jetson.GPIO # 或者下載下傳代碼進行安裝 sudo python3 setup.py install
- 設定使用者權限,為了使用Jetson GPIO庫,必須首先設定正确的使用者權限/組。建立新的gpio使用者組。然後将使用者添加到新建立的組中。
通過将99-gpio.rules檔案複制到rules.d目錄來安裝自定義udev規則。sudo groupadd -f -r gpio sudo usermod -a -G gpio your_user_name
- 如果是将源代碼下載下傳到Jetson.GPIO:
sudo cp lib/python/Jetson/GPIO/99-gpio.rules /etc/udev/rules.d/
- 如果是使用pip安裝的Jetson.GPIO,則在虛拟環境中使用pip:
sudo cp venv/lib/pythonNN/site-packages/Jetson/GPIO/99-gpio.rules /etc/udev/rules.d/
- 如果是将源代碼下載下傳到Jetson.GPIO:
- 最後需要通過運作以下指令重新啟動或重新加載udev規則:
sudo udevadm control --reload-rules && sudo udevadm trigger
C++庫
- 從官網克隆代碼
git clone https://github.com/pjueon/JetsonGPIO
- 建立建構目錄并将目錄更改為該目錄。
cd JetsonGPIO mkdir build && cd build
- 配置cmake
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_EXAMPLES=ON # 參數選項說明 -DCMAKE_INSTALL_PREFIX=/usr # 選擇基礎安裝目錄 -DBUILD_EXAMPLES=ON # 選擇建立samples
- 建構以及安裝庫
三.幾種常用的通信協定
上面介紹了什麼是GPIO口以及如何安裝 GPIO庫,但是我們還不能立即去使用。我們還得再了解一下幾個常用的通信協定,這樣我們才能愉快的使用。
UART
UART(Universal Asynchronous Receiver and Transmitter)是一種非常常見的接口或協定,幾乎在每台計算機或微處理器上都可以找到它,中文我們一般稱為通用異步收發傳輸器,也稱其為RS-232标準。該協定是全雙工協定,它也是一種包括特定通信的電子、機械和實體特性的全面标準。當在總線上發送資料時,資料電平需要轉換成适合RS-232總線的電平,在總線上傳輸器發送不斷變化的電壓。高于3V的電壓值即為邏輯0,而低于-3V的電壓值即為邏輯1,-3~3V之間的電壓值被稱為不确定狀态。
很多傳感器在其輸出引腳上都能使用UART通信協定,我們就可以使用這些傳感器與我們的樹莓派和Nano通信。
PWM
PWM(Pulse Width Modulation)脈沖寬度調制(簡稱脈寬調制,通俗的講就是調節脈沖的寬度),是電子電力應用中非常重要的一種控制技術 。簡單的說,PWM就是在一個周期内,控制高電平多長時間,低電平多長時間PWM有非常廣泛的應用,比如直流電機的無極調速,開關電源、逆變器等。
I2C
I2 C(Inter-Integrated Circuit)是一種用兩條連線工作的半雙工協定,隻要發送端在發送資料,接收端就隻能監聽而不能發送資料,相反也是如此。市面上有一些帶有I2C接口的16×2字元點陣LCD顯示器子產品,我們可以寫一下程式在這塊螢幕上顯示。
I2S
I2S(Inter-IC Sound, Integrated Interchip Sound)是飛利浦在1986年定義(1996年修訂)的數字音頻傳輸标準,用于數字音頻資料在系統内部器件之間傳輸,例如編解碼器CODEC、DSP、數字輸入/輸出接口、ADC、DAC和數字濾波器等。
SPI
SPI(Serial Peripheral Interface)串行外圍裝置接口是一種全雙工短距單主裝置通信協定,與UART不同,它是一種同步通信協定。SPI簡單的連接配接方式之一是單主從連接配接,如圖所示。一般來說,總共有4條資料線,分别是時鐘(SCLK)、主入從出 (Master In Slave Out,MISO)、主出從入 (Master Out Slave In,MOSI)以及片選(CS)。
注意:NVIDIA Jetson Nano的GPIO口輸入的電壓為3.3v,大家確定輸入電壓不要超過3.3V,否則你的闆子可能會壞。
四.控制函數說明
python(參考)
- 設定GPIO的引腳定義
GPIO.setmode(GPIO.BOARD) # or GPIO.setmode(GPIO.BCM) # or GPIO.setmode(GPIO.CVM) # or GPIO.setmode(GPIO.TEGRA_SOC)
- 消除警告
- 設定一個引腳的模式
GPIO.setup(channel, GPIO.IN) # 引腳設定為輸入 GPIO.setup(channel, GPIO.OUT) # 引腳設定為輸出 GPIO.setup(channel, GPIO.OUT, initial=GPIO.HIGH) # 帶初始化的引腳定義 # 同時設定多個引腳的定義 channels = [18, 12, 13] GPIO.setup(channels, GPIO.OUT)
- 讀取引腳的值
- 設定引腳的值
- 清除所有引腳的設定
GPIO.cleanup() #清除所有引腳的值 GPIO.cleanup([chan1, chan2]) #清除部分引腳的值
- 設定中斷
#第二個參數指定要檢測的邊緣,可以是GPIO.RISING、GPIO.FALLING或GPIO.BOTH。 #如果您隻想将等待時間限制為指定的時間,可以選擇設定逾時: GPIO.wait_for_edge(channel, GPIO.RISING) GPIO.wait_for_edge(channel, GPIO.RISING, timeout=500)
- 事件檢測
GPIO.add_event_detect(channel, GPIO.RISING) run_other_code() if GPIO.event_detected(channel): do_something()
- 事件回調函數
def callback_one(channel): print("First Callback") def callback_two(channel): print("Second Callback") GPIO.add_event_detect(channel, GPIO.RISING) GPIO.add_event_callback(channel, callback_one) GPIO.add_event_callback(channel, callback_two)
C++
- cmake連結庫
find_package(JetsonGPIO) target_link_libraries(mytarget JetsonGPIO)
- 程式導入庫
#include <JetsonGPIO.h> using namespace GPIO;
- 設定GPIO的引腳定義
GPIO::setmode(GPIO::BOARD); // or GPIO::setmode(GPIO::BCM); // or GPIO::setmode(GPIO::CVM); // or GPIO::setmode(GPIO::TEGRA_SOC);
- 消除警告
- 設定一個引腳的模式
GPIO::setup(channel, GPIO::IN); GPIO::setup(channel, GPIO::OUT); GPIO::setup(channel, GPIO::OUT, GPIO::HIGH);
- 讀取引腳的值
- 設定引腳的值
- 清除所有引腳的設定
- 設定中斷
#第二個參數指定要檢測的邊緣,可以是GPIO.RISING、GPIO.FALLING或GPIO.BOTH。 #如果您隻想将等待時間限制為指定的時間,可以選擇設定逾時: GPIO::wait_for_edge(channel, GPIO::RISING);
- 事件檢測
// set rising edge detection on the channel GPIO::add_event_detect(channel, GPIO::RISING); run_other_code(); if(GPIO::event_detected(channel)) do_something();
- 事件回調函數
// you can also use callbacks witout any argument void callback_one() { std::cout << "First Callback" << std::endl; } void callback_two() { std::cout << "Second Callback" << std::endl; } GPIO::add_event_detect(channel, GPIO::RISING); GPIO::add_event_callback(channel, callback_one); GPIO::add_event_callback(channel, callback_two);
五.例程
import Jetson.GPIO as GPIO
import time
led_pin = 7
GPIO.setmode(GPIO.BOARD)
GPIO.setup(led_pin, GPIO.OUT)
try:
while 1:
print("on")
GPIO.output(led_pin, GPIO.HIGH)
time.sleep(2)
print("off")
GPIO.output(led_pin, GPIO.LOW)
time.sleep(2)
except KeyboardInterrupt:
GPIO.output(led_pin, GPIO.LOW)
GPIO.cleanup()
print("done")