Android串口通讯SerialPort(浅谈原理)

前言:通过前面这篇文章串口通讯SerialPort(使用篇)已经基本掌握了串口的使用,那么不经想问自己,到底什么才是串口通讯呢?串口通讯(Serial Communication),设备与设备之间,通过输入线(RXD),输出线(TXD),地线(GND),按位进行传输数据的一种通讯方式。CPU 和串行设备间的编码转换器。当数据从 CPU 经过串行端口发送出去时,字节数据转换为串行的位;在接收数据时,串行的位被转换为字节数据。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通行的端口,这些参数必须匹;

(上母下公) 

一、名词解释:

1.波特率:用来表示通信速度的参数,它表示每秒钟传送的 bit 的个数;

2.数据位:通信中数据位的参数;

3.停止位:表示单个包的最后一位,停止位不仅仅是表示传输的结束,并且提供上位机正时钟同步的机会;

4.校验位:串口通信中一种简单的检错方式(偶校验[2]、奇校验[1]、无校验[0]);

二、SerialPort的函数分析:

谷歌为开发者提供了一个串口通讯的工具类SerialPort,其中SerialPort中有8个函数,其中有7个是公共方法提供给使用者调用;

1)public static void setSuPath(String suPath)

        用于设置 su 路径 默认的路径 /system/bin/su,(一般不会使用)

2)static String getSuPath()

        用于获取su路径(一般不会使用)

3)public InputStream getInputStream()

        获取输入流;通过此方法可以获取设备向上位机发送过来的数据。

4)public OutputStream getOutputStream()

        获取输出流;通过此方法可以向设备发送操作指令。

5)public native void close();

        关闭串口;通过此方法关闭串口。

6)public static Builder newBuilder(File device, int baudrate)

7)public static Builder newBuilder(String devicePath, int baudrate)

        用于构建串口对象。

8) private native FileDescriptor open(String absolutePath, int baudrate, int dataBits, int parity, int stopBits, int flags);

        用于开启串口通讯,私有的方法,开发者只需创建一个SerialPort对象,函数会自动调用。

三、SerialPort打开串口的流程

1.通过Runtime,获取当串口进程。

2.向Linux内核发送一个"chmod 666 "指令设置串口进程的权限。

3.通过JNI方法获取文件描述符对象。

4.通过文件描述符对象获取输入输出流。

四、疑惑

在上述的加载流程中,不禁有一个疑问,为什么SerialPort中的open()、close()函数都用native去修饰,不用不行么?

于是我从open()入手,open返回一个对象叫FileDescriptor(文件描述符),那么这个类有什么作用呢?

于是我打开了FileDescriptor,注释是这么描述的:文件描述符类的实例充当底层特定于机器的结构的不透明句柄,该结构表示打开的文件、打开的套接字或另一个字节源或汇。文件描述符的主要实际用途是创建一个FileInputStream或FileOutputStream来包含它。应用程序不应该创建自己的文件描述符。

 结合《JNI编程指南》推荐使用场景

 既然串口通讯使用到了JNI,那么也将继承JNI编程的缺点,APP的兼容性将会变差。

五、总结

虽然串口通讯使用到进程、Linux指令、JNI...,但抛开现象看本质,最终目标还是获得一个输入输出流去进行读写操作。

  • 9
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Android中串口(SerialPort)接收数据的Demo示例如下: ```java import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import java.io.File; import java.io.IOException; import java.io.InputStream; import android_serialport_api.SerialPort; public class SerialPortActivity extends AppCompatActivity { private SerialPort mSerialPort; private InputStream mInputStream; private ReadThread mReadThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_serial_port); try { mSerialPort = new SerialPort(new File("/dev/ttyS1"), 9600, 0); mInputStream = mSerialPort.getInputStream(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } mReadThread = new ReadThread(); mReadThread.start(); } private class ReadThread extends Thread { @Override public void run() { super.run(); while (!isInterrupted()) { try { if (mInputStream == null) { return; } byte[] buffer = new byte[1024]; int size = mInputStream.read(buffer); if (size > 0) { String data = new String(buffer, 0, size); Log.d("SerialPort", "Received data: " + data); // 处理接收到的数据... } } catch (IOException e) { e.printStackTrace(); } } } } @Override protected void onDestroy() { super.onDestroy(); if (mReadThread != null) { mReadThread.interrupt(); mReadThread = null; } if (mSerialPort != null) { mSerialPort.close(); mSerialPort = null; } } } ``` 以上是一个Android中通过串口接收数据的示例代码。在`onCreate`方法中,首先打开串口并获取输入流。然后创建一个`ReadThread`线程用于循环读取串口数据。在`ReadThread`线程的`run`方法中通过`InputStream`的`read`方法读取数据,并将读取到的数据进行处理(这里只是简单地打印出来)。在`onDestroy`方法中,关闭串口和销毁线程。 需要注意的是,这里使用到了一个`android_serialport_api`库,需要在项目的`build.gradle`文件中添加对应的依赖。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值