GPIO
General Purpose Input/Output (GPIO)引脚提供可编程接口来读取二进制输入设备(例如按钮开关)的状态或控制二进制输出设备(如LED)的开/关状态。
您可以将GPIO引脚配置为高或低状态的输入或输出。作为输入,外部来源确定状态,您的应用程序可以读取当前值或对状态更改做出反应。作为输出,您的应用程序配置引脚的状态。
管理连接
为了打开与GPIO端口的连接,您需要知道唯一的端口名称。在开发的初始阶段或将应用程序移植到新硬件时,您可以使用 getGpioList()
从 PeripheralManagerService
发现所有可用的端口名称:
PeripheralManagerService manager = new PeripheralManagerService();
List<String> 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);
}
一旦您知道目标名称,请使用 PeripheralManagerService
连接到该端口。完成与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);
}
}
}
}
从输入读取
要读取GPIO端口作为输入:
DIRECTION_IN
将 setDirection()
配置为输入。ACTIVE_HIGH
或 ACTIVE_LOW
调用 setActiveType()
,将高(接近IOREF)或低(接近零)电压信号配置为 true
。getValue()
方法访问当前状态。 以下代码显示了如何设置与高电压电平相关联的有效状态的输入:
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);
...
// Read the active high pin state
if (gpio.getValue()) {
// Pin is HIGH
} else {
// Pin is LOW
}
}
监听输入状态变化
配置为输入的GPIO端口在其状态在高电平和低电平之间变化时可以通知应用程序。注册这些变更事件:
GpioCallback
附加到活动端口连接。使用setEdgeTriggerType()
方法声明触发中断事件的状态更改。边缘触发器支持以下四种类型:
EDGE_NONE
:
无中断事件。这是默认值。EDGE_RISING
: 中断从低到高的过渡。EDGE_FALLING
: 中断从低到高的过渡。EDGE_BOTH
:
中断所有状态转换。从 onGpioEdge()
中返回 true
,以指示监听器应该继续接收每个端口状态更改的事件。
以下代码为给定输入端口上的所有状态更改注册中断监听器:
public void configureInput(Gpio gpio) throws IOException {
// Initialize the pin as an input
gpio.setDirection(Gpio.DIRECTION_IN);
// Low voltage is considered active
gpio.setActiveType(Gpio.ACTIVE_LOW);
// Register for all state changes
gpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
gpio.registerGpioCallback(mGpioCallback);
}
private GpioCallback mGpioCallback = 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);
}
};
当您的应用程序不再监听传入的事件时,请注销任何中断处理程序:
public class HomeActivity extends Activity {
private Gpio mGpio;
...
@Override
protected void onStart() {
super.onStart();
// Begin listening for interrupt events
mGpio.registerGpioCallback(mGpioCallback);
}
@Override
protected void onStop() {
super.onStop();
// Interrupt events no longer necessary
mGpio.unregisterGpioCallback(mGpioCallback);
}
}
写入到输出
以编程方式控制GPIO端口的状态:
-
使用模式
DIRECTION_OUT_INITIALLY_HIGH
或DIRECTION_OUT_INITIALLY_LOW
将setDirection()
配置为输出。这些模式确保端口的初始状态在配置时也正确设置。 -
通过使用
ACTIVE_HIGH
或ACTIVE_LOW
调用setActiveType()
,将高(接近IOREF)或低(接近零)电压信号配置为true
。 -
使用
setValue()
方法设置当前状态。
以下代码显示了如何将输出设置为最初为高电平,然后使用 setValue()
方法将其状态切换为低电平:
public void configureOutput(Gpio gpio) throws IOException {
// Initialize the pin as a high output
gpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_HIGH);
// Low voltage is considered active
gpio.setActiveType(Gpio.ACTIVE_LOW);
...
// Toggle the value to be LOW
gpio.setValue(true);
}