本文实例为大家分享了C#实现串口通信的具体代码,供大家参考,具体内容如下
1.基本概念
2.前端winForm布局如下(仅仅为了实现功能,布局略丑)
3.代码实现如下
namespace SerialPortTest
{
public partial class Form1 : Form
{
SerialPort sp1 = new SerialPort();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//分别对应前端的波特率、数字位、校验位、停止位
cbBaudRate.SelectedIndex = 0;
cbDataBits.SelectedIndex = 0;
cbCheck.SelectedIndex = 0;
cbStop.SelectedIndex = 0;
string[] strCom = SerialPort.GetPortNames();
if (strCom == null)
{
MessageBox.Show("本机没有串口!", "Error");
return;
}
//GetPortNames()方法:获取当前计算机的串行端口名的数组
foreach (string com in System.IO.Ports.SerialPort.GetPortNames())
{
cbCom.Items.Add(com);
}
cbCom.SelectedIndex = 0;
sp1.BaudRate = 9600;
Control.CheckForIllegalCrossThreadCalls = false;
sp1.DataReceived += Sp1_DataReceived;
sp1.DtrEnable = true;//获取或设置一个值,该值在串行通信过程中启用数据终端就绪 (DTR) 信号。
sp1.RtsEnable = true;//获取或设置一个值,该值指示在串行通信中是否启用请求发送 (RTS) 信号
//设置数据读取超时为1秒
sp1.ReadTimeout = 1000;
sp1.Close();
}
private void Sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (sp1.IsOpen) //判断是否打开串口
{
//输出当前时间
DateTime dt = DateTime.Now;
txtReceived.Text += dt.GetDateTimeFormats('f')[0].ToString() + "\r\n";
try
{
Byte[] receivedData = new Byte[sp1.BytesToRead]; //创建接收字节数组
sp1.Read(receivedData, 0, receivedData.Length); //读取数据
AddContent(new UTF8Encoding().GetString(receivedData));//用万能的UTF8可以传输中文不会乱码
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "出错提示!!!!!");
txtSendStr.Text = "";
}
}
else
{
MessageBox.Show("请打开某个串口", "错误提示");
}
}
//将接受到的内容显示出来
private void AddContent(string content)
{
this.BeginInvoke(new MethodInvoker(delegate
{
txtReceived.AppendText(content);
txtReceived.AppendText("\r\n");
//记录收到的字符个数
lblRevCount.Text = (int.Parse(lblRevCount.Text) + content.Length).ToString();
}));
}
private void btnOpen_Click(object sender, EventArgs e)
{
//serialPort1.IsOpen
if (!sp1.IsOpen)
{
try
{
//设置串口号
string serialName = cbCom.SelectedItem.ToString();
sp1.PortName = serialName;
//设置各“串口设置”
string strBaudRate = cbBaudRate.Text;
string strDateBits = cbDataBits.Text;
string strStopBits = cbStop.Text;
Int32 iBaudRate = Convert.ToInt32(strBaudRate);
Int32 iDateBits = Convert.ToInt32(strDateBits);
sp1.BaudRate = iBaudRate; //波特率
sp1.DataBits = iDateBits; //数据位
switch (cbStop.Text) //停止位
{
case "1":
sp1.StopBits = StopBits.One;
break;
case "1.5":
sp1.StopBits = StopBits.OnePointFive;
break;
case "2":
sp1.StopBits = StopBits.Two;
break;
default:
MessageBox.Show("Error:参数不正确!", "Error");
break;
}
switch (cbCheck.Text) //校验位
{
case "无":
sp1.Parity = Parity.None;
break;
case "奇校验":
sp1.Parity = Parity.Odd;
break;
case "偶校验":
sp1.Parity = Parity.Even;
break;
default:
MessageBox.Show("Error:参数不正确!", "Error");
break;
}
if (sp1.IsOpen == true)//如果打开状态,则先关闭一下
{
sp1.Close();
}
//设置必要控件不可用
cbCom.Enabled = false;
cbBaudRate.Enabled = false;
cbDataBits.Enabled = false;
cbStop.Enabled = false;
cbCheck.Enabled = false;
sp1.Open(); //打开串口
btnOpen.Text = "关闭串口";
}
catch (System.Exception ex)
{
MessageBox.Show("Error:" + ex.Message, "Error");
return;
}
}
else
{
//恢复控件功能
//设置必要控件不可用
cbCom.Enabled = true;
cbBaudRate.Enabled = true;
cbDataBits.Enabled = true;
cbStop.Enabled = true;
cbCheck.Enabled = true;
sp1.Close(); //关闭串口
btnOpen.Text = "打开串口";
}
}
private void btnSend_Click(object sender, EventArgs e)
{
byte[] sendData = null;
if (!sp1.IsOpen) //如果没打开
{
MessageBox.Show("请先打开串口!", "Error");
return;
}
String strSend = txtSendStr.Text;
try
{
sendData = Encoding.UTF8.GetBytes(txtSendStr.Text.Trim());
//sp1.WriteLine(txtSendStr.Text); //写入数据
sp1.Write(sendData, 0, sendData.Length);
}
catch (Exception ex)
{
MessageBox.Show("Error:" + ex.Message, "Error");
}
}
}
}
4.测试运行结果如下
在自己同一台电脑上测试,需要先用Configure Virtual Serial Port Driver建立两个虚拟串口,如下
串口运行结果如下:
上述两窗体通信时要选择同一波特率,不然收发数据会失败
关于C# serialport的一些说明:
SerialPort() :如果未指定,则此构造函数使用默认属性值。 例如, DataBits 属性默认值为 8, Parity 属性默认为 None 枚举值,
StopBits 属性默认值为 1,默认端口名为 COM1。
public static string[] GetPortNames() :获取当前计算机的串行端口名的数组
SerialPort.Read 方法 (Byte[], Int32, Int32) :从 SerialPort 输入缓冲区读取一些字节并将那些字节写入字节数组中指定的偏移量处
SerialPort.ReadLine 方法 () :一直读取到输入缓冲区中的 NewLine 值
SerialPort.Write 方法 (Byte[], Int32, Int32) : 使用缓冲区中的数据将指定数量的字节写入串行端口
SerialPort.WriteLine 方法 (String) : 将指定的字符串和 NewLine 值写入输出缓冲区。