让代码更简单

C#简单实现串口通信

重要:本文最后更新于2020-07-11 08:33:05,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗

串口通信在工业领域用得比较多,说实在的这种技术是非常落后的。因为它不可靠,相信使用过它的人都知道为什么,这里就不多说了。虽然不可靠,但它还是经常被使用,C#的串口通信你会吗?一起来学习下吧。

C#简单实现串口通信

C#简单实现串口通信

这个程序有点花哨,其实主要的代码就一点,逻辑判断什么的自己写吧,核心代码如下。

首先实例化串口对象与注册串口接收事件。这一部分可以通过串口控件使用vs的设置界面设置,无需代码,当然使用代码也是可以的。

复制
 Mydata.mserialprot = new SerialPort();
Mydata.mserialprot.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

串口信息初始化

复制
/// <summary>
/// 串口初始化设置
/// </summary>

public void InitializeSerialSet()
{
InitializePorts(); // 初始化串口号
// 初始化波特率
comboBox_BandRate.Text = comboBox_BandRate.Items[0].ToString();
// 初始化校验位
comboBox_Check.Text = comboBox_Check.Items[0].ToString();
// 初始化数据位
comboBox_Data.Text = comboBox_Data.Items[3].ToString();
// 初始化停止位
comboBox_Stop.Text = comboBox_Stop.Items[0].ToString();

}
/// <summary>
/// 可用串口扫描,并且显示
/// </summary>
public void InitializePorts()
{
comboBox_Serial.Items.Clear(); // 清空原来的信息
// 返回可用串口号,形式:COM3
string[] arraysPostsNames = SerialPort.GetPortNames(); // 获取所有可用的串口号

// 检查串口号是否正确
if (arraysPostsNames.Length > 0)
{

Array.Sort(arraysPostsNames); // 使用默认进行排序,从小到大肾虚
for (int i = 0; i < arraysPostsNames.Length; i++)
{
comboBox_Serial.Items.Add(arraysPostsNames[i]); // 将所有可用串口加载到串口显示框当中
}
comboBox_Serial.Text = arraysPostsNames[0]; // 默认选择第一个串口

comboBox_Serial.Enabled = true; // 打开选择框

}
else
{

comboBox_Serial.Text = "None"; // 提示没有可用串口
comboBox_Serial.Enabled = false; // 禁止打开串口选择框
}

}

打开串口

复制
private void btOpenCom_Click(object sender, EventArgs e)
{
if (Mydata.mserialprot == null)
{
return;
}

if (Mydata.mserialprot.IsOpen == false)
{
Mydata.mserialprot.PortName = comboBox_Serial.Text;
Mydata.mserialprot.BaudRate = Convert.ToInt32(comboBox_BandRate.Text);
Mydata.mserialprot.Parity = (Parity)Enum.Parse(typeof(Parity), comboBox_Check.Text); // 强制类型转换
Mydata.mserialprot.DataBits = Convert.ToInt32(comboBox_Data.Text);
Mydata.mserialprot.StopBits = (StopBits)Enum.Parse(typeof(StopBits), comboBox_Stop.Text);
Mydata.mserialprot.WriteTimeout = 300;
Mydata.mserialprot.ReadTimeout = 300;
Mydata.mserialprot.ReceivedBytesThreshold = 1;
try
{
Mydata.mserialprot.Open();

// 设置按键的使用权限
comboBox_Serial.Enabled = false;
comboBox_BandRate.Enabled = false;
comboBox_Check.Enabled = false;
comboBox_Data.Enabled = false;
comboBox_Stop.Enabled = false;
btOpenCom.Text = "关闭串口";
}
catch (Exception)
{ 
MessageBox.Show("串口连接失败!\r\n可能原因:串口被占用", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
else
{
Mydata.mserialprot.Close(); // 关闭串口
// 设置按键的使用权限
comboBox_Serial.Enabled = true;
comboBox_BandRate.Enabled = true;
comboBox_Check.Enabled = true;
comboBox_Data.Enabled = true;
comboBox_Stop.Enabled = true;
btOpenCom.Text = "打开串口";
}
}

接收串口数据

复制
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)//串口数据接收事件
{
Thread.Sleep(60);
try
{
string recvContent = null;//用来存放接收到的内容 
byte[] data = new byte[Mydata.mserialprot.BytesToRead]; //申请存放数据的缓冲区 
Mydata.mserialprot.Read(data, 0, Mydata.mserialprot.BytesToRead);//读取数据到data中 
Mydata.mserialprot.DiscardInBuffer();

recvContent += new ASCIIEncoding().GetString(data);//将接收到的内容追加到接收区

//使用Invoke访问主线程创建的控件
this.Invoke((EventHandler)(delegate
{
MessageBox.Show(recvContent);

}));

}
catch { }
}

串口发送数据

复制
/// <summary>
/// 向串口中发送数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public bool SendData(byte[] data)
{
if (Mydata.mserialprot == null)
{
return false;
}
if (Mydata.mserialprot.IsOpen == false)
{
return false;
}

try
{
Mydata.mserialprot.Write(data, 0, data.Length);
}
catch (Exception)
{
//提示信息
MessageBox.Show("数据发送失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return false;
}

return true;
}

发送数据使用代码

复制
if (Mydata.mserialprot == null)
{
return;
}

if (Mydata.mserialprot.IsOpen == true)
{
string senddata = textBox1.Text;
byte[] data = System.Text.Encoding.Default.GetBytes(senddata); // 将发送的数据转化为字节数组 
SendData(data); // 发送数据
}

整个实现过程分为三步,也就是三个代码段。

  1. 初始化并打开串口、注册串口接收数据事件。
  2. 接收数据实现。
  3. 发送数据实现。

就这么简单,上面我是以字符的形式发送接收的,如果你需要十六进制,自己转换就行了。

感觉很棒!可以赞赏支持我哟~

19 打赏

评论 (7)

登录后评论
为啥我那个Mydata.mserialport 会报错呀。
这个Mydata指的是什么?
一个类,里面放的静态变量,方便其它类中使用。
学习了
马克
有整个项目源码码?我想要源码
几行代码都要源码....自己动手不香吗?
QQ咨询 邮件咨询 狗哥推荐