百度上传播比较广的那个示例代码一堆错误,我这里改了一下可以用了,特此记录。
实现效果:一个COM口发送数据,另一个COM口接受数据
注意:如果电脑上没有COM口,可以用Configure Virtual Serial Port Driver找个软件模拟出COM口,当我打开COM1口,没有打开COM2口时会出现下图的效果
完整代码如下,记得把按钮click事件对应一下
using System.IO.Ports;
using System.Text;
namespace TestSerialPort
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
settextevent += set;
}
public SerialPort sp1 = new SerialPort();
public SerialPort sp2 = new SerialPort();
private void openCOM1_Click(object sender, EventArgs e)
{
if (!sp1.IsOpen)
{
try
{
//串口号
sp1.PortName = "COM1";
//波特率
sp1.BaudRate = 115200;
//数据位
sp1.DataBits = 8;
//停止位
sp1.StopBits = StopBits.One;
//奇偶校验位
sp1.Parity = Parity.Even;
//DataReceived事件发送前,内部缓冲区里的字符数
sp1.ReceivedBytesThreshold = 1;
sp1.RtsEnable = true; sp1.DtrEnable = true; sp1.ReadTimeout = 3000;
// Control.CheckForIllegalCrossThreadCalls = false;
//表示将处理 System.IO.Ports.SerialPort 对象的数据接收事件的方法。
sp1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(sp1_DataReceived_1);
//打开串口
sp1.Open();
MessageBox.Show("COM1打开成功!");
}
catch (Exception ex)
{
MessageBox.Show("COM1打开失败!");
}
}
else
{
MessageBox.Show("COM1已打开!");
}
}
private void closeCOM1_Click(object sender, EventArgs e)
{
if (sp1.IsOpen)
{
sp1.Close();
MessageBox.Show("COM1关闭成功!");
}
}
private void openCOM2_Click(object sender, EventArgs e)
{
if (!sp2.IsOpen)
{
try
{
//串口号
sp2.PortName = "COM2";
//波特率
sp2.BaudRate = 115200;
//数据位
sp2.DataBits = 8;
//停止位
sp2.StopBits = StopBits.One;
//奇偶校验位
sp2.Parity = Parity.Even;
sp2.ReceivedBytesThreshold = 1;
sp2.RtsEnable = true; sp2.DtrEnable = true; sp2.ReadTimeout = 3000;
Control.CheckForIllegalCrossThreadCalls = false;
//表示将处理 System.IO.Ports.SerialPort 对象的数据接收事件的方法。
sp2.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(sp2_DataReceived_2);
//打开串口
sp2.Open();
MessageBox.Show("COM2打开成功!");
}
catch (Exception ex)
{
MessageBox.Show("COM2打开失败!");
}
}
else
{
MessageBox.Show("COM2已打开!");
}
}
private void closeCOM2_Click(object sender, EventArgs e)
{
if (sp2.IsOpen)
{
sp2.Close();
MessageBox.Show("COM2关闭成功!");
}
}
private void send_Click(object sender, EventArgs e)
{
if (sp1.IsOpen)
{
if (!string.IsNullOrEmpty(this.richTextBox1.Text))
{
sp1.WriteLine(this.richTextBox1.Text + "\r\n");
}
else
{
MessageBox.Show("发送数据为空");
}
}
else
{
MessageBox.Show("COM1未打开!");
}
}
public delegate void settext(string text);
public event settext settextevent;
public void set(string text)
{
this.richTextBox2.Text = text;
}
StringBuilder builder1 = new StringBuilder();
//在接收到了ReceivedBytesThreshold设置的字符个数或接收到了文件结束字符并将其放入了输入缓冲区时被触发
public void sp1_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine("接收中...");
int n = sp1.BytesToRead; //先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
byte[] buf = new byte[n]; //声明一个临时数组存储当前来的串口数据
sp1.Read(buf, 0, n); //读取缓冲数据
builder1.Remove(0, builder1.Length); //清除字符串构造器的内容
builder1.Append(Encoding.ASCII.GetString(buf));
string comdata = builder1.ToString();
Console.WriteLine("data: + " + comdata);
this.Invoke(settextevent, comdata);
}
public void sp2_DataReceived_2(object sender, SerialDataReceivedEventArgs e)
{
Console.WriteLine("接收中...");
int n = sp2.BytesToRead; //先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
byte[] buf = new byte[n]; //声明一个临时数组存储当前来的串口数据
sp2.Read(buf, 0, n); //读取缓冲数据
builder1.Remove(0, builder1.Length); //清除字符串构造器的内容
builder1.Append(Encoding.ASCII.GetString(buf));
string comdata = builder1.ToString();
Console.WriteLine("data: + " + comdata);
this.Invoke(settextevent, comdata);
}
}
}