C#winfrom串口接收数据的问题

Mr.胤少 2019-05-25 12:10:53
哪位大佬麻烦看下,下面代码有什么问题,下拉框选择另一个串口的时候再给serialport.PortName赋值时会提示串口已打开,下拉框选择另一个串口后要如何关闭上一个串口,使选择的串口常开状态。只有50分了,哪位大佬帮帮忙!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO.Ports;

namespace HardWare
{
public partial class HardWare : Form
{
SerialPort serialport = new SerialPort();
//建立个委托
private delegate string returnStrDelegate();
private delegate void Displaydelegate(byte[] InputBuf);
Byte[] OutputBuf = new Byte[128];
//private Displaydelegate disp_delegate;
string targetCOMPort;

public HardWare()
{
InitializeComponent();
}

private void HardWare_Load(object sender, EventArgs e)
{
cmbPort.Items.AddRange(SerialPort.GetPortNames());
cmbPort.SelectedIndex = 0;
}

//接收数据监控
public void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

//Byte[] InputBuf = new Byte[128];

try
{
setcom();
string str = "";

int len = serialport.BytesToRead;
Byte[] readBuffer = new Byte[len];
serialport.Read(readBuffer, 0, len);
str = null;
str = Encoding.Default.GetString(readBuffer);

//触发外部处理接收消息事件
//如果需要和界面上的控件交互显示数据,使用下面的方法。
this.txtRec.Invoke(new Action(() =>
{
txtRec.Text = str;
}));
//清空接收缓冲区
serialport.DiscardInBuffer();
}
catch (TimeoutException ex) //超时处理
{
MessageBox.Show(ex.ToString());
}
}

//打开端口
public void setcom()
{
try
{
//serialport.Close(); //如果在这里先写关闭的话,那新的串口就不是常开状态,会取不到接收的数据
//serialport = new SerialPort(targetCOMPort, 9600, Parity.None, 8, StopBits.Two);
targetCOMPort = returnCB(returnstr);
serialport.PortName = targetCOMPort; //通信端口
serialport.BaudRate = 9600; //串行波特率
serialport.DataBits = 8; //每个字节的标准数据位长度
serialport.StopBits = StopBits.Two; //设置每个字节的标准停止位数
serialport.Parity = Parity.None; //设置奇偶校验检查协议
serialport.Encoding = System.Text.Encoding.GetEncoding("GB2312");
if (!serialport.IsOpen)
{
serialport.Open();
}
//disp_delegate = new Displaydelegate(DispUI);
//串口控件成员变量,字面意思为接收字节阀值,
//串口对象在收到这样长度的数据之后会触发事件处理函数
//一般都设为1
serialport.ReceivedBytesThreshold = 1;
serialport.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
}
catch (Exception i)
{
MessageBox.Show(i.ToString());
}
}

private string returnstr()
{
return cmbPort.SelectedItem.ToString();
}

//判断一下是不是该用Invoke,不是就直接返回~
private string returnCB(returnStrDelegate myDelegate)
{
if (this.InvokeRequired)
{
return (string)this.Invoke(myDelegate);
}
else
{
return myDelegate();
}
}

private void HardWare_FormClosed(object sender, FormClosedEventArgs e)
{
if (serialport.IsOpen)
{
serialport.Close();
}
System.Environment.Exit(0);
}

private void cmbPort_SelectedIndexChanged(object sender, EventArgs e)
{
//serialport.Close();
setcom();
}
}
}
...全文
148 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jx315425246 2019-05-25
  • 打赏
  • 举报
回复

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO.Ports;

namespace HardWare
{
public partial class HardWare : Form
{
SerialPort serialport = new SerialPort();
//建立个委托
private delegate string returnStrDelegate();
private delegate void Displaydelegate(byte[] InputBuf);
Byte[] OutputBuf = new Byte[128];
//private Displaydelegate disp_delegate;
string targetCOMPort;

public HardWare()
{
InitializeComponent();
}

private void HardWare_Load(object sender, EventArgs e)
{
cmbPort.Items.AddRange(SerialPort.GetPortNames());
cmbPort.SelectedIndex = 0;
}

//接收数据监控
public void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

//Byte[] InputBuf = new Byte[128];

try
{
setcom();
string str = "";

int len = serialport.BytesToRead;
Byte[] readBuffer = new Byte[len];
serialport.Read(readBuffer, 0, len);
str = null;
str = Encoding.Default.GetString(readBuffer);

//触发外部处理接收消息事件
//如果需要和界面上的控件交互显示数据,使用下面的方法。
this.txtRec.Invoke(new Action(() =>
{
txtRec.Text = str;
}));
//清空接收缓冲区
serialport.DiscardInBuffer();
}
catch (TimeoutException ex) //超时处理
{
MessageBox.Show(ex.ToString());
}
}

//打开端口
public void setcom()
{
try
{
if(serialport!=null) //这样判断
{
if(serialport.IsOpen)
erialport.Close();
}
//serialport.Close(); //如果在这里先写关闭的话,那新的串口就不是常开状态,会取不到接收的数据
//serialport = new SerialPort(targetCOMPort, 9600, Parity.None, 8, StopBits.Two);
targetCOMPort = returnCB(returnstr);
serialport.PortName = targetCOMPort; //通信端口
serialport.BaudRate = 9600; //串行波特率
serialport.DataBits = 8; //每个字节的标准数据位长度
serialport.StopBits = StopBits.Two; //设置每个字节的标准停止位数
serialport.Parity = Parity.None; //设置奇偶校验检查协议
serialport.Encoding = System.Text.Encoding.GetEncoding("GB2312");
if (!serialport.IsOpen)
{
serialport.Open();
}
//disp_delegate = new Displaydelegate(DispUI);
//串口控件成员变量,字面意思为接收字节阀值,
//串口对象在收到这样长度的数据之后会触发事件处理函数
//一般都设为1
serialport.ReceivedBytesThreshold = 1;
serialport.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
}
catch (Exception i)
{
MessageBox.Show(i.ToString());
}
}

private string returnstr()
{
return cmbPort.SelectedItem.ToString();
}

//判断一下是不是该用Invoke,不是就直接返回~
private string returnCB(returnStrDelegate myDelegate)
{
if (this.InvokeRequired)
{
return (string)this.Invoke(myDelegate);
}
else
{
return myDelegate();
}
}

private void HardWare_FormClosed(object sender, FormClosedEventArgs e)
{
if (serialport.IsOpen)
{
serialport.Close();
}
System.Environment.Exit(0);
}

private void cmbPort_SelectedIndexChanged(object sender, EventArgs e)
{
//serialport.Close();
setcom();
}
}
}
大鱼> 2019-05-25
  • 打赏
  • 举报
