我正在使用C#通過modbus rs485 rs232
與2個相位表進行通信,其中包括其他日誌中的電源電壓。Modbus通信
我必須通過總線發送數據,以便我可以收到讀數。
我已經連接了一條正常的電線並且短接了發送和接收。
的數據被收到,該事件被觸發:
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);
}
是否有在線資源有一個典型的通信會話的記錄,與CRC完成?然後,您至少可以將您的算法應用於這些示例消息並查看是否提供了相同的CRC。 –
什麼是「緩衝區」變量?它是一個列表?你確定你的「味精」變量是否大於6?爲什麼不直接使用串口的緩衝區而不是逐字節地將其分解,在List中重構,然後將其轉換回全局字節數組?爲什麼在讀取緩衝區的內容後,您還要立即在串行端口上調用ReadExisting? –
CRC似乎是正確的@AndyzSmith。 你是什麼意思打電話redexisting realy我在哪裏可以稱它?是的緩衝區是一個列表 – Combinu