#自写了一个很菜的串口通讯,不过个人感觉好理解,分享一下
##C#写串口通讯流程:
第一步:串口实例化(这一步至少要传进串口号和波特率,其他的如校验位先不考虑,这里做一个简单的串口通讯)
第二步:打开串口
第三步:写发送/接收函数
不废话了,直接上干货
插一个电脑自己搜索COM口的函数,要设置一个comboBOX_port组件:
private void GetCom()
{
String[] mystring = SerialPort.GetPortNames(); // 获取计算机的端口名的数组
for (int i = 0; i < mystring.Length; i++)
{
comboBox_port.Items.Add(mystring[i]);
}
comboBox_port.Text = mystring[0];
}
先看整体代码,然后后面详解一下思路:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
namespace COM_Device
{
public class COM
{
private string m_com;
private int m_baudrate;
SerialPort device;
string revebuff;
public COM(string com ,int baudrate)
{
m_baudrate = baudrate;
m_com = com;
}
/// <summary>
/// 连接设备
/// </summary>
public string Connect()
{
string ret = "OK";
try
{
device = new SerialPort(m_com,m_baudrate);
device.Open();
}
catch(Exception ex)
{
ret = ex.Message;
}
return ret;
}
/// <summary>
/// 关闭设备
/// </summary>
public string Close()
{
string ret = "OK";
try
{
if(device == null)
{
ret = "COM口未连接";
return ret;
}
device.Close();
}
catch (Exception ex)
{
ret = ex.Message;
}
return ret;
}
/// <summary>
/// 发送消息字符串
/// </summary>
public string Send(string str) //发送字符串
{
string ret = "OK";
try
{
if (!device.IsOpen)
{
ret = "COM口未打开";
return ret;
}
device.Write(str);
}
catch(Exception ex)
{
ret = ex.Message;
}
return ret;
}
/// <summary>
/// 发送16进制数
/// </summary>
public string SendtoHex(string str)
{
string ret = "OK";
try
{
if (!device.IsOpen)
{
ret = "COM口未打开";
return ret;
}
byte[] data = new byte[1];
str = str.Replace(" ", ""); // 把空格去掉
for (int i = 0; i < (str.Length - str.Length % 2) / 2; i++)
{
// 把发送文本框的数值两个两个的发送,并且转化为16进制表示
data[0] = Convert.ToByte(str.Substring(i * 2, 2), 16);
device.Write(data, 0, 1); // 从0开始写入1个字节
}
if (str.Length % 2 != 0) // 剩下1位数据单独处理
{
data[0] = Convert.ToByte(str.Substring(str.Length - 1, 1), 16); // 单独发送1位
device.Write(data, 0, 1); // 写入到串口
}
}
catch(Exception ex)
{
ret = ex.Message;
}
return ret;
}
/* 字符串转化为十六进制的字节数据
str:要转换的字符串*/
public byte[] strToHexBytes(string str)
{
str = str.Replace(" ", ""); // 把空格去掉
if (str.Length % 2 != 0)
{
str = str.Insert(str.Length - 1, "0");
}
byte[] array = new byte[str.Length / 2];
for (int i = 0; i < str.Length / 2; i++)
{
array[i] = Convert.ToByte(str.Substring(2 * i, 2), 16);
}
return array;
}
/// <summary>
/// byte[]转为16进制字符串
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < bytes.Length; i++)
{
returnStr += bytes[i].ToString("X2");
}
}
return returnStr;
}
/// <summary>
/// 接收16位消息
/// </summary>
public string ReveHex(ref string buff)
{
try
{
if (!device.IsOpen)
{
return "COM口未打开";
}
int count = device.BytesToRead;
byte[] buffer = new Byte[count]; //创建缓冲区
device.Read(buffer, 0, count);
buff = byteToHexStr(buffer);
string ret = buff;
buff = null;
return ret;
}
catch(Exception ex)
{
return ex.Message;
}
}
public string ReveHex()
{
return ReveHex(ref revebuff);
}
/// <summary>
/// 接收字符串
/// </summary>
public string Reve(ref string buff)
{
try
{
if (!device.IsOpen)
{
return "COM口未打开";
}
buff = device.ReadExisting(); //以字符串方式读
string ret;
ret = buff;
buff = null;
return ret;
}
catch(Exception ex)
{
return ex.Message;
}
}
public string Reve()
{
return Reve(ref revebuff);
}
}
}
1.实例化串口
//这里m_com,m_baudrate是自己创建的,根据需求改
SerialPort device = device = new SerialPort(m_com,m_baudrate);
2.打开串口
device.Open();//打开串口,就这么简单,C#已经给你封装好了
(1)发送字符串函数
public string Send(string str) //发送字符串
{
string ret = "OK";
try
{
if (!device.IsOpen)
{
ret = "COM口未打开";
return ret;
}
device.Write(str);//只有这一步是发送
}
catch(Exception ex)
{
ret = ex.Message;
}
return ret;//在自己写的时候判断一下到底发送成功没有
}
(2)发送16位进制数(考虑到跟单片机通讯,我自己做单片机的)
/// <summary>
/// 发送16进制数
/// </summary>
public string SendtoHex(string str)
{
string ret = "OK";
try
{
if (!device.IsOpen)
{
ret = "COM口未打开";
return ret;
}
byte[] data = new byte[1];
str = str.Replace(" ", ""); // 把空格去掉
for (int i = 0; i < (str.Length - str.Length % 2) / 2; i++)
{
// 把发送文本框的数值两个两个的发送,并且转化为16进制表示
data[0] = Convert.ToByte(str.Substring(i * 2, 2), 16);
device.Write(data, 0, 1); // 从0开始写入1个字节
}
if (str.Length % 2 != 0) // 剩下1位数据单独处理
{
data[0] = Convert.ToByte(str.Substring(str.Length - 1, 1), 16); // 单独发送1位
device.Write(data, 0, 1); // 写入到串口
}
}
catch(Exception ex)
{
ret = ex.Message;
}
return ret;
}
(3)接收字符串
/// <summary>
/// 接收字符串
/// </summary>
public string Reve(ref string buff)
{
try
{
if (!device.IsOpen)
{
return "COM口未打开";
}
buff = device.ReadExisting(); //以字符串方式读
string ret;
ret = buff;
buff = null;
return ret;
}
catch(Exception ex)
{
return ex.Message;
}
}
public string Reve()//做了一个处理,接收到一次后就清空缓存字符
{
return Reve(ref revebuff);
}
(4)接收16位进制数
/// <summary>
/// 接收16位消息
/// </summary>
public string ReveHex(ref string buff)
{
try
{
if (!device.IsOpen)
{
return "COM口未打开";
}
int count = device.BytesToRead;
byte[] buffer = new Byte[count]; //创建缓冲区
device.Read(buffer, 0, count);
buff = byteToHexStr(buffer);
string ret = buff;
buff = null;
return ret;
}
catch(Exception ex)
{
return ex.Message;
}
}
public string ReveHex()//做了一个处理,接收到一次后就清空缓存字符串
{
return ReveHex(ref revebuff);
}
#目前亲测可用,有错误的地方请大佬们批评予以改正(感谢!!!),这也是我自己自学照猫画虎