c# - Modbus通讯

标签 c# crc modbus

我正在使用 C# 通过 modbus rs485 rs232 与记录电源电压的 2 相电表进行通信。

我必须通过总线发送数据,以便接收读数。
我连接了一根普通电线并将发送和接收短路。

收到数据并触发此事件:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    byte[] buff = new byte[sp.BytesToRead];

    //Read the Serial Buffer
    sp.Read(buff, 0, buff.Length);
    string data= sp.ReadExisting();

    foreach (byte b in buff)
    {
        AddBuffer(b); //Add byte to buffer
    }
}

然后这个缓冲区被发送到另一个函数,就是这个函数:

private void AddBuffer(byte b)
{
    buffer.Add(b);

    byte[] msg =  buffer.ToArray();

    //Make sure that the message integrity is correct
    if (this.CheckDataIntegrity(msg))
    {
        if (DataReceived != null)
        {
            ModbusEventArgs args = new ModbusEventArgs();
            GetValue(msg, args);
            DataReceived(this, args);
        }
        buffer.RemoveRange(0, buffer.Count);

    }
}

我认为问题出在数据完整性检查上:

public bool CheckDataIntegrity(byte[] data)
{
    if (data.Length < 6)
        return false;
    //Perform a basic CRC check:
    byte[] CRC = new byte[2];
    GetCRC(data, ref CRC);
    if (CRC[0] == data[data.Length - 2] && CRC[1] == data[data.Length - 1])
        return true;
    else
        return false;
}

有一个 CRC 检查,但奇怪的是它永远不会变为真。 CRC计算:

private void GetCRC(byte[] message, ref byte[] CRC)
{

    ushort CRCFull = 0xFFFF;
    byte CRCHigh = 0xFF, CRCLow = 0xFF;
    char CRCLSB;

    for (int i = 0; i < (message.Length) - 2; i++)
    {
        CRCFull = (ushort)(CRCFull ^ message[i]);

        for (int j = 0; j < 8; j++)
        {
            CRCLSB = (char)(CRCFull & 0x0001);
            CRCFull = (ushort)((CRCFull >> 1) & 0x7FFF);

            if (CRCLSB == 1)
                CRCFull = (ushort)(CRCFull ^ 0xA001);
        }
    }
    CRC[1] = CRCHigh = (byte)((CRCFull >> 8) & 0xFF);
    CRC[0] = CRCLow = (byte)(CRCFull & 0xFF);
}

最佳答案

问题在于 ReadExisting() 的使用。它不能以这种方式使用,因为缓冲区中充满了来自串口的无用数据。 @glace 在评论中发现了这个问题!

关于c# - Modbus通讯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18487800/

相关文章:

python - 如何在 modbus 寄存器中存储带符号的 16 位值

javascript - 使用 Vanilla JS 的 CRC-16 校验和计算器

c# - 嵌入式 C 中的 Modbus RTU 实现

c# - 按属性分类的正确方法

c++ - 无法弄清楚如何计算CRC7

德尔福 5 到 2010

c# - 来自 vb.net 中字符串的 CRC-16/ARC

c# - 对索引器属性使用 Moq 会导致 CaSTLe 出现 InvalidCastException

c# - 尝试删除 Azure Functions 中的 blob,但缺少 DeleteIfExists 方法

c# - 等效于 mstest 中的 assert.warning?