Android 串口通信编程及串口协议分析

Android 串口通信编程及串口协议分析,第1张

概述Android串口通信编程:嵌入式编程和可穿戴设备及智能设备都会用到串口,这里就带大家分析下,

AndroID 串口通信编程:嵌入式编程和可穿戴设备及智能设备都会用到串口,这里就带大家分析下,

一,androID串口通信

串口通信采用一个第三方开源项目,实现串口数据收发。

1. 使用了http://code.Google.com/p/androID-serialport-API/的项目的serialport API和jni;
2. 支持4串口同时收发,有定时自动发送功能,收发模式可选Txt或Hex模式;
3.  n,8,1,没得选;
4. 为减轻界面卡顿的情况,接收区的刷新采用单独的线程进行定时刷新;
5. 发送区的数据以及一些设置项,在程序关闭时会自动保存,打开时自动载入;
6. jni使用最新的NDKr8b重新编译了一下

简单编写步骤:

1.新建一个项目,自己起个名字
2.直接复制serialport API和jni文件夹到新建的工程,如果不想自己编译jni,就连libs文件夹也一起复制
3.去androID官方网站下载NDK,解压,在CMD中转到jni目录,并执行 绝对路径\ndk-build
4.自己再封装一个工具类或直接使用SerialPort类都行,举个直接使用的例:
直接剽窃原项目的SerialPortActivity.java,并稍微改一下,重点改这里
mSerialPort = mApplication.getSerialPort();
这里可以改成
new SerialPort(new file("/dev/s3c2410_serial0"),9600,0);//COM0,波特率9600
5. SerialPortFinder的使用就没什么好讲的了,实例化后用.getAllDevicesPath()就能获取到所有设备了。
其它如数据转换等请参考源码

源码可以参考谷歌androID-serialport-API例子

http://code.Google.com/p/androID-serialport-API/source/checkout
svn checkout http://androID-serialport-API.Googlecode.com/svn/trunk

二,串口通信协议解析

1.通信基本格式

字段 描述 长度(字节)
起始符 0F,十六进制码  1
信息类型 一个字节,十六进制码(0F,F0,FF等保留码不用)1
信息长度 是信息内容的长度,ASCII码表示(0~9,A~F,最大长度为256)(例如长为11个,十六进制是0B,则两个字节就写0x30 0x42)。
注:因为最大长度256不能满足有些指令的要求,所以对长度做了扩展,下面是扩展说明:
如果第一个字节的最高位为1,则表示扩展长度。在扩展长度状态下,其他15个字节通过16进制大端模式来保存长度。比如:0x80 0x12表示长度为0x001 2,0x81 0x12表示长度为0x0112。2
信息内容 一组十六进制码  N
校验 一个字节,十六进制码,是自信息类型起至对象号止所有码的异或。1
结束符 F0,一个字节,十六进制码 (为了保证可靠性,车机下发的结束符为F0 FF)1

2.协议解析

/**    * 读取终端设备数据    * @author administrator    */   private class ReadThread extends Thread {      @OverrIDe     public voID run() {       super.run();        // 定义一个包的最大长度       int maxLength = 2048;       byte[] buffer = new byte[maxLength];       // 每次收到实际长度       int available = 0;       // 当前已经收到包的总长度       int currentLength = 0;       // 协议头长度4个字节(开始符1,类型1,长度2)       int headerLength = 4;        while (!isInterrupted()) {         try {           available = minputStream.available();           if (available > 0) {             // 防止超出数组最大长度导致溢出             if (available > maxLength - currentLength) {               available = maxLength - currentLength;             }             minputStream.read(buffer,currentLength,available);             currentLength += available;           }                    }         catch (Exception e) {           e.printstacktrace();         }          int cursor = 0;         // 如果当前收到包大于头的长度,则解析当前包         while (currentLength >= headerLength) {           // 取到头部第一个字节           if (buffer[cursor] != 0x0F) {             --currentLength;             ++cursor;             continue;           }                      int contentLenght = parseLen(buffer,cursor,headerLength);           // 如果内容包的长度大于最大内容长度或者小于等于0,则说明这个包有问题,丢弃           if (contentLenght <= 0 || contentLenght > maxLength - 5) {             currentLength = 0;             break;           }           // 如果当前获取到长度小于整个包的长度,则跳出循环等待继续接收数据           int factPackLen = contentLenght + 5;           if (currentLength < contentLenght + 5) {             break;           }            // 一个完整包即产生           // proceOnePacket(buffer,i,factPackLen);           onDataReceived(buffer,factPackLen);           currentLength -= factPackLen;           cursor += factPackLen;          }         // 残留字节移到缓冲区首         if (currentLength > 0 && cursor > 0) {           System.arraycopy(buffer,buffer,currentLength);         }       }     }   }    /**    * 获取协议内容长度    * @param header    * @return    */   public int parseLen(byte buffer[],int index,int headerLength) {  //   if (buffer.length - index < headerLength) { return 0; }     byte a = buffer[index + 2];     byte b = buffer[index + 3];     int rlt = 0;     if (((a >> 7) & 0x1) == 0x1) {       rlt = (((a & 0x7f) << 8) | b);     }     else {       char[] tmp = new char[2];       tmp[0] = (char) a;       tmp[1] = (char) b;       String s = new String(tmp,2);       rlt = Integer.parseInt(s,16);     }      return rlt;   }  protected voID onDataReceived(final byte[] buffer,final int index,final int packlen) {     System.out.println("收到信息");     byte[] buf = new byte[packlen];     System.arraycopy(buffer,index,buf,packlen);     ProtocolAnalyze.getInstance(myHandler).analyze(buf);    } 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

总结

以上是内存溢出为你收集整理的Android 串口通信编程及串口协议分析全部内容,希望文章能够帮你解决Android 串口通信编程及串口协议分析所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1149665.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存