文章目录
- 一.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用户组。然后将用户添加到新创建的组中。
sudo groupadd -f -r gpio sudo usermod -a -G gpio your_user_name
通过将99-gpio.rules文件复制到rules.d目录来安装自定义udev规则。
-
如果是将源代码下载到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/
-
-
最后需要通过运行以下命令重新启动或重新加载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
-
构建以及安装库
sudo make install
三.几种常用的通信协议
上面介绍了什么是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.setwarnings(False)
-
设置一个引脚的模式
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.input(channel) #返回值为GPIO.LOW or GPIO.HIGH
-
设置引脚的值
GPIO.output(channel, state) #state可以是GPIO.LOW or GPIO.HIGH
-
清除所有引脚的设置
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::setwarnings(false);
-
设置一个引脚的模式
GPIO::setup(channel, GPIO::IN); GPIO::setup(channel, GPIO::OUT); GPIO::setup(channel, GPIO::OUT, GPIO::HIGH);
-
读取引脚的值
int value = GPIO::input(channel);
-
设置引脚的值
GPIO::output(channel, state); //GPIO::LOW(== 0) or GPIO::HIGH(== 1)
-
清除所有引脚的设置
GPIO::cleanup();
-
设置中断
#第二个参数指定要检测的边缘,可以是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")