关于c# serialport接受数据怪现象

荒凉1 2013-11-27 10:45:49

private void Form1_Load(object sender, EventArgs e)
{
this.serialPort1.PortName = "com8";
this.serialPort1.BaudRate = 9600;
this.serialPort1.DataBits = 8;
this.serialPort1.StopBits = StopBits.One;
this.serialPort1.Parity = Parity.Even;
this.serialPort1.Open();
this.timer1.Enabled = true;
this.timer1.Interval = 500;
}

private void button1_Click(object sender, EventArgs e)
{
this.serialPort1.Close();
this.Close();
}

private void ReceiveText(object sender, EventArgs e)
{
double datareceive_2;
short datareceive_4 = 8;
short datareceive_5 = 4;
string datareceive_6;
string datareceive_7;
string datareceive_8;
int datareceive_9;
char[] datareceive_0 = datareceive.ToCharArray();//字符串转换成字符串数组
//byte[] datareceive_0 = Convert.FromBase64String(datareceive);
int i = datareceive_0.Length;//判断长度
if (i == 7)
{
datareceive_4 = (short)datareceive_0[3];//获取所需
datareceive_5 = (short)datareceive_0[4];

datareceive_6 = Convert.ToString(datareceive_4, 16);//十进制转化十六进制
datareceive_7 = Convert.ToString(datareceive_5, 16);
if (datareceive_6.Length < 2)
{
datareceive_6 = "0" + datareceive_6;//长度不足两位补 0
}
if (datareceive_7.Length < 2)
{
datareceive_7 = "0" + datareceive_7;
}
datareceive_8 = "";
datareceive_8 = datareceive_6 + datareceive_7;//拼接十六进制数
datareceive_9 = int.Parse(datareceive_8, System.Globalization.NumberStyles.HexNumber);//十六进制转化为十进制
datareceive_2 = datareceive_9 / 100.0;
this.label1.Text = datareceive_2.ToString();
}
}
private void timer1_Tick(object sender, EventArgs e)//发送数据
{
byte[] senddata = { 0x01, 0x03, 0x21, 0x03, 0x00, 0x01, 0x7e, 0x36 };
serialPort1.Write(senddata, 0, senddata.Length);
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(10);
datareceive = null;
datareceive = serialPort1.ReadExisting();
this.Invoke(new EventHandler(ReceiveText));

}

}
奇怪的情况是这样的:
这里用的Modbus来得到数据的,情况如下所示:得到的数据:01 03 02 13 88 B5 12得到的是:01 03 02 13 3f 3f 12有的时候数据正常有时候就像这样不正确,不知道怎么回事,想了很多不知道问题所在,希望得到解答! 我刚刚试了一下,原来是我的char[]里面存0-7的数的时候都是正常的,也就是8进制的,但是我接收到的都是16进制的,一旦超过8以上的就编程3f了,但是我看char的值是这养:
// 摘要:
// 表示 System.Char 的最大可能值。此字段为常数。
public const char MaxValue = (char)0xffff;
//
// 摘要:
// 表示 System.Char 的最小可能值。此字段为常数。
public const char MinValue = '\0';
怎么会出现这样的情况呢,求解释!
还有个问题:c#中CHAR的取值是-128--127,怎么编程0-255的,我试了好像写不了!
...全文
250 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
肚皮向上的鱼 2014-03-13
  • 打赏
  • 举报
回复
引用 7 楼 leafmao 的回复:
[quote=引用 6 楼 h804759109 的回复:] [quote=引用 5 楼 leafmao 的回复:] [quote=引用 4 楼 h804759109 的回复:] [quote=引用 3 楼 leafmao 的回复:] MODBUS也有两种传输方式,ASCII或者是RTU,不知道楼主是用的哪一种传输方式
你好 是rtu[/quote] 如果MODBUS采用RTU方式传输了 01 03 02 13 88 B5 12,那就好解释了, 实际上datareceive = serialPort1.ReadExisting();读到的是这些值对应的ASCII码字符,而88和B5由于超出了7F,实际上对应的是'?',即0x3F。对应的是ASCII字符,后来又通过char字符数组转换成short之类的。。。 楼主这样做好费周章。。。将16进制通过ASCIIEncoding接收,又再转成16进制,不如直接就按照16进制来接收,也省的用char字符数组进行转换了。 这样做: int len=serialPort1.BytesToRead(); byte[] buffer=new byte[len]; serialPort1.Read(buffer,0,len);//这样就可以原封不动的接收到 01 03 02 13 88 B5 12,将buffer保存起来就可以[/quote] 非常感谢你![/quote] 结贴给分吧- -![/quote] 纳雍readexisting方法读数据,只要遇到数据大于7F的就出错了,有什么方法解决吗?我的意思是一定要用readexisting这个方法的话?
因改变就改变 2013-12-05
  • 打赏
  • 举报
