关于串口编程的总结2

我们的程序收发十六进制命令,假设采用16个字节,一个包头(1字节),一个控制(命令字1字节),一个具体命令(数据13字节),一个校验位(1字节),由于java本身对内部控制的应用较少,所以这个前后总共花费了五六个小时才搞定,特此记录一下。

这个程序还是有一些缺点的,就是它并不是一次性的返回所有数据,我尝试了很多方式都不行,最后通过判断的方式只接受一条完整有效的命令。

类型转换

java的操作一般都是对字符串或数组的操作为主,这里的转换有两种方式:

数组

对数组的操作,就是定义一个16字节数组,然后对每一个字节单独赋值。

优点很明显,就是可以准确的控制到每一个字节,校验比对都很方便

缺点也同样明显,当命令较多时,编写不易,而且校验起来很麻烦。

byte[] buffer = new byte[16];
buffer[0] = (byte) 0xFD;
...

字符串

字符串是java中最常用的,优缺点也同样明显,但我还是用字符串了

首先命令得是确定值,因为字符串的修改,并不如数组那样方便,为了方便,我们在每个字节中加个空格,方便查看:

String commandStr = "FD E1 01 00 00 00 00 00 00 00 00 00 00 00 00 E2";

然后就是把它转换为byte数组,但是字符串有个问题,就是每次读取的是一个char,比如FD,会被分成两个部分,那么在编写转换类的时候,就需要把它们合成一个。

  1. 一个字节是8位, 那么我们首先取得F,然后左移4位,放在高4位的位置,低4位归零,D通过转换后放在第四位的位置上,这样就合并为一个完整的字节了:高4位 0x0f0,低4位 0x ff
  2. 对位置来说,我们每次需要取得两位进行合并,所以每次需要索引到字符串中对应的位置,下面的代码中封装为toByte方法
  3. 将Byte数组转换为hexString就太特么方便了,一下就 体现出java那强大的特性
// 十六进制字符串转二进制数组
public static byte[] hexStringToByte(String hex) {
    hex = hex.replace(" ", "");
    int len = (hex.length() / 2);
    byte[] result = new byte[len];
    char[] achar = hex.toCharArray();
    for (int i = 0; i < len; i++) {
        int pos = i * 2;
        result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
    }
    return result;
}

//获取char的索引
private static int toByte(char c) {
    return (byte) "0123456789ABCDEF".indexOf(c);
}

// byte数组转换为十六进制字符串,用java提供的转换类即可
public static final String bytesToHexString(byte[] bArray) {
    StringBuffer sb = new StringBuffer(bArray.length);
    String sTemp;
    for (int i = 0; i < bArray.length; i++) {
        sTemp = Integer.toHexString(0xFF & bArray[i]);
        if (sTemp.length() < 2)
            sb.append(0);
        sb.append(sTemp.toUpperCase());
    }
    return sb.toString();
}

对SerialPortActivity的修改

之前对串口的封装及代码已经在 关于串口编程的总结 中了

对于read的无数次测试,最后我发现,还是没找到一次性读取的办法,如果有大神有好的办法可留言告诉我一声,万分感谢!!!

基本每次都读取一个字符的东西,但是有个问题,就是并不是所有的都是一个字节,有可能超出1个字节,为了防止这种事情发生,最好限定每次只读一个字节

size = mInputStream.read(buffer, 0, 1);

对应用类的修改

  1. 为了防止越界,还是把抽象方法加上一个size比较好,虽然已经是稳定的1个字节了..
  2. 判断包头是否正确
  3. 拷贝数组到全局变量,并线性偏移
@Override
protected void onDataReceived(byte[] buffer, int size) {
    try {

        if ((mSize == 0) && (buffer[0] == (byte) 0xFD)) {
            System.arraycopy(buffer, 0, mBuffer, mSize, size);
            mSize++;
        } else if (mSize > 0) {
            System.arraycopy(buffer, 0, mBuffer, mSize, size);
            mSize++;
        } else {
            L.e("初始值不是FD " + ConvertUtils.bytesToHexString(buffer));
        }

        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(runnable);

    } catch (ArrayIndexOutOfBoundsException e) {
        L.e("error: over 16 bit.");
    }

}

对于runnable来说,收到的消息同样要进行处理:

  1. 当runnable收到数据时,我们可预知命令大小是16个字节的,用全局size判断是否收取完整即可
  2. 包头 已经判断成功了,收取完整后通过约定的规则去判定校验位是否完整
  3. 对全局变量归零

if (mSize == 16) {
    byte checkBit = (byte) (mBuffer[1] + mBuffer[2]);
    if (checkBit == mBuffer[15]) {
        // do something..
        L.e("校验成功");

    }
    String mString = ConvertUtils.bytesToHexString(mBuffer);
    L.e("command:" + mString);

    mSize = 0;
    mBuffer = new byte[16];
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,310评论 0 5
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 4,867评论 0 9
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,618评论 0 10
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,151评论 0 4
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,503评论 6 13