CRC-16/Modbus在C#故障中的实现



我目前正在设置步进电机控制器和计算机之间的通信,用C#编写应用程序(这是我第一次使用这种编程语言,虽然我不是计算机科学家,而是一名工业工程师,但我确信有一些方法可以优化函数,但我不知道,因此,如果有关于这方面的建议,我也将不胜感激(。因此,我一直在使用控制器必须与之通信的RS-485,并实现了一种生成所需CRC(循环冗余检查(字节的算法。

这就是我的问题开始的地方。我找不到我的函数没有生成正确CRC值的原因。我已经用一些CRC的在线计算器进行了检查,我还使用了Modbus指南中出现的示例(其中还解释了代码是如何实现的(。

以下是我为CRC演算编写的代码:

class Program
{
static void Main(string[] args)
{
// 0x05, 0x06, 0x17, 0x70, 0x00, 0x01 
byte[] prueba = new byte[] { 0x02, 0x07 };
byte[] result = Aux.CRC(prueba);
Console.WriteLine(result[0] + " " + result[1]);
}
}
class Aux{
public static byte[] CRC(byte[] to_evaluate)
{
byte[] CRC_Byte = new byte[2] { 0, 0 };
UInt16 CRC_Register = 0xFFFF;            //16 bits 1111.1111.1111.1111
UInt16 CRC_pol = 0xa001;                 //16 bits 1010.0000.0000.0001
foreach (UInt16 byte_val in to_evaluate)
{
CRC_Register ^= byte_val;
Console.WriteLine("XOR inicial : {0:X}", CRC_Register);
for (byte i = 0; i < 8; i++)
{
CRC_Register >>= 1;
Console.WriteLine("Desplazamiento " + (i + 1) + ": {0:X}", CRC_Register);
if ((CRC_Register & 1) != 0)
{
CRC_Register ^= CRC_pol;
Console.WriteLine("XOR: {0:X}", CRC_Register);
}
}
}
Console.WriteLine("{0:X}",CRC_Register);
byte low_byte_CRC = (byte)((CRC_Register << 8) >> 8);
byte high_byte_CRC = (byte)(CRC_Register >> 8);
CRC_Byte[0] = low_byte_CRC;
CRC_Byte[1] = high_byte_CRC;
return CRC_Byte;
}
}

使用附加的测试数组和多项式0xa001的预期结果对于CRC_Register为0x1241,对于CRC_Byte为{0x41,0x12}。

我不得不在C#中实现一次PPP的CRC检查,这绝对没有乐趣!

我在这个链接中发现了应该正确生成CRC的代码。它遵循您共享链接的文件第39页第6.2.2节中的CRC生成程序。

// Compute the MODBUS RTU CRC
UInt16 ModRTU_CRC(byte[] buf, int len)
{
UInt16 crc = 0xFFFF;

for (int pos = 0; pos < len; pos++) 
{
crc ^= (UInt16)buf[pos];          // XOR byte into least sig. byte of crc

for (int i = 8; i != 0; i--)      // Loop over each bit
{    
if ((crc & 0x0001) != 0)        // If the LSB is set
{      
crc >>= 1;                    // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else                            // Else LSB is not set
{                            
crc >>= 1;                    // Just shift right
}
}
}
// Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
return crc;  
}

最新更新