现假设有一系列产品我们需要使用软件控制其运作,我们可以通过向设备发送各种指令来达到此要求,首先由于产品种类较多,而且有些产品是纵向升级的,升级之后的产品基本上保持原有功能基础上加了些新功能,基于此要求,我们在设计相应类时,可以使用继承的方法,通信基类使用抽象类不允许直接实例化,仅提供一般串口操作的方法,比如发送指令及关串口等操作(初始化串口及打开串口操作在构造函数中完成),这样有任何产品只要从这个类继承即可调用基类函数,而且考虑到产品升级,只要继承相应的基类,重新相应的方法即可,即可以重用代码,结构又比较清晰,下面是一些示例代码
using
System;
using
System.IO.Ports;
using
System.Threading;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace
TripodDemo
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 串口操作通用类,抽象类防止类别直接实例化
/// </summary>
public abstract class ComPort : IDisposable
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 使用变量锁定对象
/// </summary>
private object objComm = new object();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 串口对象
/// </summary>
private SerialPort com;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private bool disposed = false;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
SerialPort#region SerialPort
public ComPort()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
com = new SerialPort("COM1", 9600);
OpenCom();
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public ComPort(SerialPort sp)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
com = sp;
OpenCom();
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void OpenCom()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
try
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!com.IsOpen)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
com.ReadTimeout = 3000;
com.WriteTimeout = 3000;
com.Open();
}
}
catch (Exception ex)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
throw new Exception(ex.Message);
}
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
Dispose & Close#region Dispose & Close
public void Dispose()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Dispose(true);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void Dispose(bool disposing)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!disposed && disposing && com != null && com.IsOpen)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
com.Close();
disposed = true;
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Close()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Dispose(true);
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
发送数据#region 发送数据
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 发送数据
/// </summary>
/// <param name="bwrite">写数据</param>
/// <param name="returnDataLen">读数据长度</param>
/// <param name="bread">读数据</param>
/// <param name="msel">超时毫秒</param>
/// <returns>是否执行成功</returns>
public bool SendData(byte[] bwrite, int returnDataLen, out byte[] bread, int msel)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
lock (objComm)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
bread = new byte[returnDataLen];
long l = DateTime.UtcNow.Ticks + msel * 10000;
com.DiscardInBuffer();
com.DiscardOutBuffer();
com.Write(bwrite, 0, bwrite.Length);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
while (com.BytesToRead < returnDataLen && DateTime.UtcNow.Ticks < l)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Thread.Sleep(1);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//串口无反应
if (com.BytesToRead < returnDataLen)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
try
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
com.Read(bread, 0, bread.Length);
return true;
}
catch (TimeoutException)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
}
}
#endregion
}
}
using
System;
using
System.IO.Ports;
using
System.Text;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace
TripodDemo
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
public class SerialQ01 : ComPort
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
构造函数#region 构造函数
public SerialQ01()
: base()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//constructor
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public SerialQ01(SerialPort sp)
: base(sp)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//constructor
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
读时间#region 读时间
public bool ReadDeviceTime(byte macno, out string time)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
int retLen = 10;
byte[] bread;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//构建命令
byte b1 = 0xAA;
byte b2 = 0x00;
byte b3 = 0x32;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
byte[] bwrite =
{ b1, b2, b2, macno, macno, b3, b3 };
bool bRet = SendData(bwrite, retLen, out bread, 1000);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
#if DEBUG
foreach (byte b in bread)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
System.Diagnostics.Debug.WriteLine(b.ToString("X2"));
}
#endif
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
time = string.Empty;
if (bRet)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (bread[0] == 0xCC && bread[1] == 0x30 && bread[2] == 0x30)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
time = string.Format("20{0}-{1}-{2} {3}:{4}", bread[3].ToString("X2"), bread[4].ToString("X2"), bread[5].ToString("X2"), bread[6].ToString("X2"), bread[7].ToString("X2"));
return true;
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
设置时间#region 设置时间
public bool SetDeviceTime(byte macno, DateTime time)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
int retLen = 10;
byte[] bread;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//构建命令
byte b1 = 0xAA;
byte b2 = 0x00;
byte b3 = 0x31;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
byte year = Convert.ToByte(time.Year.ToString().Substring(2, 2), 16);
byte month = Convert.ToByte(time.Month.ToString(), 16);
byte day = Convert.ToByte(time.Day.ToString(), 16);
byte hour = Convert.ToByte(time.Hour.ToString(), 16);
byte min = Convert.ToByte(time.Minute.ToString(), 16);
byte sec = Convert.ToByte(time.Second.ToString(), 16);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
byte xor = (byte)(year ^ month ^ day ^ hour ^ min ^ sec);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
byte[] bwrite =
{ b1, b2, b2, macno, macno, b3, b3, year, month, day, hour, min, sec, xor };
bool bRet = SendData(bwrite, retLen, out bread, 1000);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
#if DEBUG
foreach (byte b in bread)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
System.Diagnostics.Debug.WriteLine(b.ToString("X2"));
}
#endif
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (bRet)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (bread[0] == 0xCC && bread[1] == 0x30 && bread[2] == 0x30)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return true;
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
发卡#region 发卡
public bool IssueCard(byte macno, string cardNo)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (cardNo.Length < 8) return false;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
int retLen = 10;
byte[] bread;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//构建命令
byte b1 = 0xAA;
byte b2 = 0x00;
byte b3 = 0x45;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
byte cardNo1 = Convert.ToByte(cardNo.Substring(0, 2), 16);
byte cardNo2 = Convert.ToByte(cardNo.Substring(2, 2), 16);
byte cardNo3 = Convert.ToByte(cardNo.Substring(4, 2), 16);
byte cardNo4 = Convert.ToByte(cardNo.Substring(6, 2), 16);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
byte xor = (byte)(cardNo1 ^ cardNo2 ^ cardNo3 ^ cardNo4);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
byte[] bwrite =
{ b1, b2, b2, macno, macno, b3, b3, cardNo1, cardNo2, cardNo3, cardNo4, xor };
bool bRet = SendData(bwrite, retLen, out bread, 1000);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
#if DEBUG
foreach (byte b in bwrite)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
System.Diagnostics.Debug.WriteLine(b.ToString("X2"));
}
#endif
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (bRet)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (bread[0] == 0xCC && bread[1] == 0x30 && bread[2] == 0x30)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return true;
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
}
using
System;
using
System.IO.Ports;
using
System.Text;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace
TripodDemo
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 产品Q01的长升级版本,大部分功能同Q01,但发卡模块增加有效期
/// </summary>
public class SerialQ01A : SerialQ01
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
构造函数#region 构造函数
public SerialQ01A()
: base()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//constructor
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public SerialQ01A(SerialPort sp)
: base(sp)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//constructor
}
#endregion
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
发卡#region 发卡
public bool IssueCard(byte macno, string cardNo, DateTime bTime, DateTime eTime)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (cardNo.Length < 8) return false;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
int retLen = 10;
byte[] bread;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
//构建命令
byte b1 = 0xAA;
byte b2 = 0x00;
byte b3 = 0x45;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
byte cardNo1 = Convert.ToByte(cardNo.Substring(0, 2), 16);
byte cardNo2 = Convert.ToByte(cardNo.Substring(2, 2), 16);
byte cardNo3 = Convert.ToByte(cardNo.Substring(4, 2), 16);
byte cardNo4 = Convert.ToByte(cardNo.Substring(6, 2), 16);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
byte bYear = Convert.ToByte(bTime.Year.ToString(), 16);
byte bMonth = Convert.ToByte(bTime.Month.ToString(), 16);
byte bDay = Convert.ToByte(bTime.Day.ToString(), 16);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
byte eYear = Convert.ToByte(eTime.Year.ToString(), 16);
byte eMonth = Convert.ToByte(eTime.Month.ToString(), 16);
byte eDay = Convert.ToByte(eTime.Day.ToString(), 16);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
byte xor = (byte)(cardNo1 ^ cardNo2 ^ cardNo3 ^ cardNo4 ^ bYear ^ bMonth ^ bDay ^ eYear ^ eMonth ^ eDay);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
byte[] bwrite =
{ b1, b2, b2, macno, macno, b3, b3, cardNo1, cardNo2, cardNo3, cardNo4, bYear, bMonth, bDay, eYear, eMonth, eDay, xor };
bool bRet = SendData(bwrite, retLen, out bread, 1000);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
#if DEBUG
foreach (byte b in bwrite)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
System.Diagnostics.Debug.WriteLine(b.ToString("X2"));
}
#endif
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (bRet)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (bread[0] == 0xCC && bread[1] == 0x30 && bread[2] == 0x30)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return true;
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return false;
}
}
#endregion
}
}
源码示例:
/Files/chenzz/TripodDemo_cs.zip
/Files/chenzz/TripodDemo.zip