串口监听程序,总是造成蓝屏重启

c_t0427 2010-03-19 04:50:07
我写了一个小程序用于监听串口的数据,第一次点监听,然后暂停,都还正常,但是再点监听的时候就会造成蓝屏死机.我是在虚拟机里面用SerialNull 模拟的串口通信,用别的测试软件通信正常.串口消息是用测试软件发的,监听正常,但是就是在暂停和监听切换的时候会造成蓝屏死机。请大家帮帮忙看看问题在哪里。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;


namespace PortTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private SerialPort Sp = new SerialPort();
public delegate void SetTextCallback(string text);
private Thread newThread = null;
string readstr = null;

private void SetText(string text)
{
if (this.textBox_data.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox_data.Text = text;
}

}
private void ThreadProcSafe()
{
this.SetText(readstr);
}
public void Sp_DataReceived(object sender,System.IO.Ports.SerialDataReceivedEventArgs e)
{
byte[] readBuffer = new byte[Sp.ReadBufferSize];
Sp.Read(readBuffer, 0, readBuffer.Length);
readstr =Encoding.UTF8.GetString(readBuffer);


this.newThread = new Thread(new ThreadStart(this.ThreadProcSafe));
this.newThread.Start();
}

private void button1_Click(object sender, EventArgs e)
{
Sp.PortName = "COM4";
Sp.BaudRate = 9600;
Sp.Parity = Parity.None;
Sp.StopBits = StopBits.One;

Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
Sp.ReceivedBytesThreshold = 1;
try
{
Sp.Open();
button_pause.Enabled = true;
button_listen.Enabled = false;
}
catch
{
MessageBox.Show("端口COM4打开失败!");
}
}
private void button2_Click(object sender, EventArgs e)
{
newThread.Abort();
Sp.Close();
button_listen.Enabled = true;
button_pause.Enabled = false;
}


}
}
...全文
890 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
xunzhaotonglei 2011-11-27
  • 打赏
  • 举报
回复
大侠你好,我现在急需编一个串口监听程序,实现串口一直处于监听状态,只要有数据向串口发送,串口就自动接收并显示在文本框里的程序,和你上面写得很像,能否把你的源程序和工程发给我看下,谢谢了。我的邮箱314498072@qq.com.
Tylerco 2010-08-07
  • 打赏
  • 举报
回复
这里可以解决你们的问题
http://blog.csdn.net/Tylerco/archive/2010/08/06/5794275.aspx
51Crack 2010-03-22
  • 打赏
  • 举报
回复
先用2楼的异步方法,然后在目标方法中再读数据!
c_t0427 2010-03-22
  • 打赏
  • 举报
回复
实际接收的大小是小于sp.BytesToRead.
xingyuebuyu 2010-03-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 c_t0427 的回复:]
我发现问题应该出自
Sp.Read(readBuffer, 0, readBuffer.Length);
这一句,如果每次到这里中断,就没问题,把这个中断点去掉,然后点继续,马上就蓝屏。
[/Quote]

byte[] readBuffer = new byte[Sp.BytesToRead];
Sp.Read(readBuffer, 0, readBuffer.Length);

数组的长度设为需要的数量。
ReadBufferSize是接收缓冲区的容量,它可能大于实际接收到的大小
c_t0427 2010-03-22
  • 打赏
  • 举报
回复
我发现问题应该出自
Sp.Read(readBuffer, 0, readBuffer.Length);
这一句,如果每次到这里中断,就没问题,把这个中断点去掉,然后点继续,马上就蓝屏。
c_t0427 2010-03-22
  • 打赏
  • 举报
回复
问题没有解决,我把
this.newThread = new Thread(new ThreadStart(this.ThreadProcSafe));
this.newThread.Start();
这2句给屏蔽了,依然蓝屏。
不接收数据肯定没有问题,我是虚拟了com3和com4,com3发送信号,一旦有信号过来,就蓝屏。
Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
Sp.ReceivedBytesThreshold = 1;
c_t0427 2010-03-22
  • 打赏
  • 举报
回复
感谢各位的帮忙。
结贴了。
liuh6的sleep方法可以解决一点问题,但是会带来新问题。给了一点分。
xingyuebuyu 的代码问题都解决了。特别感谢。
xingyuebuyu 2010-03-22
  • 打赏
  • 举报
回复
判断串口是否处于打开状态,这个是进行安全性检查,防止你的程序在触发DataReceived 事件后,准备接收时,程序的其它地方有突然将串口关闭,这时你去read就会出现异常。

Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
进行事件绑定
Sp.DataReceived -= Sp_DataReceived;
就是移除事件绑定

