我有以下协议规范,用于将消息发送到我正在集成的设备,按顺序分成字节:
我无法获得字节6& 7正确。
如何计算校验和还不是很清楚,它表示字节6和7是(2; 5)的总和 - 2; 5是什么意思?
我目前的代码是:
require 'serialport'
# Open collector serial port
serial = SerialPort.new('/dev/ttyAMA0', baud: 9600, data_bits: 8, stop_bits: 1,
parity: SerialPort::NONE)
checksum = '10E0'.unpack("C*").inject(:+).ord
p serial.write(0x02.chr) # start byte
p serial.write('10E0') # commands
p serial.write(checksum + checksum) # checksum byte 1 + 2
p serial.write(0x03.chr) # End byte
p serial.read
回复没有运气。有谁知道我做错了什么?或更好地理解这个规范?
非常感谢!
答案 0 :(得分:2)
您的“协议规范”令人困惑。对于字节6和7,它提到了“校验和”和“CRC”。这是两种不同类型的计算。它们不是同义词。当存在多个位错误时,校验和容易出现错误验证。 CRC在检测错误方面要好得多。
因此,您需要解决是否需要计算消息字节2到5的CRC-8校验值或校验和(截断为一个字节)的问题。无论如何最终都需要8位值存储在消息字节6和7中。
您的“协议规范”有:
6. Binary s=(byte)SUM(2;5) CRC_H=0b1000_s7_s6_s5_s4 Checksum hight byte
7. Binary s=(byte)SUM(2;5) CRC_L=0b1000_s3_s2_s1_s0 Checksum low byte
显然校验和字节的高半字节(即位“s7_s6_s5_s4”)存储在消息的字节6中,并设置了高位(位8)(如所示) “0b1000 _”位字符串)。校验和字节的低半字节(即位“s3_s2_s1_s0”)存储在消息的字节7中,并设置高位(位8)。
当校验和产生值0x02或0x03时,大概设置第8位(在每个字节中)将防止错误检测到消息的开始或结束字节。这应该通过使消息框架易于识别并且难以识别错误来改善消息完整性。
我不做ruby,所以只能提供C代码。
unsigned char chksum = mesg[2] + mesg[3] + mesg[4] + mesg[5];
mesg[6] = 0x80 | ((chksum >> 4) & 0x0f);
mesg[7] = 0x80 | (chksum & 0x0f);