您好,登錄后才能下訂單哦!
近日編寫了一個手機的燈控系統:
因為添加了許多以前不具備的功能,并且為了數據傳輸更加穩定,格式更加規范,并且為了以后再進行同類項目的格式統一,本次特地根據計算機網絡,在已有的協議HipulseU基礎上進一步改造,自制了一套應用層的協議。
首先本套協議的格式定義如下:
協議格式:
SOI 7EH 起始位標志 1字節 ASCII: 7EH
VER 10H 1字節 ASCII: 31H,30H
ADR 01H 1字節 ASCII:30H,31H
CID1 命令 41H 運行控制命令
42H 配置文件讀寫命令
43H 時鐘控制命令
44H 寫EEPROM命令
45H 寫文件名
CID2 輔助命令 1字節
----------------------------------------------------------------------------------------------------------------------
CID1=41H時 運行命令
CID2:
10H:參數配置信息n條每條14字節HEX(28字節ASCII碼)
13H:參數運行EEPROM中的配置信息開機缺省。
14H: 參數運行CID1=45H中指定的文件。
20H:停止命令
----------------------------------------------------------------------------------------------------------------------
CID1=42H時 寫配置文件
CID2:
00H:~FEH 寫配置文件
FFH: 寫配置文件,續寫配置文件結束
CID1=43H:時鐘
CID2:
00H:寫時鐘命令格式: 年-月-日-星期-時-分-秒 (分別為兩個字節ASCII碼)
01H:讀時鐘命令格式: 年-月-日-星期-時-分-秒
02H:設置開機關機時間
格式 開始:(年-月-日-參數-時-分-秒)
結束:(年-月-日-參數-時-分-秒)
參數:兩字節ASCII碼
D7 D6 D5 D4 D3 D2 D1 D0
0 1 1 1 1 1 1 1
星期 日 六 五 四 三 二 一
1 0 0 0 0 0 0 0
年月日十分秒
1 1 1
----------------------------------------------------------------------------------------------------------------------
CID1=44H時向EEPROM寫配置信息
CID2:
00H:向EEPROM寫配置信息
----------------------------------------------------------------------------------------------------------------------
CID1=45H:文件名
CID2:
00H:文件名(寫入或運行的文件名,1字節)
----------------------------------------------------------------------------------------------------------------------
CID1=46H:預覽設置
CID2:
00H: 1倍
01H: 10倍
02H:100倍
03H:1000倍
----------------------------------------------------------------------------------------------------------------------
LENGTH 2字節長度 先傳高字節再傳低字節
其中:校驗碼:LCHKSUM=D15~D12
長度標示碼:LENID=D11~D0 表示INFO中傳送的ASCII碼字節數
校驗碼計算:D11~D8+D7~D4+D3~D0,求和后模16余數取反加1
INFO數據格式
COMMAND INFO
CHKSUM數據格式
CHKSUM的計算是除SOI,EOI和CHKSUM外,其它字符按ASCII碼值累加求和,所得結果模65536余數取反加1
EOI 0DH 結束碼
響應信息
SOI 7EH 起始位標志 1字節 ASCII: 7EH
VER 10H 1字節 ASCII: 31H,30H
ADR 01H 1字節 ASCII:30H,31H
CID1 60H
CID2 RTN
LENGTH 2字節長度 先傳高字節再傳低字節
其中:校驗碼:LCHKSUM=D15~D12
長度標示碼:LENID=D11~D0 表示INFO中傳送的ASCII碼字節數
校驗碼計算:D11~D8+D7~D4+D3~D0,求和后模16余數取反加1
INFO數據格式
DATA INFO
CHKSUM數據格式
CHKSUM的計算是除SOI,EOI和CHKSUM外,其它字符按ASCII碼值累加求和,所得結果模65536余數取反加1
EOI 0DH 結束碼
RTN:
00:正常
01:VER錯
02:CHKSUM錯
03:LCHKSUM錯
04: CID2無效
05:命令格式錯
06:無效命令
E0:地址錯
E1~EFH:其它錯誤
12H:參數文件名 文件中存配置文件名每個配置文件名1字節(ASCII兩字節)
11H:參數文件名 每個1字節(兩字節ASCII碼)
協議中的所有內容都是把一字節的內容,用兩字節的ascii碼來替換,例如原本的內容是一字節0x2f,最終會被替換為
0x32 0x46(2的ascii碼是0x32,f的ascii碼是0x46)
由于本次使用的是Android編程所以最終協議被封裝成java包,
首先定義數據格式類把要傳輸的數據定義為Data類:
public class Data {private byte[] sol;private byte[] eol;private byte[] ver;private byte[] adr;private byte[] cid1;private byte[] cid2;private byte[] lenid;private byte[] info;private byte[] chksum; //以下定義Data類的各個數據成員變量的getter和setter方法 }
再定義一個DataOperator類用對,Data類進行各種操作。
由于要進行十六進制代碼與ascii碼之間的轉換所以,要創建一個靜態數組來進行兩者的對應:
public class Ascii { public static byte[] ASCII = new byte[] { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }; }
下面主要介紹 LCHKSUM的計算方法和CHKSUN的計算方法:
下面是LCHKSUM的計算方法,該方法通過對相應的LENGTH內容進行構造LCHKSUM
public byte[] createLength_chksum(byte[] src) { byte[] result = new byte[1]; // 用來記錄計算len_chksum時的中間轉換變量 int len_check = 0; // 計算len_chksum先計算長度每個字節所代表的ascii碼的字符的真值和 for (int i = 0; i < 3; i++) { if (src[i] > 0x39) { len_check = len_check + (src[i] & 0xff) - 0x37; } else { len_check = len_check + (src[i] & 0xff) - 0x30; } } // System.out.println(len_check); // 把相應的和模16 len_check %= 16; // 再把結果取反 len_check = 16 - len_check; // 得到結果的ascii碼的真值 if (len_check == 16) { result[0] = 0; } else { result[0] = Ascii.ASCII[len_check]; } // System.out.println(result[0]); return result; }
下面是CHKSUM的計算方法,參數為整個數據(除了開始和結束位):
public byte[] createChksum(byte[] src) { // 用來記錄計算chksum時的中間轉換變量 int check = 0; // 用來存放chksum結果 byte[] result = new byte[4]; // 計算每一字節的和 for (int i = 1; i < src.length; i++) { // System.out.println(src[i]); int a = src[i] & 0xff; check = check + a; } System.out.println(check); // 把和對65535求余數 check = check % 65536; // 再把求余之后的結果取反 check = 65536 - check; // 把最后的結果分為四字節的ascii碼 result[0] = Ascii.ASCII[((check >> 12) & 0x0000000f)]; result[1] = Ascii.ASCII[((check >> 8) & 0x0000000f)]; result[2] = Ascii.ASCII[((check >> 4) & 0x0000000f)]; result[3] = Ascii.ASCII[((check & 0x0000000f))]; System.out.println(result[0] + " " + result[1] + " " + result[2] + " " + result[3]); return result; }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。