两者本来就是搭配使用的
c_t0427 2010-03-22
  • 打赏
  • 举报
回复
还有 Sp.DataReceived -= Sp_DataReceived;
这样暂停是有什么好处?不是太明白,请xingyuebuyu再给我详细解释下
c_t0427 2010-03-22
  • 打赏
  • 举报
回复
感谢xingyuebuyu,这下子不死了。是不是问题的根源在于要在
public void Sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
if (Sp.IsOpen == true) //判断串口是否处于打开状态
{
byte[] readBuffer = new byte[Sp.ReadBufferSize];
Sp.Read(readBuffer, 0, readBuffer.Length);
readstr = Encoding.UTF8.GetString(readBuffer);

SetText(readstr);
}
}
判断串口是否处于打开状态
xingyuebuyu 2010-03-22
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;


namespace PortTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private SerialPort Sp = new SerialPort();
public delegate void SetTextCallback(string text);
//private Thread newThread = null;
string readstr = null;

private void SetText(string text)
{
if (this.textBox_data.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.BeginInvoke(d, new object[] { text });
}
else
{
this.textBox_data.Text = text;
}

}

public void Sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
if (Sp.IsOpen == true)
{
byte[] readBuffer = new byte[Sp.ReadBufferSize];
Sp.Read(readBuffer, 0, readBuffer.Length);
readstr = Encoding.UTF8.GetString(readBuffer);

SetText(readstr);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

}

private void button1_Click(object sender, EventArgs e)
{
Sp.PortName = "COM4";
Sp.BaudRate = 9600;
Sp.Parity = Parity.None;
Sp.StopBits = StopBits.One;

Sp.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived);
Sp.ReceivedBytesThreshold = 1;
try
{
Sp.Open();
button_pause.Enabled = true;
button_listen.Enabled = false;
}
catch
{
MessageBox.Show("端口COM4打开失败!");
}
}
private void button2_Click(object sender, EventArgs e)
{
Sp.DataReceived -= Sp_DataReceived;
Sp.Close();
button_listen.Enabled = true;
button_pause.Enabled = false;
}


}
}


简单的修改了,试试
c_t0427 2010-03-22
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 xingyuebuyu 的回复:]
按我之前说的改了后,你直接在电脑的串口上测试,确认没有问题在到虚拟机里面用SerialNull 模拟的串口通信。这个可能是SerialNull 模拟的串口出现问题了
[/Quote]
SerialNull 没有问题,我用别人做的串口测试软件试验的时候,开关串口都很正常,我自己做了个定时发送的程序,每次发送随机数,用别人的串口测试软件接收也正常。问题肯定是我做的这个数据接收程序的问题。
Sp.BytesToRead =4096,我发送的数据就2字节都出问题。
tigerleq 2010-03-22
  • 打赏
  • 举报
回复
先判断,串口是否能用
是否被占用,
是则强关,或者改用其他端口

先要开启端口,发送数据关闭端口
还有就是串口,有个时间,在一定时间内,没有操作端口
系统会自动关闭,所以在每次用得时候
但关闭的端口,你发送数据不会造成蓝屏
cjcgy 2010-03-22
  • 打赏
  • 举报
回复
串口冲突了?

已经被别人用了?
xingyuebuyu 2010-03-22
  • 打赏
  • 举报
回复
按我之前说的改了后,你直接在电脑的串口上测试,确认没有问题在到虚拟机里面用SerialNull 模拟的串口通信。这个可能是SerialNull 模拟的串口出现问题了
liuh6 2010-03-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 c_t0427 的回复:]
我发现问题应该出自
Sp.Read(readBuffer, 0, readBuffer.Length);
这一句,如果每次到这里中断,就没问题,把这个中断点去掉,然后点继续,马上就蓝屏。
[/Quote]

如果有这个情况.加
System.Threading.Thread.Sleep(1000);试一下.
c_t0427 2010-03-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 mjay0210 的回复:]
肯定是死循环 的调用 非托管代码了
[/Quote]请问哪里有死循环。
mjay0210 2010-03-22
  • 打赏
  • 举报
回复
肯定是死循环 的调用 非托管代码了
c_t0427 2010-03-22
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 51crack 的回复:]
先用2楼的异步方法,然后在目标方法中再读数据!
[/Quote]
2楼的异步方法是指写textbox的时候用的吧。那个地方我屏蔽了依然死机。
加载更多回复(2)

110,568

社区成员

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

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

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