最近開發中用rs485
串列埠命令去控制繼電器和風機調速,用到了mudbus
指令。通過串列埠會傳送一串』 01 06 00 01 01 00 d9 9a '這樣的命令到繼電器,從而達到控制的目的。起初,對這命令感到疑惑,最後經過文件檢視及分析,發現不同的位代表了不同含義:裝置位址(01)、功能號(06)、資料位址(0001)、資料(0100)、crc16校驗(d99a)。
其中crc16校驗是怎麼得出的,由什麼的得出的讓我感到困惑,文件也沒有說明,經過查閱發現crc16校驗是對前面的命令,也就是』 01 06 00 01 01 00 『進行了crc16校驗計算,從而得到所需要的』d9 9a』 ,再進行傳送。
crc即迴圈冗餘校驗碼(cyclic redundancy check),是資料通訊領域中最常用的一種查錯校驗碼。奇偶校驗雖然簡單,但是漏檢率太高,而crc則要低的多,所以大多數都是使用crc來校驗。crc只能檢錯,不能糾錯。如果發現錯誤,可根據雙方協議規定要求傳送方重新傳送。
crc校驗,本質上是模2除法求餘。將傳送資訊m(x)當做被除數,傳送方和接收方共同約定乙個除數g(x),然後求餘r(x),該餘數r(x)即為crc值。原始資訊中某位發生變化,則crc值發生翻天覆地的變化,因此檢錯比較高效。
傳送方根據傳送報文,計算出crc值。將原始資訊和該crc值一起傳送給接收方。接收方根據原始資訊,按照同樣的演算法,計算crc。如果計算的crc值不正確的話,則表明在資料傳輸的過程中,原始資訊(或者crc值)發生錯誤。
方法1:
/**
* 計算crc16校驗碼
* * @param bytes 需要計算的位元組陣列
*/public
static string getcrc
(byte
bytes)
else}}
return integer.
tohexstring
(crc)
;}
方法2:
/**
* 查表法計算crc16校驗
* * @param data 需要計算的位元組陣列
*/public
static string gettablecrc
(byte
data)
;byte
crc16_l =
;int crc;
int uccrchi =
0x00ff
;int uccrclo =
0x00ff
;int iindex;
for(
byte datum : data)
crc =
((uccrchi &
0x00ff
)<<8)
|(uccrclo &
0x00ff)&
0xffff
;//高低位互換,輸出符合相關工具對modbus crc16的運算
crc =
((crc &
0xff00
)>>8)
|((crc &
0x00ff
)<<8)
;return string.
format
("%04x"
, crc)
;}
起初輸入時候,直接以字串輸入』010600010100』, 得到數值為』a118』,發現並不是我想要的值。發現是ascii校驗結果,而我想要的是十六進製制校驗結果。所以需要轉換,通過
byte
bytes =
newbiginteger
("010600010100",16
).tobytearray()
;
方法進行轉換,然後進行crc計算,即得到結果』d9 9a』。 Android串列埠除錯
前面有乙個客戶需要系統支援pl2303的usb轉串列埠線,通過otg線連線了pad,但是pad可以識別到裝置後,一直無法收發資料,開始的時候,再android上無法正常開啟裝置,許可權不夠,後面root後修改許可權,可以正常開啟了 其實可以通過修改ueventd.rc,這個檔案,修改掛載裝置的許可權...
android 串列埠通訊
因為工作需要,從未接觸過串列埠的我被老闆欽定了.查了幾天資料之後,終於搞出了乙份能用的demo 是別人寫好的,對android serialport api 的乙個依賴.接入這個依賴之後,照著提示去做基本就可以搞定了.需要注意的是,如果你接收到的資料不完整,可能是你使用的串列埠被占用了 我自己開發的...
android串列埠通訊
串列埠通訊 serial communications 的概念非常簡單,串列埠按位 bit 傳送和接收位元組。串列埠用於ascii碼字元的傳輸。通訊使用3根線完成,分別是地線 gnd 傳送 tx 接收 rx 由於串列埠通訊是非同步的,埠能夠在一根線上傳送資料同時在另一根線上接收資料。其他線用於握手,...