C# SerialPort 串口的基本使用
SerialPort 是 C# 的串口类。
先创建一个串口实例对象:
_serialPort = new SerialPort();
基本的串口参数属性
BaudRate // 波特率
Parity // 校验位:奇校验,偶校验,无校验
DataBits // 数据位:6,7,8
StopBits // 停止位:StopBits.One StopBits.Two
打开关闭串口
获取可用的端口名称:
public string[] PortNames
{
get { return System.IO.Ports.SerialPort.GetPortNames(); }
}
通过 GetPortNames()
静态函数获取。
打开串口:
_serialPort.PortName; // 先赋值哪一个端口
_serialPort.Open(); // 打开
多次打开同一个端口,会抛出异常,需要做好异常处理。
关闭串口:
_serialPort.Close();
获取串口打开状态:
_serialPort.IsOpen;
串口发送数据
_serialPort.Write(byteData, 0, byteData.Length);//发送数据(数据,从0开始,结束位置)
public void Write(byte[] buffer, int offset, int count); // 函数原型,可以看下重载
串口接受数据
需要先绑定串口监听事件:
// 绑定数据接受监听事件
_serialPort.DataReceived += SerialPort_DataReceived;
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// 数据接收后需要干的活
}
/// <summary>
/// 串口接收数据
/// </summary>
public byte[] ReceiveData()
{
//定义一个接收数组,获取接收缓冲区数据的字节数
byte[] byteData = new byte[_serialPort.BytesToRead];
//读取数据
this.serialPort.Read(byteData, 0, _serialPort.BytesToRead);
return byteData;
}
另一种方式读取,循环读取 BytesToRead:
_serialPort.Write(byteData, 0, byteData.Length); // 先发送数据
// ...
// 循环读取,等待返回的数据
while(true)
{
if (_port.BytesToRead > 0)
{
_recivedData.Add((byte)_port.ReadByte()); // 一个字节一个字节的读取
}
// 这里可以对字节计数,如果多少字节之后,然后 Break;
// 也可以,做一个超时,比如 1s 钟之后,还没调出,直接 Break.
}
上面这种方式可以避免,有些硬件的数据不是一次性返回的,读取数据不完整的情况。
串口通信中的一些数据转换和验证
判断十六进制字符串hex是否正确:
private bool IsIIlegalHex(string hex)
{
return System.Text.RegularExpressions.Regex.IsMatch(hex, @"([^A-Fa-f0-9]|\s+?)+");
}
去除十六进制字符串的中间间隔符,十六进制字符串转化成字节数组:
/// <summary>
/// 去掉16进制字符串中的隔离符【 如:" ", "0x", "0X"】
/// </summary>
/// <param name="inString">需要转换的字符串数据</param>
/// <returns></returns>
private string DeleteSplitString(string inString)
{
string outString = string.Empty;
string[] delArray = { " ", "0x", "0X" };
if (inString.Contains(" ") || inString.Contains("0x") || inString.Contains("0X"))//存在隔离符
{
string[] str = inString.Split(delArray,
System.StringSplitOptions.RemoveEmptyEntries);//以隔离符进行转换数组,去掉隔离符,去掉空格。
for (int i = 0; i < str.Length; i++)
{
outString += str[i].ToString();
}
return outString;
}
else//不存在隔离符就直接返回
{
return inString;
}
}
/// <summary>
/// 把16进制字符串转换成byte[]
/// </summary>
/// <param name="inString"></param>
/// <returns></returns>
public byte[] From16ToBtyes(string inString)
{
inString = DeleteSplitString(inString);//去掉16进制中的隔离符
byte[] stringByte = new byte[inString.Length / 2];
for (int a = 0, b = 0; a < inString.Length; a = a + 2, b++)
{
try
{
string str = inString.Substring(a, 2);
stringByte[b] = (byte)Convert.ToInt16(str, 16);
}
catch (Exception ex)
{
throw new Exception("输入的数据不是纯16进制数! 参考错误信息:" + ex.Message);
}
}
return stringByte;
}
字符串转字节数组:
string outString = "";
byte[] bytes = Encoding.Default.GetBytes(inString);
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库