您的位置:首页 > 其它

如何处理串口通讯数据重合与分批到达的问题

2006-09-29 09:25 525 查看
重合:
指示设备工作时,设备返回ok;而此时设备主动上报数据,这两个数据可能发生重合;因此串口同时可能有多个消息到达

分批到达:
一个回复由于干扰信号的关系,分两次到达,第一次到达了11个字节的前5个字节,第二次到达了11个字节的后6个字节。
在接收事件中(On_Comm)需要对数据进行整理,将这两种问题解决后(借助于数据包头,数据包尾),还有校验码的问题

下面是我的解决方案,由于是第一编写这样的程序,没什么经验,所以希望大家能提出意见.

private static Logger logger = LogManager.GetCurrentClassLogger(); //

MSCommLib.MSCommClass mc = new MSCommLib.MSCommClass(); //实例化MSCOMM

System.Timers.Timer timer = null; //定时器

ArrayList m_bytelist = new ArrayList(); //全局变量来存放接收到的数据

byte[] m_data = new byte[11]; //一个完整的消息指令数组长度为11

private int m_second = 0; //超时时间

private void InitCommonPort()
{

try
{
mc.CommPort = 3;

mc.Settings = "38400,n,8,1";

mc.RThreshold = 1; //每接收一个字符则激发OnComm()事件

mc.DTREnable = true;

mc.Handshaking = MSCommLib.HandshakeConstants.comNone;

mc.InputMode = MSCommLib.InputModeConstants.comInputModeBinary; //二进制

mc.InBufferSize = 1024;

mc.InputLen = 0; //决定每次Input读入的字符个数,缺省为0,表示读取接收缓冲区的全部内容
//mc.InputLen = 1; //一次读取一个

mc.NullDiscard = false;

mc.PortOpen = true; //打开串口

mc.OnComm +=new MSCommLib.DMSCommEvents_OnCommEventHandler(mc_OnComm);

Console.WriteLine("串口已打开!");

logger.Debug("串口已打开!");
}
catch
{
logger.Debug("串口打开失败!");
}
}

/// <summary>
/// 初始化定时器
/// </summary>
private void InitTimer()
{
timer = new System.Timers.Timer(1000);
timer.AutoReset = true;
timer.Enabled = true;
timer.Elapsed +=new ElapsedEventHandler(timer_Elapsed);
}

/// <summary>
/// 处理接收的数据
/// </summary>
private void checkByteList()
{
byte[] t_byte = new byte[11];

int j = 0;

if(m_bytelist.Count == 0)
{
return;
}
else
{
for(int i=0;i<m_bytelist.Count;i++)
{
t_byte[j] = (byte)m_bytelist[i];

if(t_byte[0] == 0x82)
{
if(j==10)
{
if(t_byte[10] == 0x83)
{
sendMail(t_byte);

j = 0;

this.clearArray(ref t_byte);

m_bytelist.RemoveRange(0,11);
}
else //如果包尾不是以83开头,数据不合法,丢弃
{
j=0;

logger.Debug("/n错误的指令 : [" + Utilities.ByteArrayToHexString(t_byte) + "] 已被丢弃! ");

this.clearArray(ref t_byte);

m_bytelist.RemoveRange(0,11);
}
}
else
{
j++;

this.InitTimer(); //初始化定时器

if(m_second == 5) //5秒后停止
{
logger.Debug("不完整的指令 : ["+Utilities.ByteArrayToHexString(t_byte) + "]");

this.clearArray(ref t_byte);

m_bytelist.RemoveRange(0,j);

j=0;
}
}
}
else //如果包头不是以82开头,数据不合法,丢弃
{
j=0;

logger.Debug("/n错误的指令 : [" + Utilities.ByteArrayToHexString(t_byte) + "] 已被丢弃! ");

this.clearArray(ref t_byte);

m_bytelist.RemoveRange(0,1);
}
}
}
}

/// <summary>
/// clear array
/// </summary>
/// <param name="o_data"></param>
private void clearArray(ref byte[]o_data)
{
for(int i=0;i<o_data.Length;i++)
{
o_data[i] =0;
}
}

/// <summary>
/// 将消息发给上层
/// </summary>
/// <param name="inData"></param>
private void sendMail(byte[] inData)
{

}

/// <summary>
/// 从串口接收数据

/// </summary>
private void mc_OnComm()
{
byte [] t_byte = (byte[])mc.Input; //receive data and clear buffer

for(int i = 0;i<t_byte.Length;i++)
{
m_bytelist.Add(t_byte[i]);
}
}

private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime now = DateTime.Now;
m_second = now.Second;
}

/// <summary>
/// 接收MCU主动发送的消息、解析、封装成对象消息发送给Session层
/// </summary>
protected override void process()
{
checkByteList();
}

主要的代码就这么多了,没有整理比较乱,有空的时候再整理一下了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