串口数据解析问题

qq_37436100 2018-08-20 04:05:47
高手们,实在搞不定,没弄过串口程序,协议如下:


我要怎么解析数据呢
找了点网上的代码
我要怎么根据协议来改合适呢,没有包尾

public class ByteQueue
{
private List<byte> m_buffer = new List<byte>();
public bool Find()
{
if (m_buffer.Count == 0)
return false;
int HeadIndex = m_buffer.FindIndex(o => o == 0xA5);

if (HeadIndex == -1)
{
m_buffer.Clear();
return false; //没找到A5
}

else if (HeadIndex != 0) //不为开头移掉之前的字节
{
if (HeadIndex > 1)
m_buffer.RemoveRange(0, HeadIndex);
}

int length = GetLength();
if (m_buffer.Count < length)
{
return false;
}



int TailIndex = m_buffer.FindIndex(o => o == 0xA5); //查找55的位置

if (TailIndex == -1)
{
//这一步为防止连发一个AA开头的包后,没发55,而又发了一个AA
int head = m_buffer.FindLastIndex(o => o == 0xA5);
if (head > -1)
{
m_buffer.RemoveRange(0, head);
}
return false;
}
else if (TailIndex + 1 != length) //计算包尾是否与包长度相等
{
m_buffer.RemoveRange(0, TailIndex);
return false;
}

return true;
}

/// <summary>
/// 命令类型
/// </summary>
/// <returns></returns>
public byte Cmd()
{
if (m_buffer.Count >= 2)
{
return m_buffer[1];
}
return 0;
}

/// <summary>
/// 序号
/// </summary>
/// <returns></returns>
public byte Number()
{
if (m_buffer.Count >= 3)
{
return m_buffer[2];
}
return 0;
}

/// <summary>
/// 包长度
/// </summary>
/// <returns></returns>
public int GetLength()
{
int len = 5;//AA 命令类型 序号 校验和 55
if (m_buffer.Count >= 3)
{
switch (m_buffer[2]) //第三字节为序号
{
case 0x00: //序号
return len + 16;
case 0x01: //序号
return len + 10;
case 0x02: //序号
return len + 12;
}
}
return 0;
}
/// <summary>
/// 提取数据
/// </summary>
public void Dequeue(byte[] buffer, int offset, int size)
{
m_buffer.CopyTo(0, buffer, offset, size);
m_buffer.RemoveRange(0, size);
}

/// <summary>
/// 队列数据
/// </summary>
/// <param name="buffer"></param>
public void Enqueue(byte[] buffer)
{
m_buffer.AddRange(buffer);
}
}


...全文
270 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Mr Dang 2018-08-21
  • 打赏
  • 举报
回复
其实很简单,你想复杂了,串口协议就2个方法(组帧和解析帧),协议是个搬运工,搬运数据的。
1、首先找帧头A5,帧字节长度是固定的,所以可以计算校验和,效验和对的就是一帧合法帧,否则就查找下一个A5,再计算校验和 。。。
2、上一步已经找到了合法帧,就直接按照理论的协议帧格式提取数据,再处理数据即可。
qq_37436100 2018-08-20
  • 打赏
  • 举报
回复
大神们,有人帮我解释一下代码中的find是怎么找到数据的吗?
qq_37436100 2018-08-20
  • 打赏
  • 举报
回复
引用 5 楼 xuzuning 的回复:
设传入字节数组为 bs, 则: 先判断是否为合法数据 if (bs[0] == 0xa5 && BitConverter.ToUInt16(bs, 7) == bs.Length - 10) { //条件满足是合法数据 //按 根据协议 指示的位置取值就可以了 }
每次回来的数据及长度不一样,我不知道怎么取,,哥们,能留个QQ不?
xuzuning 2018-08-20
  • 打赏
  • 举报
回复
设传入字节数组为 bs,
则:
先判断是否为合法数据
if (bs[0] == 0xa5 && BitConverter.ToUInt16(bs, 7) == bs.Length - 10)
{
//条件满足是合法数据
//按 根据协议 指示的位置取值就可以了
}
qq_37436100 2018-08-20
  • 打赏
  • 举报
回复
引用 3 楼 stherix 的回复:
[quote=引用 2 楼 qq_37436100 的回复:] 没有包尾,怎么取数据呢
用包头+长度就行 DBLNG应该是数据区长度,数据区长度+包头+校验字长度就是整包长[/quote] 我怎么取出来来,这个find有点看不懂
  public bool Find()
        {
            if (m_buffer.Count == 0)
                return false;
            int HeadIndex = m_buffer.FindIndex(o => o == 0xA5);
 
            if (HeadIndex == -1)
            {
                m_buffer.Clear();
                return false; //没找到A5
            }
 
            else if (HeadIndex != 0) //不为开头移掉之前的字节
            {
                if (HeadIndex > 1)
                    m_buffer.RemoveRange(0, HeadIndex);
            }
 
            int length = GetLength();
            if (m_buffer.Count < length)
            {
                return false;
            }
 
 
 
            int TailIndex = m_buffer.FindIndex(o => o == 0xA5); //查找55的位置
 
            if (TailIndex == -1)
            {
                //这一步为防止连发一个AA开头的包后,没发55,而又发了一个AA
                int head = m_buffer.FindLastIndex(o => o == 0xA5);
                if (head > -1)
                {
                    m_buffer.RemoveRange(0, head);
                }
                return false;
            }
            else if (TailIndex + 1 != length) //计算包尾是否与包长度相等
            {
                m_buffer.RemoveRange(0, TailIndex);
                return false;
            }
 
            return true;
        }
public bool Find() { if (m_buffer.Count == 0) return false; int HeadIndex = m_buffer.FindIndex(o => o == 0xA5); if (HeadIndex == -1) { m_buffer.Clear(); return false; //没找到A5 } else if (HeadIndex != 0) //不为开头移掉之前的字节 { if (HeadIndex > 1) m_buffer.RemoveRange(0, HeadIndex); } int length = GetLength(); if (m_buffer.Count < length) { return false; } int TailIndex = m_buffer.FindIndex(o => o == 0xA5); //查找55的位置 if (TailIndex == -1) { //这一步为防止连发一个AA开头的包后,没发55,而又发了一个AA int head = m_buffer.FindLastIndex(o => o == 0xA5); if (head > -1) { m_buffer.RemoveRange(0, head); } return false; } else if (TailIndex + 1 != length) //计算包尾是否与包长度相等 { m_buffer.RemoveRange(0, TailIndex); return false; } return true; }
stherix 2018-08-20
  • 打赏
  • 举报
回复
引用 2 楼 qq_37436100 的回复:
没有包尾,怎么取数据呢


用包头+长度就行
DBLNG应该是数据区长度,数据区长度+包头+校验字长度就是整包长
qq_37436100 2018-08-20
  • 打赏
  • 举报
回复
没有包尾,怎么取数据呢
jhone99 2018-08-20
  • 打赏
  • 举报
回复
解协议需要根据协议的含义来解析

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