C# 串口读取数据不完整

Ac_Lotus_G 2010-09-26 03:33:38
int bytes = serialPort1.BytesToRead;

我在后面定义一个数组:

byte[] buffer = new byte[bytes];

当串口缓存里有16个数据时,bytes却只有3,有时是13,有时8,反正经常只读了一部分数据,导致该数组里的数据总是一经判断就出错。为什么呀?为何bytes和serialPort1.BytesToRead不相等,怎么解决这个问题,希望大家帮帮我!
...全文
1226 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
ysz89757 2010-09-28
  • 打赏
  • 举报
回复
学习之
Ac_Lotus_G 2010-09-28
  • 打赏
  • 举报
回复
一个一个地读,读到包尾就停止,是可行的!
Ac_Lotus_G 2010-09-27
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 w_f_y4422 的回复:]
也要看你的代码是什么时候执行的,如果放在串口接收事件里,根本不用循环,否则会死掉。
[/Quote]


就在 serialPort1_DataReceived_1()里啊
w_f_y4422 2010-09-27
  • 打赏
  • 举报
回复
也要看你的代码是什么时候执行的,如果放在串口接收事件里,根本不用循环,否则会死掉。
yangjinCK 2010-09-27
  • 打赏
  • 举报
回复
System.Threading.Thread.Sleep(500);//发送完信息立即接收一定要加上延时函数
不然肯定会接收不完整了
w_f_y4422 2010-09-27
  • 打赏
  • 举报
回复
试试这样子

List<byte> arr = new List<byte>();
while (true)
{
if (serialPort1.BytesToRead > 0)
{
arr.Add((byte)serialPort1.ReadByte());
if (arr.Count > 2)
{
int len = arr.Count;
if (arr[len - 1] == 255 && arr[len - 2] == 255)
{
break;
}
}
}
}
/*
* 处理arr

*/
arr.Clear();
w_f_y4422 2010-09-27
  • 打赏
  • 举报
回复
首先你要明白Read方法会导致BytesToRead重新计算,所以你的程序必定是有问题,其次if (buffer[bytes - 2] == 255 & buffer[bytes - 1] == 255)
里的&应该改为&&.
假如你的每组数据长度不固定,只是以255 作为结束标志,我觉得要另建一数组,每次读取一字节进去,遇到255时表示读完,取出这数组的值,然后清空,重新再填。
Ac_Lotus_G 2010-09-27
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 w_f_y4422 的回复:]
[/Quote]

我会收到一组一组的数据,完整地读出每一组数据并进行处理就是我的目的!为了避免冲突,下位机发上的每组数据之间会有两三秒的延迟。
Ac_Lotus_G 2010-09-27
  • 打赏
  • 举报
回复
我每组数据的最后两个是255,大家帮我看看程序问题在哪儿?

int bytes = serialPort1.BytesToRead;
byte[] buffer = new byte[bytes];

for (;;)
{

serialPort1.Read(buffer, 0, bytes);
if (buffer[bytes - 2] == 255 & buffer[bytes - 1] == 255)
break;
}

因为出现了只读取了一部分数据的情况,我加了for语句是想反复读数据,判断所读取的数据最后两个是255的时候,就认为已经完整读取了一组数据,跳出循环,往下执行。


感觉程序有问题,希望大家指点一下。
w_f_y4422 2010-09-27
  • 打赏
  • 举报
回复

public partial class Form1 : Form
{
delegate void del();
public Form1()
{
InitializeComponent();
}

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
this.Invoke(new del(A));
}
private void A()
{
if (serialPort1.BytesToRead == 9)
{
byte[] buffer = new byte[serialPort1.BytesToRead];
serialPort1.Read(buffer, 0, serialPort1.BytesToRead);
string str=Encoding.ASCII.GetString(buffer);
richTextBox1.AppendText(str);
}
}

private void Form1_Load(object sender, EventArgs e)
{
serialPort1.Open();
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
}
}
}

不知你具体的需求是什么,反正我能顺利将数据按9个字节读进来为。
CHN_smallfox 2010-09-27
  • 打赏
  • 举报
回复
Application.Doevents();
一切为了你 2010-09-27
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 ac_lotus_g 的回复:]
循环read的话,会读多了,因为我接收的数据的一组一组地过来的,循环地读会读到下一组的数据。
[/Quote]
在没组数据后面加个标志
在读取 判断标志
Ac_Lotus_G 2010-09-27
  • 打赏
  • 举报
回复
把串口读出来的数据放入缓存,再从缓存读需要的数据进行分析?
兔子-顾问 2010-09-27
  • 打赏
  • 举报
回复
基本常识,流设备是需要先缓存再分析的。
Ac_Lotus_G 2010-09-27
  • 打赏
  • 举报
回复
for (;;)
{
serialPort1.Read(buffer, 0, bytes);
if (buffer[bytes - 2] == 255 & buffer[bytes - 1] == 255)
break;
}

这个循环读取 有问题吗
TTRN 2010-09-27
  • 打赏
  • 举报
回复
纯顶 学习下
Ac_Lotus_G 2010-09-27
  • 打赏
  • 举报
回复
我只需要读到一组的包尾就停止
Ac_Lotus_G 2010-09-27
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 ling3wei 的回复:]
serialPort1.ReadBufferSize 串口缓冲大小设了没
[/Quote]


readbuffersize 设了8192
  • 打赏
  • 举报
回复
不知道你的什么问题,我以前读取的PLC的串口数据包。
我觉得你直接判断报文结束字符不就行了
yinrongg 2010-09-27
  • 打赏
  • 举报
回复
serialPort1.ReadBufferSize 串口缓冲大小设了没
加载更多回复(14)

111,129

社区成员

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

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

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