C# 解码并重新格式化串行数据数组中的值
我的应用程序从串行接口接收数据。一些接收到的记录可以直接显示在文本框中,其他记录必须转换。我必须解码的一条串行消息包含512字节和多个信息 要接收数据,我使用:C# 解码并重新格式化串行数据数组中的值,c#,windows,forms,visual-studio,C#,Windows,Forms,Visual Studio,我的应用程序从串行接口接收数据。一些接收到的记录可以直接显示在文本框中,其他记录必须转换。我必须解码的一条串行消息包含512字节和多个信息 要接收数据,我使用: private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) { var serialPort = (SerialPort)sender; string data = serialPort
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
var serialPort = (SerialPort)sender;
string data = serialPort.ReadExisting();
dataDecoder(data);
}
在数据解码器中,我执行以下操作:
private void dataDecoder(string input)
{
string post = ""; //empty string
char[] buf = input.ToCharArray(); //Converter input String to Char Array
if (buf[0] == '#') //only process records starting with #, others go directly to SetText(string)
{
post += "Decode, Len="; //Informal message
int up = int.Parse(buf[2].ToString()); //Upper byte of 16bit-binary integer
int low = int.Parse(buf[3].ToString()); //lower byte of 16bit-binary integer
int len = low << 8 | up; //converter to decimal int
post += len; //edit string
post += " Channel: "; //informal message
int first = int.Parse(buf[4].ToString()); //Upper byte of 16bit-binary integer
int second = int.Parse(buf[5].ToString()); //lower byte of 16bit-binary integer
int chnl = second << 8 | first; //converter to decimal int
post += chnl; //edit string
post += "DATA"; //informal message
for (int i = 0; i < 507; i++) //decode contents 6 to 511 (512byte is checsum)
{
int k = i + 6; //format selector
int one = int.Parse(buf[k].ToString()); //Highest byte of 32bit-binary integer
int two = int.Parse(buf[k + 1].ToString()); //second high byte of 32bit-binary integer
int three = int.Parse(buf[k + 2].ToString()); //second low byte of 32bit-binary integer
int four = int.Parse(buf[k + 3].ToString()); //lowest byte of 32bit-binary integer
int rec = four << 24 | three << 16 | two << 8 | one; //convert to decimal int
post += rec; //edit string
post += ","; //separation character
}
SetText(post); //set text to texbox
}
else
{
SetText(input); //set input to textbox (unconverted)
}
}
}
我能做些什么更好地解决这个问题
编辑
以下是串行数据的第一部分(取自串行监视器)
2342 FC 01 00 00 00 00
23是#
42是B
FC 01是记录长度,在本例中是已知的,其508(01FC)我不知道您有什么数据格式,但您可以使用正则表达式或自定义映射,如下所示
public static unsafe void dataDecoder(string input)
{
switch (input[0])
{
case '#':
byte[] bytes = Encoding.UTF8.GetBytes(input);
Map(bytes);
break;
}
}
public static unsafe string Map(this byte[] bytes)
{
var offset = 2;
var post = string.Empty;
if (bytes == null)
return post;
//while (bytes.Length < offset)
{
int len =0
int chnl =0;
fixed (byte* numPtr = &bytes[offset])
{
len = *(Int16*)numPtr;
}
offset += 2;
post += len;
post += " Channel: ";
fixed (byte* numPtr = &bytes[offset])
{
chnl = *(Int16*)numPtr;
}
offset += 2;
}
// etc...
return post;
}
公共静态数据解码器(字符串输入)
{
开关(输入[0])
{
案例“#”:
byte[]bytes=Encoding.UTF8.GetBytes(输入);
映射(字节);
打破
}
}
公共静态不安全字符串映射(此字节[]字节)
{
var偏移=2;
var post=string.Empty;
如果(字节==null)
回程站;
//while(bytes.Length
你说的“占一个字符”是什么意思?字符在C#中可以是16位,int是32位,所以我认为它不能更大。您还可以使用字符串[0],我以前也尝试过,但我读过一些帖子,说这不能在C#中实现,因为字符串是不可变的。您可以使用不安全的代码并通过指针读取数据,如示例所示。首先我们跳过第一个字节“#”,第二个得到len Int16它将是您的长度:fixed(byte*numpr=&bytes[2]){len=(Int16)numpr;}我的意思是Int16可以占用2个字节(FF FF),或者如果以ASCII格式存储在5个字节的字符串表示形式“32767”
public static unsafe void dataDecoder(string input)
{
switch (input[0])
{
case '#':
byte[] bytes = Encoding.UTF8.GetBytes(input);
Map(bytes);
break;
}
}
public static unsafe string Map(this byte[] bytes)
{
var offset = 2;
var post = string.Empty;
if (bytes == null)
return post;
//while (bytes.Length < offset)
{
int len =0
int chnl =0;
fixed (byte* numPtr = &bytes[offset])
{
len = *(Int16*)numPtr;
}
offset += 2;
post += len;
post += " Channel: ";
fixed (byte* numPtr = &bytes[offset])
{
chnl = *(Int16*)numPtr;
}
offset += 2;
}
// etc...
return post;
}