回复
大致看了一下,你注释掉的地方就是关键
jx315425246 2019-05-25
  • 打赏
  • 举报
回复
要是不成,写成这样

if(serialport!=null) //这样判断
{
if(serialport.IsOpen)
{
serialport.Close();
}
}
serialport=new SerialPort();
Mr.胤少 2019-05-25
  • 打赏
  • 举报
回复
引用 2 楼 jx315425246 的回复:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO.Ports;

namespace HardWare
{
public partial class HardWare : Form
{
SerialPort serialport = new SerialPort();
//建立个委托
private delegate string returnStrDelegate();
private delegate void Displaydelegate(byte[] InputBuf);
Byte[] OutputBuf = new Byte[128];
//private Displaydelegate disp_delegate;
string targetCOMPort;

public HardWare()
{
InitializeComponent();
}

private void HardWare_Load(object sender, EventArgs e)
{
cmbPort.Items.AddRange(SerialPort.GetPortNames());
cmbPort.SelectedIndex = 0;
}

//接收数据监控
public void Comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

//Byte[] InputBuf = new Byte[128];

try
{
setcom();
string str = "";

int len = serialport.BytesToRead;
Byte[] readBuffer = new Byte[len];
serialport.Read(readBuffer, 0, len);
str = null;
str = Encoding.Default.GetString(readBuffer);

//触发外部处理接收消息事件
//如果需要和界面上的控件交互显示数据,使用下面的方法。
this.txtRec.Invoke(new Action(() =>
{
txtRec.Text = str;
}));
//清空接收缓冲区
serialport.DiscardInBuffer();
}
catch (TimeoutException ex) //超时处理
{
MessageBox.Show(ex.ToString());
}
}

//打开端口
public void setcom()
{
try
{
if(serialport!=null) //这样判断
{
if(serialport.IsOpen)
erialport.Close();
}
//serialport.Close(); //如果在这里先写关闭的话,那新的串口就不是常开状态,会取不到接收的数据
//serialport = new SerialPort(targetCOMPort, 9600, Parity.None, 8, StopBits.Two);
targetCOMPort = returnCB(returnstr);
serialport.PortName = targetCOMPort; //通信端口
serialport.BaudRate = 9600; //串行波特率
serialport.DataBits = 8; //每个字节的标准数据位长度
serialport.StopBits = StopBits.Two; //设置每个字节的标准停止位数
serialport.Parity = Parity.None; //设置奇偶校验检查协议
serialport.Encoding = System.Text.Encoding.GetEncoding("GB2312");
if (!serialport.IsOpen)
{
serialport.Open();
}
//disp_delegate = new Displaydelegate(DispUI);
//串口控件成员变量,字面意思为接收字节阀值,
//串口对象在收到这样长度的数据之后会触发事件处理函数
//一般都设为1
serialport.ReceivedBytesThreshold = 1;
serialport.DataReceived += new SerialDataReceivedEventHandler(Comm_DataReceived);
}
catch (Exception i)
{
MessageBox.Show(i.ToString());
}
}

private string returnstr()
{
return cmbPort.SelectedItem.ToString();
}

//判断一下是不是该用Invoke,不是就直接返回~
private string returnCB(returnStrDelegate myDelegate)
{
if (this.InvokeRequired)
{
return (string)this.Invoke(myDelegate);
}
else
{
return myDelegate();
}
}

private void HardWare_FormClosed(object sender, FormClosedEventArgs e)
{
if (serialport.IsOpen)
{
serialport.Close();
}
System.Environment.Exit(0);
}

private void cmbPort_SelectedIndexChanged(object sender, EventArgs e)
{
//serialport.Close();
setcom();
}
}
}


我现在思路有点混乱了,试下加那个判断看下,主要是想把窗体加载时打开的串口关掉,然后再selectindex选择另一个串口时使串口常开,我自己写的那个新串口不是常开状态,接收不到数据。

110,566

社区成员

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

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

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