Сводка по использованию последовательного порта Android

Готов к работе

  • Среда NDK
  • C-файл, используемый для последовательной связи

Примечание: путь к имени функции в файле c необходимо изменить , а также необходимо изменить как файл c, так и файл заголовка .h

Доступ к базовой библиотеке

Импорт с использованием библиотеки SO

  1. Создайте новую запись jni в основном каталоге и поместите туда файл C
  2. Создайте новые файлы Android.mk , Application.mk и настройте
  3. Скомпилируйте проект и получите скомпилированный файл библиотеки so.Сгенерированный каталог по умолчанию - app \ build \ intermediate \ jniLibs \ app \ debug \ armeabi, если скомпилированная версия выпуска находится в каталоге releaseasse.
  4. Создайте новый каталог jniLibs в основном каталоге и скопируйте сгенерированную библиотеку so в этот
  5. Настройте файл gradle в каталоге приложения
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. Создайте файл класса в коде, загрузите файл библиотеки so и определите метод открытия и закрытия последовательного порта.

Введение в CMake

  1. Создайте новую папку cpp в основном каталоге и поместите сюда исходный файл c
  2. Настройте файл 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. Настройте файл Gradle в приложении
android {   
    defaultConfig {
        ...
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}
  1. Создайте файл класса в коде, загрузите файл библиотеки so и определите метод открытия и закрытия последовательного порта.

Открыть / закрыть последовательный порт

Открывать и закрывать в jni

В файле C определены два метода, а именно открытие и закрытие последовательного порта. Метод открытия последовательного порта имеет возвращаемое значение, а возвращаемое значение - объект FileDescriptor.Мы используем этот объект для чтения и записи данных в последовательный порт.

Откройте последовательный порт

Запросить последовательный порт

Некоторые настраиваемые устройства могут иметь много последовательных портов. Какой последовательный порт нужно открыть нашему приложению? С одной стороны, вы можете запросить у производителя устройства имя последовательного порта, к которому нам нужно подключиться. С другой стороны, мы можем только перечислить все последовательные порты и попробовать их один за другим.

Запросить все последовательные порты:
определить класс SerialPortFinder и перечислить все последовательные порты и пути устройства, прочитав файл / proc / tty / drivers

Метод: метод getAllDevices () в SerialPortFinder , см. Код SerialPortFinder для конкретной реализации

включить

После нахождения соответствующего последовательного порта вызовите метод jni, чтобы открыть последовательный порт. При открытии вам необходимо передать три параметра: путь к последовательному порту, скорость передачи данных и метод открытия.

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

При открытии последовательного порта получается объект FileDescriptor, и на основе объекта создается поток ввода и вывода для реализации операций чтения и записи.

Закройте последовательный порт

Вам необходимо закрыть последовательный порт после использования и перед выходом из приложения. Это эквивалентно файловым операциям, которым необходимо закрыть файловый поток. Последовательная связь - это, по сути, файловая операция, поэтому ее необходимо закрыть.

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

Отправить / прочитать данные

Когда последовательный порт открыт, получается поток ввода и вывода, затем следующая отправка и чтение должны работать с этим потоком.

отправить данные:

Отправляемые данные представляют собой массив байтов. Если это строка, шестнадцатеричная команда и т. Д., Их необходимо преобразовать в массив байтов и отправить. Просто напишите данные в наш выходной поток.

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

Прочитать данные:

Прочтите данные относительно передаваемых данных, относительные шаги немного больше, потому что мы не знаем, когда я отправлю последовательные данные , поэтому необходимость постоянно открывать данные подпотока из входного потока, чтобы взять , когда взять длину данных Если он не равен 0, проанализируйте данные для следующего шага.

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;
}

Считанные данные также представляют собой массив байтов, и данные необходимо проанализировать. Как правило, поставщик оборудования предоставляет соответствующий метод анализа.

Последовательный порт читает и отправляет данные, в качестве идентификационных битов будет 2-5 байтов, обычно начиная с 0xFF, каждый пакет унифицирован, и вам нужно быть внимательными при отправке и анализе данных.

использовать

Вы можете открыть последовательный порт в приложении, а затем определить метод отправки и чтения данных в BaseActivity или BaseFragment проекта и вызвать его напрямую там, где вам нужно его использовать.

Прилагается

Исходный файл на C:

termios.h

SerialPort.h

SerialPort.c

Github

рекомендация

отblog.csdn.net/lizebin_bin/article/details/86159524
рекомендация