RC-232C是外设硬件通讯协议中比较常见的一种,例如扫码枪,光源控制器,压力测试仪,温控仪等等。以下简述串口通讯知识,用C#实现串口通讯的主要操作。
串口通讯主要参数属性包括:波特率,数据位,停止位以及奇偶校验。这是硬件使用手册必定会提到的(除非没有使用手册),不明确需要和硬件供应商确认沟通。
1.建立类Com_BaseClass,声明属性变量。
public class Com_BaseClass
{
//属性
public SerialPort m_SerialPort;//声明串口
public string m_CommPort;//串口名
public int m_BaudRate; //波特率
public int m_DataBit;//数据位
public StopBits m_StopBit;//停止位
public Parity m_Parity;//奇偶校验
}
2.串口属性准备好后,编辑串口基本操作包括:串口初始化,串口关闭,数据发送,数据接收。继续往类Com_BaseClass里面编辑串口操作。
public class Com_BaseClass
{
//属性
public SerialPort m_SerialPort;//声明串口
public string m_CommPort;//串口名
public int m_BaudRate; //波特率
public int m_DataBit;//数据位
public StopBits m_StopBit;//停止位
public Parity m_Parity;//奇偶校
/// <summary>串口初始化</summary>
/// <param name="CommPort">串口名称"COM1"</param>
/// <param name="BaudRate">波特率</param>
/// <param name="Party">奇偶校验</param>
/// <param name="dataBit">数据位</param>
/// <param name="StopBit">停止位</param>
public int InitCom(string CommPort, int BaudRate,Parity Party, int dataBit, StopBits StopBit)
{
int err = -1;
try
{
//传入参数
m_CommPort = CommPort;
m_BaudRate = BaudRate;
m_Parity = Party;
m_DataBit = dataBit;
m_StopBit = StopBit;
if (m_SerialPort == null)//创建实例
{
m_SerialPort = new SerialPort(m_CommPort, m_BaudRate, m_Parity, m_DataBit, m_StopBit);
}
else
{
if (m_SerialPort.IsOpen) m_SerialPort.Close();
m_SerialPort.PortName = m_CommPort;
m_SerialPort.BaudRate = m_BaudRate;
m_SerialPort.Parity = m_Parity;
m_SerialPort.DataBits = m_DataBit;
m_SerialPort.StopBits = m_StopBit;
}
try
{
m_SerialPort.Open();//打开串口
err = 0;//打开成功,初始化返回0
}
catch (Exception ex)
{
throw ex;
}
}
catch (Exception ex)
{
return err;
}
return err;
}
//判断串口已经实例化,不等于null
//串口关闭
public int ClosePort()
{
try
{
if (m_SerialPort != null)
m_SerialPort.Close();
return 0;
}
catch (Exception ex)
{
return -1;
}
}
//数据发送基本内容
//串口已经初始化
//串口已经打开
//清除接收缓存区
//清除传输缓存区
//写入待发送的数据
//1.发送字符串
public int SendData(string sendString)
{
if (m_SerialPort == null)
{
return -1;//端口未初始化
}
if (!m_SerialPort.IsOpen)
{
return-1;//串口未打开
}
try
{
m_SerialPort.DiscardInBuffer();
m_SerialPort.DiscardOutBuffer();
m_SerialPort.Write(sendString);
return 0;
}
catch (Exception ex)
{
return -1;
}
}
//2.也有发送字节的
public int SendData(byte[] _SendBytes)
{
if (m_SerialPort == null)
{
return -1;//端口未初始化
}
if (!m_SerialPort.IsOpen)
{
return -1;//串口未打开
}
try
{
m_SerialPort.DiscardInBuffer();//清空接收缓冲区内存
m_SerialPort.DiscardOutBuffer();//清空传输缓冲区内存
m_SerialPort.Write(_SendBytes, 0, _SendBytes.Length); // 数据写入
return 0;
}
catch (Exception ex)
{
return -1;
}
}
//数据接收
public int ReceiveData(ref byte[] _OutBytes, int _recLen, int _Timeout)
{
List<byte> _BytesData = new List<byte>();//临时保存缓冲区数据
long _StarTime = DateTime.Now.Ticks;//10000000分之1秒
long _EndTime;
long _interval = 0;
int Errno = 0;
if (m_SerialPort == null)
{
return -1;//端口未初始化
}
if (!m_SerialPort.IsOpen)
{
return -1;//串口未打开
}
try
{
m_SerialPort.ReadTimeout = _Timeout;//串口读取超时
while (true) //在超时范围内等待读取
{
try
{
int intByteConut = m_SerialPort.BytesToRead;
if (intByteConut > 0)//判断缓存区个数
{
byte[] _TmpData = new byte[intByteConut];
m_SerialPort.Read(_TmpData, 0, intByteConut);
_BytesData.AddRange(_TmpData);//合并
Thread.Sleep(50);
if (_BytesData.Count >= _recLen)//超长,剪除
{
_BytesData.RemoveRange(_recLen, _BytesData.Count - _recLen);
break;
}
}
else
break;
}
catch (TimeoutException)
{
Thread.Sleep(20);
}
_EndTime = DateTime.Now.Ticks;
_interval = (_EndTime - _StarTime) / 10000;
if (_interval > (_Timeout - 100))
{
_OutBytes = _BytesData.ToArray();
Errno = -1;//超时跳出
break;
}
}
_OutBytes = _BytesData.ToArray();
Errno = 0;
}
catch (Exception ex)
{
_OutBytes = _BytesData.ToArray();
return -1;
}
return Errno;
}
}
******后续用Com_BaseClass,new创建实例进行编辑调用。