欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 串口通信編程及串口協(xié)議分析

 更新時(shí)間:2016年11月02日 14:50:43   投稿:lqh  
這篇文章主要介紹了Android 串口通信編程及串口協(xié)議分析的相關(guān)資料,這里對(duì)Android 串口通信進(jìn)行詳解,及簡(jiǎn)單實(shí)現(xiàn)步驟和協(xié)議進(jìn)行分析,需要的朋友可以參考下

Android 串口通信編程:嵌入式編程和可穿戴設(shè)備及智能設(shè)備都會(huì)用到串口,這里就帶大家分析下,

一,android串口通信

串口通信采用一個(gè)第三方開源項(xiàng)目,實(shí)現(xiàn)串口數(shù)據(jù)收發(fā)。

1. 使用了http://code.google.com/p/android-serialport-api/的項(xiàng)目的serialport api和jni;
2. 支持4串口同時(shí)收發(fā),有定時(shí)自動(dòng)發(fā)送功能,收發(fā)模式可選Txt或Hex模式;
3.  n,8,1,沒得選;
4. 為減輕界面卡頓的情況,接收區(qū)的刷新采用單獨(dú)的線程進(jìn)行定時(shí)刷新;
5. 發(fā)送區(qū)的數(shù)據(jù)以及一些設(shè)置項(xiàng),在程序關(guān)閉時(shí)會(huì)自動(dòng)保存,打開時(shí)自動(dòng)載入;
6. jni使用最新的NDKr8b重新編譯了一下

簡(jiǎn)單編寫步驟:

1.新建一個(gè)項(xiàng)目,自己起個(gè)名字
2.直接復(fù)制serialport api和jni文件夾到新建的工程,如果不想自己編譯jni,就連libs文件夾也一起復(fù)制
3.去android官方網(wǎng)站下載NDK,解壓,在CMD中轉(zhuǎn)到j(luò)ni目錄,并執(zhí)行 絕對(duì)路徑\ndk-build
4.自己再封裝一個(gè)工具類或直接使用SerialPort類都行,舉個(gè)直接使用的例:
直接剽竊原項(xiàng)目的SerialPortActivity.java,并稍微改一下,重點(diǎn)改這里
mSerialPort = mApplication.getSerialPort();
這里可以改成
new SerialPort(new File("/dev/s3c2410_serial0"), 9600, 0);//COM0,波特率9600
5. SerialPortFinder的使用就沒什么好講的了,實(shí)例化后用.getAllDevicesPath()就能獲取到所有設(shè)備了。
其它如數(shù)據(jù)轉(zhuǎn)換等請(qǐng)參考源碼

源碼可以參考谷歌android-serialport-api例子

http://code.google.com/p/android-serialport-api/source/checkout
svn checkout http://android-serialport-api.googlecode.com/svn/trunk

二,串口通信協(xié)議解析

1.通信基本格式

字段 描述 長(zhǎng)度(字節(jié))
起始符 0F,十六進(jìn)制碼  1
信息類型 一個(gè)字節(jié),十六進(jìn)制碼(0F,F0,FF等保留碼不用)1
信息長(zhǎng)度 是信息內(nèi)容的長(zhǎng)度,ASCII碼表示(0~9,A~F,最大長(zhǎng)度為256)(例如長(zhǎng)為11個(gè),十六進(jìn)制是0B,則兩個(gè)字節(jié)就寫0x30 0x42)。
注:因?yàn)樽畲箝L(zhǎng)度256不能滿足有些指令的要求,所以對(duì)長(zhǎng)度做了擴(kuò)展,下面是擴(kuò)展說明:
如果第一個(gè)字節(jié)的最高位為1,則表示擴(kuò)展長(zhǎng)度。在擴(kuò)展長(zhǎng)度狀態(tài)下,其他15個(gè)字節(jié)通過16進(jìn)制大端模式來(lái)保存長(zhǎng)度。比如:0x80 0x12表示長(zhǎng)度為0x001 2,0x81 0x12表示長(zhǎng)度為0x0112。2
信息內(nèi)容 一組十六進(jìn)制碼  N
校驗(yàn) 一個(gè)字節(jié),十六進(jìn)制碼,是自信息類型起至對(duì)象號(hào)止所有碼的異或。1
結(jié)束符 F0,一個(gè)字節(jié),十六進(jìn)制碼 (為了保證可靠性,車機(jī)下發(fā)的結(jié)束符為F0 FF)1

2.協(xié)議解析


/** 
   * 讀取終端設(shè)備數(shù)據(jù) 
   * @author Administrator 
   */ 
  private class ReadThread extends Thread { 
 
    @Override 
    public void run() { 
      super.run(); 
 
      // 定義一個(gè)包的最大長(zhǎng)度 
      int maxLength = 2048; 
      byte[] buffer = new byte[maxLength]; 
      // 每次收到實(shí)際長(zhǎng)度 
      int available = 0; 
      // 當(dāng)前已經(jīng)收到包的總長(zhǎng)度 
      int currentLength = 0; 
      // 協(xié)議頭長(zhǎng)度4個(gè)字節(jié)(開始符1,類型1,長(zhǎng)度2) 
      int headerLength = 4; 
 
      while (!isInterrupted()) { 
        try { 
          available = mInputStream.available(); 
          if (available > 0) { 
            // 防止超出數(shù)組最大長(zhǎng)度導(dǎo)致溢出 
            if (available > maxLength - currentLength) { 
              available = maxLength - currentLength; 
            } 
            mInputStream.read(buffer, currentLength, available); 
            currentLength += available; 
          } 
           
        } 
        catch (Exception e) { 
          e.printStackTrace(); 
        } 
 
        int cursor = 0; 
        // 如果當(dāng)前收到包大于頭的長(zhǎng)度,則解析當(dāng)前包 
        while (currentLength >= headerLength) { 
          // 取到頭部第一個(gè)字節(jié) 
          if (buffer[cursor] != 0x0F) { 
            --currentLength; 
            ++cursor; 
            continue; 
          } 
           
          int contentLenght = parseLen(buffer, cursor, headerLength); 
          // 如果內(nèi)容包的長(zhǎng)度大于最大內(nèi)容長(zhǎng)度或者小于等于0,則說明這個(gè)包有問題,丟棄 
          if (contentLenght <= 0 || contentLenght > maxLength - 5) { 
            currentLength = 0; 
            break; 
          } 
          // 如果當(dāng)前獲取到長(zhǎng)度小于整個(gè)包的長(zhǎng)度,則跳出循環(huán)等待繼續(xù)接收數(shù)據(jù) 
          int factPackLen = contentLenght + 5; 
          if (currentLength < contentLenght + 5) { 
            break; 
          } 
 
          // 一個(gè)完整包即產(chǎn)生 
          // proceOnePacket(buffer,i,factPackLen); 
          onDataReceived(buffer, cursor, factPackLen); 
          currentLength -= factPackLen; 
          cursor += factPackLen;  
        } 
        // 殘留字節(jié)移到緩沖區(qū)首 
        if (currentLength > 0 && cursor > 0) { 
          System.arraycopy(buffer, cursor, buffer, 0, currentLength); 
        } 
      } 
    } 
  } 
 
  /** 
   * 獲取協(xié)議內(nèi)容長(zhǎng)度 
   * @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);  
  } 

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

最新評(píng)論