serialport向多串口发送和接收数据的问题

hbliuren0 2008-10-24 04:31:39
实现目标:用serialport类向机器上的所有能打开的串口发送数据;然后根据回复的数据判断哪些串口是我真正需要发送数据的串口。并用serialPort_DataReceived函数接受来自不同串口的数据,并区分开后存到缓存数组中去。以待后续处理。

当前问题:每次获得的真实串口列表都不一样。郁闷死了。


是不是当serialPort_DataReceived函数没有处理完数据,这是又有其他串口发送数据,serialPort_DataReceived函数又被激活,并从头执行啊???该如何解决呀???求求大家了!!!
QQ:350691835
e_mail:hbliu_ren@yahoo.com.cn
...全文
635 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hbliuren0 2008-10-24
  • 打赏
  • 举报
回复
serialPort_DataReceived代码如下:
//串口数据接收函数
public void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//初始化接受串口的类
SerialPort TempSerialPort = (SerialPort)sender;
string str = TempSerialPort.PortName;
Byte TempPortIDByte = Byte.Parse(Convert.ToString(int.Parse(str.Substring(3, str.Length - 3)), 16));
int iByteNum = TempSerialPort.BytesToRead;
Byte[] bytes = new Byte[iByteNum];
TempSerialPort.Read(bytes, 0, iByteNum);
//只接收数据
if (ReceiveByteArray[0, 0].Equals(0x00))
{
ReceiveByteArray[0, 0] = TempPortIDByte;
ReceiveByteArray[0, 1] = Byte.Parse(Convert.ToString(iByteNum, 16));
for (int i = 2; i < iByteNum + 2; i++)
{
ReceiveByteArray[0, i] = bytes[i - 2];
}
}
else
{
bool bIsExist = false;
for (int i = 0; i < iReceiveByteArrayRowNum; i++)
{
if (!TempPortIDByte.Equals(ReceiveByteArray[i, 0]))
{
bIsExist = false;
}
else
{
bIsExist = true;
//判断当前数据的长度是否为有效值
if (ReceiveByteArray[i, 1].Equals(0x00))
{
ReceiveByteArray[i, 1] = Byte.Parse(Convert.ToString(iByteNum, 16));
for (int j = 2; j < iByteNum + 2; j++)
{
ReceiveByteArray[i, j] = bytes[j - 2];
}
}
else
{
ReceiveByteArray[i, 1] = Byte.Parse(Convert.ToString(iByteNum + int.Parse(ReceiveByteArray[i, 1].ToString()), 16));
for (int j = 2 + int.Parse(ReceiveByteArray[i, 1].ToString()); j < 2 + int.Parse(ReceiveByteArray[i, 1].ToString()) + iByteNum; j++)
{
ReceiveByteArray[i, j] = bytes[j - 2 + int.Parse(ReceiveByteArray[i, 1].ToString())];
}
}
break;
}

}
if (!bIsExist)
{
for (int i = 0; i < iReceiveByteArrayRowNum; i++)
{
if (ReceiveByteArray[i, 0].Equals(0x00))
{
ReceiveByteArray[i, 0] = TempPortIDByte;
if (ReceiveByteArray[i, 1].Equals(0x00))
{
ReceiveByteArray[i, 1] = Byte.Parse(Convert.ToString(iByteNum, 16));
for (int j = 2; j < iByteNum + 2; j++)
{
ReceiveByteArray[i, j] = bytes[j - 2];
}
}
else
{
ReceiveByteArray[i, 1] = Byte.Parse(Convert.ToString(iByteNum + int.Parse(ReceiveByteArray[i, 1].ToString()), 16));
for (int j = 2 + int.Parse(ReceiveByteArray[i, 1].ToString()); j < 2 + int.Parse(ReceiveByteArray[i, 1].ToString()) + iByteNum; j++)
{
ReceiveByteArray[i, j] = bytes[j - 2 + int.Parse(ReceiveByteArray[i, 1].ToString())];
}
}
break;
}
}
}
}
}
hbliuren0 2008-10-24
  • 打赏
  • 举报
回复
回dz_huanbao老兄: 谢谢,在网上实在没查到相应的信息,所以才来这里求助的。
dz_huanbao 2008-10-24
  • 打赏
  • 举报
回复
上网查查吧,下面是MSDN中的一段描述:

Serial received events can be caused by any of the items in the SerialData enumeration. Because the operating system determines whether to raise this event or not, not all parity errors may be reported.

PinChanged, DataReceived, and ErrorReceived events may be called out of order, and there may be a slight delay between when the underlying stream reports the error and when the event handler is executed. Only one event handler can execute at a time.

The DataReceived event is not gauranteed to be raised for every byte received. Use the BytesToRead property to determine how much data is left to be read in the buffer.

The DataReceived event is raised on a secondary thread when data is received from the SerialPort object. Because this event is raised on a secondary thread, and not the main thread, attempting to modify some elements in the main thread, such as UI elements, could raise a threading exception. If it is necessary to modify elements in the main Form or Control, post change requests back using Invoke, which will do the work on the proper thread.
hbliuren0 2008-10-24
  • 打赏
  • 举报
回复
:cpio老兄,说的问题我已经解决了,我是动态定义了好几个串口实例,然后将它们的接受函数都指向同一个serialPort_DataReceived函数。
:dz_huanbao老兄,我动态生成了几个对象,只要能打开的全部生成。
“DataReceived事件是在线程池上执行的,所以必须设计为可重入的函数,因为你不能预知同一时间会有几个线程正在执行该函数。”这个是什么意思,我还不太明白。
cpio 2008-10-24
  • 打赏
  • 举报
回复
一个serialport实例只监听一个串口(好像也只能监听到一个吧?)


接收方法倒是可以用一个,但是可以知道是哪一个serialport发过来的
dz_huanbao 2008-10-24
  • 打赏
  • 举报
回复
一个串口类的对象只能打开一个串口,然后发送或者接收数据流,楼主用了几个串口类的对象?
DataReceived事件是在线程池上执行的,所以必须设计为可重入的函数,因为你不能预知同一时间会有几个线程正在执行该函数。

110,535

社区成员

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

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

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