android串口通信(1)

                       android串口通信以及串口协议解析

 Java Code 
1
2
3
android串口通信大概功能是android系统端的ARM和系统外的一个MCU通信
通过android界面控制MCU上挂的设备,如radio、TV、BT等等,
过程图

 Java Code 
1
2
3
4
5
6
7
8
一,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重新编译了一下

 Java Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
二,串口通信协议解析
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
     */
  
     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, cursor, factPackLen);  
                    currentLength -= factPackLen;  
                    cursor += factPackLen;   
                }  
                 // 残留字节移到缓冲区首  
                 if  (currentLength >  0  && cursor >  0 ) {  
                    System.arraycopy(buffer, cursor, buffer,  0 , 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,  0 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,  0 , packlen);  
        ProtocolAnalyze.getInstance(myHandler).analyze(buf);   
    }
参考: 点击打开链接    点击打开链接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值