===========================================================================================================
程序预览:
程序运行,设置参数选择com4,打开,串口调试工具发送指令,程序接收指令
===========================================================================================================
代码解析:
代码特点:1.对串口类的封装(CSPDAO.cs);2:利用设计模式里的模板模式对串口数据发送和接收进行提取(Protocol文件夹)
CSPDAO.cs代码解析
/// <summary>
/// 请求命令队列
/// </summary>
private Queue<IProtocolReader> m_queueRequests;
/// <summary>
/// 应答数据集合
/// </summary>
private List<byte> m_listResponses;
/// <summary>
/// 发送线程同步信号
/// </summary>
private ManualResetEvent m_sendWaiter;
/// <summary>
/// 接收数据处理线程同步信号
/// </summary>
private ManualResetEvent m_receiveWaiter;
// 开启端口
m_serialPort = new SerialPort(portName, baudRate, (Parity)parity, dataBits, (StopBits)stopBits);
m_serialPort.DataReceived += SerialPortDataReceived;
m_serialPort.Open();
//
// 开启线程
m_bProtRunThdExit = false;
ThreadPool.QueueUserWorkItem(new WaitCallback(Polling)); // 轮询发送线程
ThreadPool.QueueUserWorkItem(new WaitCallback(Send)); // 命令发送线程
ThreadPool.QueueUserWorkItem(new WaitCallback(Received)); // 接收处理线程
Send方法
byte[] buffer = reader.GetCMDBytes();
m_serialPort.DiscardInBuffer();
m_serialPort.Write(buffer, 0, buffer.Length);
reader.Display();
SerialPortDataReceived方法
int iBytes = m_serialPort.BytesToRead ;
if (iBytes > 0)// m_serialPort.BytesToRead > 0
{
byte[] buffer = new byte[iBytes];
int readCount = m_serialPort.Read(buffer, 0, buffer.Length);
//
Monitor.Enter(m_listResponses);
m_listResponses.AddRange(buffer);
Monitor.Exit(m_listResponses);
}
Received方法
byte[] buffer = m_listResponses.GetRange(0, m_listResponses.Count).ToArray();
//m_oHandel.Process(buffer);
m_oHandel.Process(m_oReader, buffer);
m_listResponses.RemoveRange(0, m_listResponses.Count);
遇到的问题:
1.
//this.Invoke((EventHandler)(delegate
//{
// txtTags.Text = Tags;
//}));
this.BeginInvoke((EventHandler)(delegate
{
txtTags.Text = Tags;
}));
// 不使用Invoke原因:当点击关闭程序时,会出现无法访问已释放的对象。对象名:“MainForm”
// <位置:CSPDAO send(),catch>
2.硬件接法:因为阅读器出口接线是485,所以为了在pc机上能调试,接上了485转RS232,再接上RS232转USB
问题点:因为我想做串口重连这个功能,所以在程序运行过程中,拔掉usb,然后出现问题
"由于线程退出或应用程序请求,已放弃 I/O 操作","COM5不存在",接上usb后,程序可以跑一会,但过了一会出现"对端口的访问被拒绝",用try...catch...无法
找到网上的一些说法:
//文件句柄丢失,无解!!
//SerialPort设计时没考虑到:
//1:在Window系统中正常情况下打开的“文件”是不可能被删除。
//2:但虚拟串可却突破了这一点。
//所以,如果在“使用中”的USB转串口的设备,在未“Close”的情况下移除,那么将导致程序中的“SerialPort”对象即无法关闭,无法正常运行,也法重新再打开。
//如果有这种用法时,还是建议用标准串口