回复
MODBUS也有两种传输方式,ASCII或者是RTU,不知道楼主是用的哪一种传输方式
leafmao 2013-11-27
  • 打赏
  • 举报
回复
MODBUS也有两种传输方式,ASCII或者是RTU,不知道楼主是用的哪一种传输方式
leafmao 2013-11-27
  • 打赏
  • 举报
回复
情况如下所示:得到的数据:01 03 02 13 88 B5 12得到的是:01 03 02 13 3f 3f 12 接收到的数据本来就是字符串吗?还是16进制的数? serialPort1.ReadExisting()是在编码的基础上读取 SerialPort 对象的流和输入缓冲区中所有立即可用的字节。 默认是使用ASCIIEncoding,这种编码方式仅支持0~0x7F之间的值,如果值超出7F,会编成3F,所以0x88he 0xB5变成了0x3F, “01 03 02 13 88 B5 12”是指16进制还是什么?如果是16进制,那使用serialPort1.ReadExixting()读出来的应该是对应的ASCII字符啊
荒凉1 2013-11-27
  • 打赏
  • 举报
回复
自己先顶一下,在线等!
leafmao 2013-11-27
  • 打赏
  • 举报
回复
引用 6 楼 h804759109 的回复:
[quote=引用 5 楼 leafmao 的回复:] [quote=引用 4 楼 h804759109 的回复:] [quote=引用 3 楼 leafmao 的回复:] MODBUS也有两种传输方式,ASCII或者是RTU,不知道楼主是用的哪一种传输方式
你好 是rtu[/quote] 如果MODBUS采用RTU方式传输了 01 03 02 13 88 B5 12,那就好解释了, 实际上datareceive = serialPort1.ReadExisting();读到的是这些值对应的ASCII码字符,而88和B5由于超出了7F,实际上对应的是'?',即0x3F。对应的是ASCII字符,后来又通过char字符数组转换成short之类的。。。 楼主这样做好费周章。。。将16进制通过ASCIIEncoding接收,又再转成16进制,不如直接就按照16进制来接收,也省的用char字符数组进行转换了。 这样做: int len=serialPort1.BytesToRead(); byte[] buffer=new byte[len]; serialPort1.Read(buffer,0,len);//这样就可以原封不动的接收到 01 03 02 13 88 B5 12,将buffer保存起来就可以[/quote] 非常感谢你![/quote] 结贴给分吧- -!
荒凉1 2013-11-27
  • 打赏
  • 举报
回复
引用 5 楼 leafmao 的回复:
[quote=引用 4 楼 h804759109 的回复:] [quote=引用 3 楼 leafmao 的回复:] MODBUS也有两种传输方式,ASCII或者是RTU,不知道楼主是用的哪一种传输方式
你好 是rtu[/quote] 如果MODBUS采用RTU方式传输了 01 03 02 13 88 B5 12,那就好解释了, 实际上datareceive = serialPort1.ReadExisting();读到的是这些值对应的ASCII码字符,而88和B5由于超出了7F,实际上对应的是'?',即0x3F。对应的是ASCII字符,后来又通过char字符数组转换成short之类的。。。 楼主这样做好费周章。。。将16进制通过ASCIIEncoding接收,又再转成16进制,不如直接就按照16进制来接收,也省的用char字符数组进行转换了。 这样做: int len=serialPort1.BytesToRead(); byte[] buffer=new byte[len]; serialPort1.Read(buffer,0,len);//这样就可以原封不动的接收到 01 03 02 13 88 B5 12,将buffer保存起来就可以[/quote] 非常感谢你!
leafmao 2013-11-27
  • 打赏
  • 举报
回复
引用 4 楼 h804759109 的回复:
[quote=引用 3 楼 leafmao 的回复:] MODBUS也有两种传输方式,ASCII或者是RTU,不知道楼主是用的哪一种传输方式
你好 是rtu[/quote] 如果MODBUS采用RTU方式传输了 01 03 02 13 88 B5 12,那就好解释了, 实际上datareceive = serialPort1.ReadExisting();读到的是这些值对应的ASCII码字符,而88和B5由于超出了7F,实际上对应的是'?',即0x3F。对应的是ASCII字符,后来又通过char字符数组转换成short之类的。。。 楼主这样做好费周章。。。将16进制通过ASCIIEncoding接收,又再转成16进制,不如直接就按照16进制来接收,也省的用char字符数组进行转换了。 这样做: int len=serialPort1.BytesToRead(); byte[] buffer=new byte[len]; serialPort1.Read(buffer,0,len);//这样就可以原封不动的接收到 01 03 02 13 88 B5 12,将buffer保存起来就可以
荒凉1 2013-11-27
  • 打赏
  • 举报
回复
引用 3 楼 leafmao 的回复:
MODBUS也有两种传输方式,ASCII或者是RTU,不知道楼主是用的哪一种传输方式
你好 是rtu

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