**General Purpose Input/Output (GPIO) **是单片机乃至普通计算机设备中最常用的端口了,很多高级端口和总线都是使用一个或多个GPIO端口来实现的。
它支持数字信号的输入、输出,对最基本的数字信号方波做读写,或者说对最基本的数字信号电平高低做读取和操作。
它的基本读取操作:
- 读取电平的高/低状态
- 读取电平变化,即电平上升沿(从低电平变为高电平)和电平下降沿(从高电平变为低电平)
它的基本输出操作:
- 输出高/低电平已指示状态
- 输出电平变化,即电平拉高(把当前端口的电平设置到高电平)和电平拉低(把当前端口的电平设置到低电平)
- 输出连续变化的电平,如果输出的电平变化有周期,则被称为PWM,否则一般用于表示连续的二进制流串
管理GPIO连接
1. 列举GPIO端口
用下面的方法可以列举出设备上可用的GPIO端口列表。在Android Things中,对外围端口的管理类是PeripheralManagerService
,它可以在任何地方直接被new
出来,而且可以被创建多个实例在不同地方一起使用。
PeripheralManagerService manager = new PeripheralManagerService();
List portList = manager.getGpioList();
if (portList.isEmpty()) {
Log.i(TAG, "No GPIO port available on this device.");
} else {
Log.i(TAG, "List of available ports: " + portList);
}
2. 端口的打开与关闭
GPIO端口的打开和关闭,需要先通过PeripheralManagerService
获得一个指定端口的Gpio
对象,才能通过这个Gpio
对象去操作物理的GPIO端口。
很多硬件的物理端口即可以作为GPIO使用,也可以作为其他用途使用,但同一物理端口同一时间内通常只能被用作同一个功能
打开GPIO端口使用PeripheralManagerService.openGpio(pin)
方法获取Gpio
对象,关闭并释放GPIO端口使用Gpio.close()
方法。
public class HomeActivity extends Activity {
// GPIO Pin Name
private static final String GPIO_NAME = ...;
private Gpio mGpio;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Attempt to access the GPIO
try {
PeripheralManagerService manager = new PeripheralManagerService();
mGpio = manager.openGpio(GPIO_NAME);
} catch (IOException e) {
Log.w(TAG, "Unable to access GPIO", e);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mGpio != null) {
try {
mGpio.close();
mGpio = null;
} catch (IOException e) {
Log.w(TAG, "Unable to close GPIO", e);
}
}
}
}
3. GPIO的读写
Gpio对象获取到后,需要先对GPIO端口配置后才能使用,一般的配置步骤如下:
- 配置端口为输入还是输出
- 如果为输入,则配置的有效值是高电平还是低电平
- 如果需要监听输入电平的变化事件,就注册监听
- 通过
boolean Gpio.getValue()
读取GPIO输入值- 如果配置高电平为有效电平,则
Gpio.getValue()
为true时,表示当前输入的是高电平,false为低电平 - 如果配置低电平为有效电平,则
Gpio.getValue()
为true时,表示当前输入的是低电平,false为高电平
- 如果配置高电平为有效电平,则
public void configureInput(Gpio gpio) throws IOException {
// Initialize the pin as an input
gpio.setDirection(Gpio.DIRECTION_IN);
// High voltage is considered active;
gpio.setActiveType(Gpio.ACTIVE_HIGH);
// Register for all state changes
gpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
gpio.registerGpioCallback(new GpioCallback() {
@Override
public boolean onGpioEdge(Gpio gpio) {
// Read the active low pin state
if (gpio.getValue()) {
// Pin is LOW
} else {
// Pin is HIGH
}
// Continue listening for more interrupts
return true;
}
@Override
public void onGpioError(Gpio gpio, int error) {
Log.w(TAG, gpio + ": Error event " + error);
}
});
}