Android 串口通訊編程及串口協議分析_Android

來源:互聯網
上載者:User

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()就能擷取到所有裝置了。
其它如資料轉換等請參考源碼

源碼可以參考Googleandroid-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, 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);    } 

感謝閱讀,希望能協助到大家,謝謝大家對本站的支援!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.