using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;
namespace MSPCS
{
///
/// 通讯端口,用于和上位机通讯
/// 上行与下行使用同一种格式:
///
/*
同步头 6 Byte EB90EB90EB90H
设备地址 1 Byte DevAddr
长度 1 Byte (N+2)
命令码 1 Byte CmdCode
数据区 N Byte DATA(1),..,DATA(N)
校验码 1 Byte 累加和求余(除FF)
*
* 00H 数据接收正确(下行)
01H 数据接收错误(下行)
02H 取测量值
03H 取参数
04H 设置参数
05H 设置时间
06H 设备异常码(下行)
7FH 设备状态正常(上行)
*/
///
/// 端口类
///
public class ComPort : SerialPort, IDisposable
{
public event EventHandler NewSerialDataRecieved;
public event EventHandler TimeOutHandler;
public event EventHandler Receiving;
public event EventHandler ReceiveFinish;
public event EventHandler Uploading;
public event EventHandler UploadFinish;
static byte[] ErrorCode = { 0xEB, 0x90, 0xEB, 0x90, 0xEB, 0x90, 0x00, 0x00, 0x7F };
#region 构造函数
public ComPort()
: base()
{
Init();
}
public ComPort(System.ComponentModel.IContainer container)
: base(container)
{
Init();
}
private void Init()
{
base.PortName = "COM2";
base.BaudRate = 9600;
base.DataBits = 8;
base.StopBits = StopBits.One;
base.Parity = Parity.None;
base.ReadTimeout = SerialPort.InfiniteTimeout;
base.ReadBufferSize = 1024;
base.WriteBufferSize = 512;
base.WriteTimeout = 1000;
base.DataReceived += new SerialDataReceivedEventHandler(OnDataReceived);
}
#endregion
#region Methods
/// <summary>
/// 开始监听
/// </summary>
public void StartListening()
{
try
{
if (!this.IsOpen) // 如果端口没有打开,就打开
{
this.Open();
}
}
catch
{
MessageBox.Show("上位机通讯端口错误!",
"SPC工作站",
MessageBoxButtons.OK,
MessageBoxIcon.Hand,
MessageBoxDefaultButton.Button1);
}
}
#endregion
/// <summary>
/// 读取消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
if (null != Receiving)
{
// Receiving(sender, null);
}
//byte[] data = new byte[base.BytesToRead];
//base.Read(data, 0, base.BytesToRead);
//同步头 6 Byte EB90EB90EB90H
//设备地址 1 Byte DevAddr
//长度 cton 1 Byte (N+2)
byte[] dataInfo = new byte[8];
dataInfo[0] = Convert.ToByte(base.ReadByte());
if (0xEB != dataInfo[0])
{
base.DiscardInBuffer();
dataInfo = null;
return;
}
dataInfo[1] = Convert.ToByte(base.ReadByte());
if (0x90 != dataInfo[1])
{
base.DiscardInBuffer();
dataInfo = null;
return;
}
dataInfo[2] = Convert.ToByte(base.ReadByte());
if (0xEB != dataInfo[2])
{
base.DiscardInBuffer();
dataInfo = null;
return;
}
dataInfo[3] = Convert.ToByte(base.ReadByte());
if (0x90 != dataInfo[3])
{
base.DiscardInBuffer();
dataInfo = null;
return;
}
dataInfo[4] = Convert.ToByte(base.ReadByte());
if (0xEB != dataInfo[4])
{
base.DiscardInBuffer();
dataInfo = null;
return;
}
dataInfo[5] = Convert.ToByte(base.ReadByte());
if (0x90 != dataInfo[5])
{
base.DiscardInBuffer();
dataInfo = null;
return;
}
base.Read(dataInfo, 6, dataInfo.Length - 6);
// base.Read(dataInfo, 0, dataInfo.Length);
int len = Convert.ToInt32( dataInfo[7] );
if (len > 0)
{
byte[] data = new byte[8 + len];
dataInfo.CopyTo(data,0);
for (int i = 0; i < len; i++)
{
data[8 + i] = Convert.ToByte( base.ReadByte() );
}
base.DiscardInBuffer();
if (NewSerialDataRecieved != null)
{
NewSerialDataRecieved(this, new ComDataEventArgs(data));
}
if (null != ReceiveFinish )
{
ReceiveFinish(sender, null);
}
}
}
catch //(Exception ex)
{
if (null != TimeOutHandler)
{
TimeOutHandler(this, null);
}
return;
// MessageBox.Show("获取端口数据错误:" + ex.Message);
//if (NewSerialDataRecieved != null)
//{
// NewSerialDataRecieved(this, new ComDataEventArgs(ErrorCode));
//}
}
}
#region
/// <summary>
/// 发送数据
/// </summary>
/// <param name="result"></param>
public void SendData(byte[] result)
{
try
{
if (null != Uploading)
{
Uploading(this, null);
}
base.DiscardOutBuffer();
base.Write(result, 0, result.Length);
if (null != UploadFinish)
{
UploadFinish(this, null);
}
}
catch(Exception ex)
{
base.DiscardOutBuffer();
MessageBox.Show(ex.Message);
}
}
#endregion
}
/// <summary>
/// 数据读取消息事件
/// 把二进制值转化为测量结果。
/// </summary>
public class ComDataEventArgs : EventArgs
{
public ComDataEventArgs(byte[] data)
{
Request = data;
}
/// <summary>
/// Byte array containing data from serial port
/// </summary>
public byte[] Request;
}
}
应用程序是在CE系统上运行的,用10ms间隔重复发送数据,CE任务管理器显示内存不断增加,CPU100%。一直发送到最后,程序会卡死。注释掉 base.DataReceived += new SerialDataReceivedEventHandler(OnDataReceived);就跟程序刚启动一样了,任务管理器显示的情况一样了,只是耗了小部分内存。求大牛指点。