ご質問はありますか? あなたの質問は、「メッセージの最後にMODBUSのCRCを計算すると、モデムのデバイスが有効なMODBUSメッセージとして認識されます。
もう1つのチェックサムまたはCRC機能を実装する前に、まず最初にテストベクタを取得しようとします。
の有効なメッセージの例がありますか?末尾にのCRCが含まれていますか?
ウィキペディアによれば、上位ビットは常に1であり、nビットのためCRCが(N + 1)によって定義されなければならないので、」cyclic redundancy check、 nビットレジスタをオーバーフロービット除数、いくつかの作家は、除数の上位ビットについて言及する必要はないと仮定しています。
MODBUSが "X^15 + X^2 + 1"多項式(16ビットのCRCであるため、x^16を理解している)を使用していると言う作者は、他の作家とまったく同じ多項式を参照していますつまり、MODBUSは "X^16 + X^15 + X^2 + 1"多項式を使います。 両方の著者は、まったく同じCRCを生成し、相互に相互運用可能なコードを記述します。
また、 "フォワード"方向の標準MODBUS CRCを計算する人は、しばしばマジック定数 "0x8005"を使用します。 標準的なMODBUS CRCを逆方向に計算する人は、代わりにマジック定数 "0xA001"を使用します( "0x8005"のビット反転)。 どちらの人も、まったく同じCRCバイトを生成し、相互に相互運用可能なコードを記述します。
オンラインでMODBUS CRC計算の多くの実装があります。おそらくそのうちの1つが役に立つかもしれません。オンライン
順不同で、オンラインの多くのオプション http://www.zorc.breitbandkatze.de/crc.html
CRC計算 http://www.lammertbies.nl/comm/info/crc-calculation.html
、多くの他の人とCRCの計算を生きる:
abcdefghijklm nopq
多くの実装では、バイト指向している少し速く実行されますが、大きなルックアップテーブル を必要とし(そしてどのようにテストそれは、ルックアップテーブルがあるかどうか私にはこれまで明らかからです有効)。
多くの実装では、はるかに短いプログラムサイズ を生成し、次のようなバグが潜んでいる(ただし、チェックサムを計算するように長さ約8倍を取る)ことができ、より少ないほこりの多いコーナーを、持っている、ビット指向です:
// warning: untested code
// optimized for size rather than speed
// (i.e., uses a bit-oriented calculation rather than table-driven calculation)
uint16_t modbusCRC(uint8_t* data, int length) {
uint16_t crc = 0xFFFF;
for(int pos = 0; pos<length; pos++){
crc ^= (uint16_t)data[pos];
for(int i=0; i<8; i++){
if(crc & 1){ // LSB is set
crc >>= 1; // Shift right
crc ^= 0xA001; // XOR 0xA001
}else{ // LSB is not set
crc >>= 1;
};
};
};
return crc;
}
int main(void){
uint8_t message[80] = { // 6-byte test vector
0x11, 0x03, 0x00, 0x6B, 0x00, 0x03
};
int message_length = 6;
uint16_t the_CRC = modbusCRC(message, message_length); // find CRC of the message
message[message_length++] = the_CRC & 0xFF; // send low byte first
message[message_length++] = the_CRC >> 8; // then send high byte
assert(0x76 == message[6]); // test against known-good CRC
assert(0x87 == message[7]);
send_message(message, message_length); // send all 8 bytes of the message,
// including the two MODBUS CRC bytes.
// (Must send *all* 8 bytes of the message,
// even though there are multiple 0x00 bytes).
}
"バイナリMODBUS"( "Modbus RTUフレームフォーマット")は、メッセージのすべてのデータを2 CRCバイトを含む未加工の8ビットバイトとして送信します。
"ASCII MODBUS"( "Modbus ASCIIフレームフォーマット")は、8ビットのチェックサムを含む多かれ少なかれ単純なASCIIテキストとしてメッセージを送信します。 (チェックサムは2バイトのASCII 16進数の2文字として送信されます)。
だから質問は何ですか? – Amy
私の質問は、X15 + X2 + 1の式を使ってCRCを見つける正確な方法です。このバイトを私のポートにどのように書き込むべきですか?私はC#(VS2010)を使用して、port.writeまたはport.writelineを使用する必要がありますか?これらのバイトをどのようにポートに渡すべきですか? ASCII文字列または16進数として?ありがとう –
バイナリ文字列(バイト配列から形成することができます)、ASCII文字列も16進数も渡さないでください。 Port.Writeを使用できます。おそらく[Port.ByteArrayToString](http://franson.com/serialtools/reference_manual.asp?class=Port&item=ByteArrayToString&platform=net)を使用する必要があります。 –