Resumen de uso del puerto serie de Android

Listo para trabajar

  • Entorno NDK
  • Archivo C utilizado para la comunicación en serie

Nota: La ruta del nombre de la función en el archivo c debe modificarse , y tanto el archivo c como el archivo de encabezado .h deben modificarse

Acceso a la biblioteca subyacente

Importar usando la biblioteca SO

  1. Cree un nuevo registro jni en el directorio principal y coloque el archivo C allí
  2. Cree nuevos archivos Android.mk , Application.mk y configure
  3. Compile el proyecto y obtenga el archivo de biblioteca compilado. El directorio generado por defecto es app \ build \ intermediates \ jniLibs \ app \ debug \ armeabi, si la versión de lanzamiento compilada está en el directorio de lanzamiento
  4. Cree un nuevo directorio jniLibs en el directorio principal y copie la biblioteca generada a este
  5. Configurar el archivo gradle en el directorio de la aplicación
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        ndk {
            moduleName "serial_port"
            ldLibs "log", "z", "m"
            abiFilters "armeabi", "x86"
        }
    }

    debug {
        ndk {
            moduleName "serial_port"
            ldLibs "log", "z", "m"
            abiFilters "armeabi", "x86"
        }
    }
}
  1. Cree un archivo de clase en el código, cargue el archivo de biblioteca so y defina el método para abrir y cerrar el puerto serie

Introducción de CMake

  1. Cree una nueva carpeta cpp en el directorio principal y coloque el archivo fuente c aquí
  2. Configure el archivo CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)

# 查找cpp目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRC 变量
aux_source_directory(src/main/cpp/ DIR_LIB_SRC)

#设置源文件
add_library(SerialPort SHARED ${DIR_LIB_SRC})

#表明头文件位置
#include_directories(src/main/cpp/)

find_library( # Sets the name of the path variable.
        log-lib
        log)
target_link_libraries( # Specifies the target library.
        SerialPort
        ${log-lib})
  1. Configure el archivo gradle en la aplicación
android {   
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}
  1. Cree un archivo de clase en el código, cargue el archivo de biblioteca so y defina el método para abrir y cerrar el puerto serie

Puerto serie abierto / cerrado

Abrir y cerrar en jni

Se definen dos métodos en el archivo C, a saber, abrir y cerrar el puerto serie. El método para abrir el puerto serie tiene un valor de retorno, y el valor de retorno es un objeto FileDescriptor. Usamos este objeto para leer y escribir datos en el puerto serie.

Abra el puerto serial

Consultar puerto serie

Algunos dispositivos personalizados pueden tener muchos puertos serie. ¿Qué puerto serie necesita abrir nuestra aplicación? Por un lado, puedes pedirle al fabricante del dispositivo el nombre del puerto serie al que debemos conectarnos, por otro lado, solo podemos listar todos los puertos serie y probarlos uno por uno.

Consultar todos los puertos seriales:
defina la clase SerialPortFinder y enumere todos los puertos seriales y rutas del dispositivo leyendo el archivo / proc / tty / drivers

Método: método getAllDevices () en SerialPortFinder , consulte el código SerialPortFinder para una implementación específica

encender

Después de encontrar el puerto serie correspondiente, llame al método jni para abrir el puerto serie. Al abrir, debe pasar tres parámetros, que son la ruta del puerto serie, la velocidad en baudios y el método de apertura.

public SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException {
    if (mSerialPort == null) {
        //这里是打开了/dev/ttyS3 串口,波特率9600,
        mSerialPort = new SerialPort(new File("/dev/ttyS3"), 9600, 0);
    }
    return mSerialPort;
}

Al abrir el puerto serie, se obtiene un objeto FileDescriptor y se crea un flujo de entrada y salida basado en el objeto para realizar operaciones de lectura y escritura.

Cerrar el puerto serial

Debe cerrar el puerto serie después de su uso y antes de salir de la aplicación. Es equivalente a las operaciones de archivo que necesitan cerrar el flujo de archivos. La comunicación en serie es esencialmente una operación de archivo, por lo que debe cerrarse

/**
 * 关闭串口
 * 使用结束时记得关闭串口
 */
public void closeSerialPort() {
    if (mSerialPort != null) {
        //调用native方法关闭串口
        mSerialPort.close();
        mSerialPort = null;
    }
}

Enviar / leer datos

Cuando se abre el puerto serie, se obtiene el flujo de entrada y salida, luego el siguiente envío y lectura debe operar en este flujo.

enviar datos:

El envío de datos es una matriz de bytes, si es una cadena, comando hexadecimal, etc., debe convertirse en una matriz de bytes y enviarse. Simplemente escriba datos en nuestro flujo de salida.

public void sendBufferToSerial(byte[] data) {
    try {
        mFileOutputStream.write(data);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Leer datos:

Leer datos con respecto a los datos de transmisión, los pasos relativos un poco más, porque no sabemos cuándo enviaré datos en serie , por lo que es necesario abrir constantemente un subproceso de datos del flujo de entrada para tomar , cuándo tomar la longitud de los datos Cuando no es 0, analiza los datos para el siguiente paso.

class ReadThread extends Thread {
    @Override
    public void run() {
        super.run();
        while (!isInterrupted()) {
            int size;
            final byte[] buffer;
            try {
                buffer = new byte[128];
                if (mFileInputStream == null) return;
                size = mFileInputStream.read(buffer);

                if (size > 0) {
                    //回调
                    if (listener != null)
                        listener.receiveData(size, buffer);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


/**
 * 开始接收串口数据
 *
 * @param onReceiveDataListener 数据回调
 */
public void startReceiveData(OnReceiveDataListener onReceiveDataListener) {
    readThread = new ReadThread();
    readThread.start();
    listener = onReceiveDataListener;
}

/**
 * 停止接收数据
 */
public void stopReceiveData() {
    if (readThread != null) {
        if (readThread.isInterrupted())
            readThread.interrupt();
    }
    readThread = null;
    listener = null;
}

Los datos leídos también son la matriz de bytes y los datos deben analizarse. Generalmente, el proveedor del equipo proporcionará el método de análisis correspondiente.

El puerto serie lee y envía datos, habrá 2-5 bytes como bits de identificación, generalmente comenzando con 0xFF, cada paquete está unificado y debe prestar atención al enviar y analizar datos

utilizar

Puede elegir abrir el puerto serie en la Aplicación y luego definir el método de envío y lectura de datos en BaseActivity o BaseFragment del proyecto, y llamarlo directamente donde necesite usarlo.

Adjunto

Archivo fuente C:

termios.h

SerialPort.h

SerialPort.c

Github

Supongo que te gusta

Origin blog.csdn.net/lizebin_bin/article/details/86159524
Recomendado
Clasificación