赞
踩
一,串口介绍
1.1 串口简介
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口;
串行接口(SerialInterface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢;
1.2 串口使用场景
串口是一种用于android开发板对硬件设备通信的一种协议,通过发送某种指令控制硬件设备,通常用于物联网设备的信息传输,比如切割器,打印机,ATM吐卡机、IC/ID卡读卡等。
1.3 波特率
波特率表示串口传输速率,用来衡量数据传输的快慢,即单位时间内载波参数变化的次数,如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位,1个停止位,8个数据位),这时的波特率为240Bd,比特率为10位*240个/秒=2400bps。波特率与距离成反比,波特率越大传输距离相应的就越短;
1.4 数据位
这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据往往不会是8位的,标准的值是6、7和8位。如何设置取决于你想传送的信息;
1.5 停止位
用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢;
1.6 校验位
在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位;
1.7 串口地址
不同操作系统的串口地址,Android是基于Linux的所以一般情况下使用Android系统的设备串口地址为/dev/ttyS0;
- /dev的串口包括:虚拟串口,真实串口,USB转串口
- 真实串口:/dev/tty0..tty1这个一般为机器自带COM口
- 虚拟串口:/dev/ttyS1...ttyS2...ttyS3...均为虚拟console,同样可以作为输入输出口
- USB转串口:/dev/tty/USB0
二 Android中串口的实践
2.1 由于串口底层需要调用C代码,所以需要用jni来进行C交互,下面是全部的C代码,以及JNI调用
2.1 SerialPort.h
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- /* Header for class android_serialport_SerialPort */
-
- #ifndef _Included_android_serialport_SerialPort
- #define _Included_android_serialport_SerialPort
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * Class: android_serialport_SerialPort
- * Method: open
- * Signature: (Ljava/lang/String;IIIII)Ljava/io/FileDescriptor;
- */
- JNIEXPORT jobject JNICALL Java_android_serialport_SerialPort_open
- (JNIEnv *, jobject, jstring, jint, jint, jint, jint, jint);
-
- /*
- * Class: android_serialport_SerialPort
- * Method: close
- * Signature: ()V
- */
- JNIEXPORT void JNICALL Java_android_serialport_SerialPort_close
- (JNIEnv *, jobject);
-
- #ifdef __cplusplus
- }
- #endif
- #endif
- /* Header for class android_serialport_SerialPort_Builder */
-
- #ifndef _Included_android_serialport_SerialPort_Builder
- #define _Included_android_serialport_SerialPort_Builder
- #ifdef __cplusplus
- extern "C" {
- #endif
- #ifdef __cplusplus
- }
- #endif
- #endif
2.2 SerialPort.c
- #include <termios.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <string.h>
- #include <jni.h>
-
- #include "SerialPort.h"
-
- #include "android/log.h"
-
- static const char *TAG = "serial_port";
- #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args)
- #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
- #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
-
- static speed_t getBaudrate(jint baudrate) {
- switch (baudrate) {
- case 0:
- return B0;
- case 50:
- return B50;
- case 75:
- return B75;
- case 110:
- return B110;
- case 134:
- return B134;
- case 150:
- return B150;
- case 200:
- return B200;
- case 300:
- return B300;
- case 600:
- return B600;
- case 1200:
- return B1200;
- case 1800:
- return B1800;
- case 2400:
- return B2400;
- case 4800:
- return B4800;
- case 9600:
- return B9600;
- case 19200:
- return B19200;
- case 38400:
- return B38400;
- case 57600:
- return B57600;
- case 115200:
- return B115200;
- case 230400:
- return B230400;
- case 460800:
- return B460800;
- case 500000:
- return B500000;
- case 576000:
- return B576000;
- case 921600:
- return B921600;
- case 1000000:
- return B1000000;
- case 1152000:
- return B1152000;
- case 1500000:
- return B1500000;
- case 2000000:
- return B2000000;
- case 2500000:
- return B2500000;
- case 3000000:
- return B3000000;
- case 3500000:
- return B3500000;
- case 4000000:
- return B4000000;
- default:
- return -1;
- }
- }
-
- /*
- * Class: android_serialport_SerialPort
- * Method: open
- * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
- */
- JNIEXPORT jobject JNICALL Java_android_serialport_SerialPort_open
- (JNIEnv *env, jobject thiz, jstring path, jint baudrate, jint dataBits, jint parity,
- jint stopBits,
- jint flags) {
-
- int fd;
- speed_t speed;
- jobject mFileDescriptor;
-
- /* Check arguments */
- {
- speed = getBaudrate(baudrate);
- if (speed == -1) {
- /* TODO: throw an exception */
- LOGE("Invalid baudrate");
- return NULL;
- }
- }
-
- /* Opening device */
- {
- jboolean iscopy;
- const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);
- LOGD("Opening serial port %s with flags 0x%x", path_utf, O_RDWR | flags);
- fd = open(path_utf, O_RDWR | flags);
- LOGD("open() fd = %d", fd);
- (*env)->ReleaseStringUTFChars(env, path, path_utf);
- if (fd == -1) {
- /* Throw an exception */
- LOGE("Cannot open port");
- /* TODO: throw an exception */
- return NULL;
- }
- }
-
- /* Configure device */
- {
- struct termios cfg;
- LOGD("Configuring serial port");
- if (tcgetattr(fd, &cfg)) {
- LOGE("tcgetattr() failed");
- close(fd);
- /* TODO: throw an exception */
- return NULL;
- }
-
- cfmakeraw(&cfg);
- cfsetispeed(&cfg, speed);
- cfsetospeed(&cfg, speed);
-
-
- cfg.c_cflag &= ~CSIZE;
- switch (dataBits) {
- case 5:
- cfg.c_cflag |= CS5; //使用5位数据位
- break;
- case 6:
- cfg.c_cflag |= CS6; //使用6位数据位
- break;
- case 7:
- cfg.c_cflag |= CS7; //使用7位数据位
- break;
- case 8:
- cfg.c_cflag |= CS8; //使用8位数据位
- break;
- default:
- cfg.c_cflag |= CS8;
- break;
- }
-
- switch (parity) {
- case 0:
- cfg.c_cflag &= ~PARENB; //无奇偶校验
- break;
- case 1:
- cfg.c_cflag |= (PARODD | PARENB); //奇校验
- break;
- case 2:
- cfg.c_iflag &= ~(IGNPAR | PARMRK); // 偶校验
- cfg.c_iflag |= INPCK;
- cfg.c_cflag |= PARENB;
- cfg.c_cflag &= ~PARODD;
- break;
- default:
- cfg.c_cflag &= ~PARENB;
- break;
- }
-
- switch (stopBits) {
- case 1:
- cfg.c_cflag &= ~CSTOPB; //1位停止位
- break;
- case 2:
- cfg.c_cflag |= CSTOPB; //2位停止位
- break;
- default:
- cfg.c_cflag &= ~CSTOPB; //1位停止位
- break;
- }
-
- if (tcsetattr(fd, TCSANOW, &cfg)) {
- LOGE("tcsetattr() failed");
- close(fd);
- /* TODO: throw an exception */
- return NULL;
- }
- }
-
- /* Create a corresponding file descriptor */
- {
- jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor");
- jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "<init>", "()V");
- jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I");
- mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor);
- (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint) fd);
- }
-
- return mFileDescriptor;
- }
-
- /*
- * Class: cedric_serial_SerialPort
- * Method: close
- * Signature: ()V
- */
- JNIEXPORT void JNICALL Java_android_serialport_SerialPort_close
- (JNIEnv *env, jobject thiz) {
- jclass SerialPortClass = (*env)->GetObjectClass(env, thiz);
- jclass FileDescriptorClass = (*env)->FindClass(env, "java/io/FileDescriptor");
-
- jfieldID mFdID = (*env)->GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;");
- jfieldID descriptorID = (*env)->GetFieldID(env, FileDescriptorClass, "descriptor", "I");
-
- jobject mFd = (*env)->GetObjectField(env, thiz, mFdID);
- jint descriptor = (*env)->GetIntField(env, mFd, descriptorID);
-
- LOGD("close(fd = %d)", descriptor);
- close(descriptor);
- }
-
2.3 gen_SerialPort_h.sh 生成java的文件目录
- #!/bin/sh
- javah -o SerialPort.h -jni -classpath ../java android.serialport.SerialPort
2.4 SerialPort.java jni对应的java文件
- /*
- * Copyright 2009 Cedric Priscal
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package android.serialport;
-
- import android.util.Log;
-
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
-
- import java.io.DataOutputStream;
- import java.io.File;
- import java.io.FileDescriptor;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
-
- public final class SerialPort {
-
- private static final String TAG = "SerialPort";
-
- public static final String DEFAULT_SU_PATH = "/system/bin/su";
-
- private static String sSuPath = DEFAULT_SU_PATH;
- private File device;
- private int baudrate;
- private int dataBits;
- private int parity;
- private int stopBits;
- private int flags;
-
- /**
- * Set the su binary path, the default su binary path is {@link #DEFAULT_SU_PATH}
- *
- * @param suPath su binary path
- */
- public static void setSuPath(@Nullable String suPath) {
- if (suPath == null) {
- return;
- }
- sSuPath = suPath;
- }
-
- /**
- * Get the su binary path
- *
- * @return
- */
- @NonNull
- public static String getSuPath() {
- return sSuPath;
- }
-
- /*
- * Do not remove or rename the field mFd: it is used by native method close();
- */
- private FileDescriptor mFd;
- private FileInputStream mFileInputStream;
- private FileOutputStream mFileOutputStream;
-
- /**
- * 串口
- *
- * @param device 串口设备文件
- * @param baudrate 波特率
- * @param dataBits 数据位;默认8,可选值为5~8
- * @param parity 奇偶校验;0:无校验位(NONE,默认);1:奇校验位(ODD);2:偶校验位(EVEN)
- * @param stopBits 停止位;默认1;1:1位停止位;2:2位停止位
- * @param flags 默认0
- * @throws SecurityException
- * @throws IOException
- */
- public SerialPort(@NonNull File device, int baudrate, int dataBits, int parity, int stopBits,
- int flags) throws SecurityException, IOException {
-
-
- this.device = device;
- this.baudrate = baudrate;
- this.dataBits = dataBits;
- this.parity = parity;
- this.stopBits = stopBits;
- this.flags = flags;
-
- /* Check access permission */
- Log.e(TAG, "SerialPort: canRead" + device.canRead());
- if (!device.canRead() || !device.canWrite()) {
- try {
- /* Missing read/write permission, trying to chmod the file */
- Process su;
- su = Runtime.getRuntime().exec(sSuPath);
- String cmd = "chmod 666 " + device.getAbsolutePath() + "\n" + "exit\n";
- su.getOutputStream().write(cmd.getBytes());
- if ((su.waitFor() != 0) || !device.canRead() || !device.canWrite()) {
- throw new SecurityException();
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw new SecurityException();
- }
- }
-
- mFd = open(device.getAbsolutePath(), baudrate, dataBits, parity, stopBits, flags);
- if (mFd == null) {
- Log.e(TAG, "native open returns null");
- throw new IOException();
- }
- mFileInputStream = new FileInputStream(mFd);
- mFileOutputStream = new FileOutputStream(mFd);
-
-
- }
-
- /**
- * 串口,默认的8n1
- *
- * @param device 串口设备文件
- * @param baudrate 波特率
- * @throws SecurityException
- * @throws IOException
- */
- public SerialPort(@NonNull File device, int baudrate) throws SecurityException, IOException {
- this(device, baudrate, 8, 0, 1, 0);
- }
-
- /**
- * 串口
- *
- * @param device 串口设备文件
- * @param baudrate 波特率
- * @param dataBits 数据位;默认8,可选值为5~8
- * @param parity 奇偶校验;0:无校验位(NONE,默认);1:奇校验位(ODD);2:偶校验位(EVEN)
- * @param stopBits 停止位;默认1;1:1位停止位;2:2位停止位
- * @throws SecurityException
- * @throws IOException
- */
- public SerialPort(@NonNull File device, int baudrate, int dataBits, int parity, int stopBits)
- throws SecurityException, IOException {
- this(device, baudrate, dataBits, parity, stopBits, 0);
- }
-
- // Getters and setters
- @NonNull
- public InputStream getInputStream() {
- return mFileInputStream;
- }
-
- @NonNull
- public OutputStream getOutputStream() {
- return mFileOutputStream;
- }
-
- /**
- * 串口设备文件
- */
- @NonNull
- public File getDevice() {
- return device;
- }
-
- /**
- * 波特率
- */
- public int getBaudrate() {
- return baudrate;
- }
-
- /**
- * 数据位;默认8,可选值为5~8
- */
- public int getDataBits() {
- return dataBits;
- }
-
- /**
- * 奇偶校验;0:无校验位(NONE,默认);1:奇校验位(ODD);2:偶校验位(EVEN)
- */
- public int getParity() {
- return parity;
- }
-
- /**
- * 停止位;默认1;1:1位停止位;2:2位停止位
- */
- public int getStopBits() {
- return stopBits;
- }
-
- public int getFlags() {
- return flags;
- }
-
- // JNI
- private native FileDescriptor open(String absolutePath, int baudrate, int dataBits, int parity,
- int stopBits, int flags);
-
- public native void close();
-
- /**
- * 关闭流和串口,已经try-catch
- */
- public void tryClose() {
- try {
- mFileInputStream.close();
- } catch (IOException e) {
- //e.printStackTrace();
- }
-
- try {
- mFileOutputStream.close();
- } catch (IOException e) {
- //e.printStackTrace();
- }
-
- try {
- close();
- } catch (Exception e) {
- //e.printStackTrace();
- }
- }
-
- static {
- System.loadLibrary("serial_port");
- }
-
- public static Builder newBuilder(File device, int baudrate) {
- return new Builder(device, baudrate);
- }
-
- public static Builder newBuilder(String devicePath, int baudrate) {
- return new Builder(devicePath, baudrate);
- }
-
- public final static class Builder {
-
- private File device;
- private int baudrate;
- private int dataBits = 8;
- private int parity = 0;
- private int stopBits = 1;
- private int flags = 0;
-
- private Builder(File device, int baudrate) {
- this.device = device;
- this.baudrate = baudrate;
- }
-
- private Builder(String devicePath, int baudrate) {
- this(new File(devicePath), baudrate);
- }
-
- /**
- * 数据位
- *
- * @param dataBits 默认8,可选值为5~8
- * @return
- */
- public Builder dataBits(int dataBits) {
- this.dataBits = dataBits;
- return this;
- }
-
- /**
- * 校验位
- *
- * @param parity 0:无校验位(NONE,默认);1:奇校验位(ODD);2:偶校验位(EVEN)
- * @return
- */
- public Builder parity(int parity) {
- this.parity = parity;
- return this;
- }
-
- /**
- * 停止位
- *
- * @param stopBits 默认1;1:1位停止位;2:2位停止位
- * @return
- */
- public Builder stopBits(int stopBits) {
- this.stopBits = stopBits;
- return this;
- }
-
- /**
- * 标志
- *
- * @param flags 默认0
- * @return
- */
- public Builder flags(int flags) {
- this.flags = flags;
- return this;
- }
-
- /**
- * 打开并返回串口
- *
- * @return
- * @throws SecurityException
- * @throws IOException
- */
- public SerialPort build() throws SecurityException, IOException {
- return new SerialPort(device, baudrate, dataBits, parity, stopBits, flags);
- }
- }
-
-
- public static void checkFilePermission(File file) {
- Log.e(TAG, "canRead: " + file.canRead());
- Log.e(TAG, "canWrite: " + file.canWrite());
- if (!file.canRead() || !file.canWrite()) {
- try {
- /* Missing read/write permission, trying to chmod the file */
- Process su;
- su = Runtime.getRuntime().exec(sSuPath);
- String cmd = "chmod 7777 " + file.getAbsolutePath() + "\n" + "exit\n";
- su.getOutputStream().write(cmd.getBytes());
- Log.e(TAG, "checkFilePermission: " + file.getAbsolutePath());
- if ((su.waitFor() != 0) || !file.canRead() || !file.canWrite()) {
- throw new SecurityException();
- }
- } catch (Exception e) {
- e.printStackTrace();
- Log.e(TAG, "checkFilePermission: Exception:" + e.getMessage());
- throw new SecurityException();
- }
- }
- }
-
-
- //隐藏系统导航栏
- public void hideBottomNavation() {
- chmod("mount -o remount -w /system");
- chmod("chmod 777 /system");
- chmod("echo qemu.hw.mainkeys=1 >> /system/build.prop");
- }
-
- public void chmod(String instruct) {
- try {
- Process process = null;
- DataOutputStream os = null;
- process = Runtime.getRuntime().exec("su");
- os = new DataOutputStream(process.getOutputStream());
- os.writeBytes(instruct);
- os.flush();
- os.close();
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
- }
2.5 CMakeLists.txt,编译c或c++程序的规则文件
Cmake在Jni那篇讲过,这个地方在讲下
CMake是一个可以跨平台的编译工具,可以用简单的语句来描述所有平台的编译过程。他能够输出各种各样的 makefile 或者工程文件。和make与makefile类似,我们在使用CMake时同样也需要一个文件来提供规则,这个文件就是CMakeLists
使用CMake编写跨平台工程的流程如下:
(1)编写源文件
(2)编写CMakeLists.txt
(3)由CMake根据CMakeLists.txt来生成相应的makefile文件
(4)使用make并根据makefile调用gcc来生成相应的可执行文件。
- # Sets the minimum version of CMake required to build your native library.
- # This ensures that a certain set of CMake features is available to
- # your build.
-
- cmake_minimum_required(VERSION 3.4.1)
-
- # Specifies a library name, specifies whether the library is STATIC or
- # SHARED, and provides relative paths to the source code. You can
- # define multiple libraries by adding multiple add.library() commands,
- # and CMake builds them for you. When you build your app, Gradle
- # automatically packages shared libraries with your APK.
-
- add_library( # Specifies the name of the library.
- serial_port
-
- # Sets the library as a shared library.
- SHARED
-
- # Provides a relative path to your source file(s).
- src/main/cpp/SerialPort.c )
-
- find_library( # Sets the name of the path variable.
- log-lib
-
- # Specifies the name of the NDK library that
- # you want CMake to locate.
- log )
-
- # Specifies libraries CMake should link to your target library. You
- # can link multiple libraries, such as libraries you define in this
- # build script, prebuilt third-party libraries, or system libraries.
-
- target_link_libraries( # Specifies the target library.
- serial_port
-
- # Links the target library to the log library
- # included in the NDK.
- ${log-lib} )
2.5 调用串口-连接,并获取输入输出流
- Runnable serialConnectRunnable = new Runnable() {
- @Override
- public void run() {
- try {
- if (mSerialPort == null) {
- mSerialPort = new SerialPort(new File(path), baudrate);
- mOutputStream = mSerialPort.getOutputStream();
- mInputStream = mSerialPort.getInputStream();
- }
- } catch (SecurityException e) {
- ToastUtil.showToast(App.getInstance(), "You do not have read/write permission to the serial port.");
- } catch (IOException e) {
- ToastUtil.showToast(App.getInstance(), "The serial port can not be opened for an unknown reason.");
- } catch (InvalidParameterException e) {
- ToastUtil.showToast(App.getInstance(), "Please configure your serial port first.");
- }
- //Serial结束
- }
- };
2.6 读取串口消息
- private class ReadThread extends Thread {
-
- @Override
- public void run() {
- super.run();
- while (!isInterrupted()) {
- int size;
- try {
- byte[] buffer = new byte[512];
- if (mInputStream == null) return;
- size = mInputStream.read(buffer);
- if (size > 0) {
- String mReception=new String(buffer, 0, size);
- String msg = mReception.toString().trim();
- Log.e(TAG, "接收短消息:" + msg);
- }
- } catch (IOException e) {
- e.printStackTrace();
- return;
- }
- }
- }
- }
2.7 发送串口指令
- private class WriteRunnable implements Runnable {
- @Override
- public void run() {
- try {
- String cmd="KZMT;";
- Log.e(TAG, "发送短消息:" + cmd);
- mOutputStream.write(cmd.getBytes());
- mOutputStream.flush();
- } catch (IOException e) {
-
- }
- }
- }
2.8 断开关闭串口
- /**
- * 关闭串口连接
- */
- public void closeSerialPortStream() {
- try {
- if (mOutputStream != null) {
- mOutputStream.close();
- mOutputStream = null;
- }
- if (mInputStream != null) {
- mInputStream.close();
- mInputStream = null;
- }
- if (mSerialPort != null) {
- mSerialPort.close();
- mSerialPort = null;
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
三 google官方串口工具类
3.1 除了上面自己编程C底层文件,也可以直接用google官方的串口工具SDK(android-serialport-api),Github串口Demo地址:https://github.com/licheedev/Android-SerialPort-API
3.2 依赖:
- allprojects {
- repositories {
- ...
- jcenter()
- mavenCentral() // since 2.1.3
- }
- }
-
- dependencies {
- implementation 'com.licheedev:android-serialport:2.1.3'
- }
3.3 使用
- // 默认8N1(8数据位、无校验位、1停止位)
- // Default 8N1 (8 data bits, no parity bit, 1 stop bit)
- SerialPort serialPort = new SerialPort(path, baudrate);
-
- // 可选配置数据位、校验位、停止位 - 7E2(7数据位、偶校验、2停止位)
- // or with builder (with optional configurations) - 7E2 (7 data bits, even parity, 2 stop bits)
- SerialPort serialPort = SerialPort
- .newBuilder(path, baudrate)
- // 校验位;0:无校验位(NONE,默认);1:奇校验位(ODD);2:偶校验位(EVEN)
- // Check bit; 0: no check bit (NONE, default); 1: odd check bit (ODD); 2: even check bit (EVEN)
- // .parity(2)
- // 数据位,默认8;可选值为5~8
- // Data bit, default 8; optional value is 5~8
- // .dataBits(7)
- // 停止位,默认1;1:1位停止位;2:2位停止位
- // Stop bit, default 1; 1:1 stop bit; 2: 2 stop bit
- // .stopBits(2)
- .build();
-
- // read/write to serial port - needs to be in different thread!
- InputStream in = serialPort.getInputStream();
- OutputStream out = serialPort.getOutputStream();
-
- // close
- serialPort.tryClose();
四 总结
串口通讯使用到进程、Linux指令、JNI等,但本质最终还是获得一个输入输出流去进行读写操作;
串口通讯对于Android开发者来说,仅需关注如何连接、操作(发送指令)、读取数据。
大部分的物联网通信本质上都是获取io流,通过io流进行数据的传输和读取,比如蓝牙,wifi等,只不过蓝牙,wifi是通过Socket协议维持一个长连接进行通信
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。