(100分)高手何在?用SerialPorts 关闭串口,再次打开时出错?怎样才能不出错?
用COMMN控件可以随时关闭,再打开可是,用SerialPorts 关闭后再次初始化并打开串口时出现错误提示“串口被关闭”? --------------------编程问答-------------------- up --------------------编程问答-------------------- up --------------------编程问答-------------------- to vs2003http://www.codeproject.com/dotnet/DotNetComPorts.asp
to vs2005
http://www.codeproject.com/csharp/serialcommunication.asp --------------------编程问答-------------------- 作者:veryhappy(wx.net)
在.NET 1.1版本中微软并没有封装一个串口操作的类,但是我们可以在网络上找到通过WIN32 API读写文件方式访问串口的开源类库,比如:JustinIO。但是最近笔者在写一个易做图池(支持8块SIM,收发短信的硬件设备,RJ45接口)的操作类库时,发现使用JustinIO的类库并不能很好的操作这样的设备(注:该设备是通过TCP/IP方式虚拟COM口来操作的),会出现初始化串口不正常甚至导致开发机蓝屏这样的严重问题。但是如果使用微软的MSCOMM控件却能很好的操作这类的虚拟串口。在.NET 2.0中微软又提供了一个IO.Ports新的命名空间,其中包含了SerialPort类,一个简单快捷的串口操作类。所以笔者想直接用SerialPorts类来替代JustinIO的类来操作串口。
关于SerialPort的成员属性和方法,这里就不在详细写了,主要是微软的帮助写的更全,我写多了大家看着也没有意思。如果本机安装了MSDN 2005可以访问ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref8/html/T_System_IO_Ports_SerialPort_Members.htm来具体查看,如果没有安装可以访问在线的MSDN库http://msdn2.microsoft.com/en-us/library/system.io.ports.serialport(VS.80).aspx。但是在我的类库中使用比较多的方法是Open,Close,Write,ReadExisting,事件DataReceived等。
在以前利用JustinIO来读写串口操作的时候总要在string和byte数组中不断的转换,现在利用SerialPort这样的事情就交给类库去完成吧,我们就关心发送和接收到的ASCII编码的string类型内容。原来在实时读取接收到的短信内容的时候我们需要写一个死循环来自己处理,现在注册SerialPort的DataReceived事件来直接获得接收到的数据更为方便,还很少出错。
下面我就简要说明一下我的类库结构,最主要的SMS类完成了串口的全部操作,至于短信相关的PDU编码解码的方法类也是从网络上下载的开源类,这里就不再说明了,因为和我的主题也不相关。
在这里比较重要的几个方法做一个简要说明
/// <summary>
/// 执行AT命令
/// </summary>
/// <param name="p_ATCommand">命令</param>
/// <returns>结果字符串</returns>
private string ExeATCommand ( string p_ATCommand )
{……}
我们操作短信设备最主要的工作就是向它发送特定的AT指令,然后再获取相应的结果,分析结果内容再作出我们的判断。所以在这里我把发送AT指令并获取指令执行结果的过程写成了ExeATCommand方法,用来执行AT指令。比如我的测试串口是否正常工作的一个方法IsConnect就是先调用ExeATCommand方法,发送“AT”命令到串口,根据串口返回的信息,“OK”或是“ERROR”来确定是它是否正在连接工作。
调用方法,添加对KostechSMS.DLL的引用。
using KostechSMS;
SMS InstanceSMSObject = new SMS([串口], [速率], [短信中心号码], [重试次数], [延迟时间]);
InstanceSMSObject.IsSendMessage([号码], [内容]); // 发送短信
// 实时监听收到的短信
InstanceSMSObject.ReceiveMessageEvent += new SMS.ReceiveMessageHandle( [本地的方法] );
InstanceSMSObject.ListenPortStart(); // 开始监听,当收到短信时将自动通知[本地的方法]
最后说明一下我的开发软件环境:Windows Server 2003 Standard,.NET Framework 2.0,Visual Studio 2005,IIS6。最后生成的DLL在Windows和WEB上面测试收发均成功。
另外,需要全部源码的请留下你的EMAIL,我好发送。作品还有很多欠缺之处,以后能多多改进,有好想法的尽快沟通互相学习。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=651949
--------------------编程问答-------------------- 等高手 --------------------编程问答-------------------- 不懂啊,帮顶 --------------------编程问答-------------------- ...又开一帖阿!楼主急脾气
我一直用MSComm,没有用过SeriaPorts类
先给下位机复位
你就测试一条 下发 看看返回的数据是不是你要的!
--------------------编程问答-------------------- 如果能再次打开,只是报异常,就可以在catch里吃掉异常;若不能再次打开,在前一次可用dispose先释放掉端口实例!可用终端配合调试 --------------------编程问答-------------------- 最近也在研究SeriaPorts,可以随时打开关闭的,没出现你说的问题,要不贴下相关代码看看 --------------------编程问答-------------------- SerialPorts太垃圾,打开串口后如果串口在硬件中丢失,比如用USB转串口,拔掉USB线后,CPU就一质100%,程序没响应,无法退出,垃圾的很。不建议楼主使用
还是老老实实MSComm吧 --------------------编程问答-------------------- 关注,帮顶 --------------------编程问答-------------------- mark 学习 --------------------编程问答-------------------- 正是我想学习的啊,希望没有来晚,请给我发一份,好心人。
ljleager@163.com --------------------编程问答-------------------- 首先,SerialPort这玩意还是非常强大的,串口协议栈不完整的情况下,也可以正常通讯,但效率上比较不理想,一个串口操作而已,竟然启动了28个线程来实现。无法理解。占3M内存。 --------------------编程问答-------------------- 我想学习的啊,希望没有来晚,请给我发一份,好心人。
wxhanshan@163.com --------------------编程问答-------------------- 要学会征服新的困难才有进步
老老实实 MSCOMM 呆着 不是好的态度 --------------------编程问答-------------------- 每次打开端口前先判断此端口的状态,如果是打开状态就先关闭一下。 --------------------编程问答-------------------- 每次打开端口前先判断此端口的状态,如果是打开状态就先关闭一下。 --------------------编程问答-------------------- 每次打开端口前先判断此端口的状态,如果是打开状态就先关闭一下。
但isOpen并不能真正反映串口的状态。比如再打开一个已经打开的串口时(外部工具打开),就不能用代码实现先关后开的操作。 --------------------编程问答-------------------- up
up
up --------------------编程问答-------------------- 说了半天没说到点上,串口传输数据时关闭窗口,再次打开就卡了额,调试结果是串口无法打开 --------------------编程问答-------------------- 我也出现这样的问题 --------------------编程问答-------------------- 串口是独占的,真正关闭串口的时候容易造成死锁,很多代码在释放串口时只是假释放,其实串口并没有关闭,所以在此打开的时候会提示报错,我以前在写一个电子称实时称重的代码时碰到过这种问题,在网上试了很多办法都没效果,要死程序卡死,要么就是假释放,后来用异步代理的方式才解决,但是前提是牺牲了一些性能,异步没有同步反应快! --------------------编程问答-------------------- public void SetPa()
{
try
{
string[] portNames = SerialPort.GetPortNames();//串口数组
if (portNames.Length > 0)
{
bool check = false;
for (int j = 0; j < portNames.Length; j++)
{
try
{
//设置参数
myPort.PortName = portNames[j];//串口号
myPort.BaudRate = BaudRate;//波特率
myPort.DataBits = DataBits; //数据位
myPort.StopBits = stopBits; //停止位
myPort.Parity = parity; //奇偶校验
myPort.RtsEnable = RtsEnable; // 打开RTS ,这步很重要
if (!myPort.IsOpen)
{
myPort.Open();
}
}
catch (Exception ex)
{
if (j == portNames.Length - 1)
{
throw (new Exception(ex.Message.ToString()));
}
else
{
continue;
}
}
//连接命令
//byte[] dataInfoByte = HandCom();
byte[] dataInfoByte = AllCommand(handCom, 0, 0, null, 0, "", handcommands);
//发送数据
sendData(dataInfoByte);
//检测应答数据
if (CheckReceiveData(dataInfoByte, handcommands))
{
check = true;
break;
}
if (check)
{
break;
}
else
{
myPort.Close();
}
}
if (!check)
{
string error = "";
if (language)
{
error = "连接失败!";
}
else
{
error = "連接失敗!";
}
throw (new Exception(error));
}
}
else
{
string error = "";
if (language)
{
error = "请插入设备!";
}
else
{
error = "請插入設備!";
}
throw (new Exception(error));
}
}
catch (Exception ex)
{
throw (new Exception(ex.Message));
}
我用的是SerialPort控件,在升级PC的时候强制关闭程序,断开串口,结果重新打开就卡在Open()里面,等一段时间后就出现什么信号灯之类的,求高手呀 --------------------编程问答--------------------
这是强大的代价。
现在的电脑,3M内存只是小意思,只要功能、性能够强大。SerialPort和微软一路货 --------------------编程问答-------------------- 帮顶 同样求解 --------------------编程问答-------------------- 我曾经遇到过这种问题 可能是你在同一个函数里写入串口打开、发送数据、关闭串口这一系列操作 这样会导致错误 解决方法 将关闭串口操作放在定时器 延时一小段时间再关闭
补充:.NET技术 , C#