欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

多功能嵌入式解码软件

程序员文章站 2022-03-20 12:29:56
概述 在嵌入式开发的过程中,由于经常需要下位机与上位机通信,通信之间就需要协议,有协议就需要进行解码,而产品开发得过程中,协议可能不断更新,协议更新就需要解码软件更新,不断更新解码软件就很麻烦,如果所有人都愿意麻烦,那么我不愿意。在这里就产生了一个通用的解码类库,使用者就可以简单的改一下协议文件,通 ......

 概述

  在嵌入式开发的过程中,由于经常需要下位机与上位机通信,通信之间就需要协议,有协议就需要进行解码,而产品开发得过程中,协议可能不断更新,协议更新就需要解码软件更新,不断更新解码软件就很麻烦,如果所有人都愿意麻烦,那么我不愿意。在这里就产生了一个通用的解码类库,使用者就可以简单的改一下协议文件,通过调用这个类库,就可以实现解码,不需要再更改解码算法了。
class_frame类库就是这样的一个很方便的库件。

 类库简介

 1 #region 程序集 xutopia, version=1.0.0.0, culture=neutral, publickeytoken=null
 2 // d:\workspace\09 uarttool\19\mydll\xutopia\xutopia\bin\debug\xutopia.dll
 3 #endregion
 4 
 5 using system.collections.generic;
 6 
 7 namespace xutopia
 8 {
 9     public class class_frame
10     {
11         public bool protocolfresh;
12         public string framemsg;
13 
14         public class_frame();
15 
16         public _decodedattimelystruct decodetimely(byte rxddat);
17         public void process_protocol_readed(string strpro);
18         public list<_savedecodestruct> savedecodedat(list<byte> listrxd);
19 
20         public struct _decodedattimelystruct
21         {
22             public byte function;
23             public list<object> listre;
24         }
25         public struct _savedecodestruct
26         {
27             public byte function;
28             public string str;
29         }
30     }
31 }

名称空间:xutopia;

类的名称:class_frame;

 

属性:

  public bool protocolfresh;

    true  :   已经正确解析出协议;

         false :  没有协议。

  public string framemsg;

    解析出协议的信息。

方法:

  public _decodedattimelystruct decodetimely(byte rxddat);

    param:

        rxddat:接收到的数据;

  retval:

    _decodedattimelystruct:解码的信息;

    function : 功能码;

    listre: 解码的数据。需要强制类型转换后才能使用。

  public void process_protocol_readed(string strpro);

    param:

        strpro:读取到的协议文件;

  public list<_savedecodestruct> savedecodedat(list<byte> listrxd);

    param:

      listrxd:接收到的数据的泛型集合。

    retval:

      每一种功能码的解码数据:

        function:功能码;

        str : 需要保存的数据。

 验证类库

 通信协议

下面进行一个示例:

    下位机需要向上位机发送3中数据帧,数据帧以功能码来识别,每种数据帧的协议如下3个表格所示,上位机需要把这些数据按照协议解码出来,并进行保存以便分析。

通信协议:

多功能嵌入式解码软件

多功能嵌入式解码软件

多功能嵌入式解码软件

准备协议文件

  按照通信协议编写协议文件
  

/*
this is a protocol
2019-03-28
正文中不可以出现注释
e.g. 正文//注释内容
e.g. 正文
//注释内容
正文开头第一行必须是frametype
*/
/*
目前最后一行必须是空行
*/
frametype=header2 function
header1=0xa0
header2=0xa1
body=1
function=0xb1
index=1,type=unsigned char
index=2,type=unsigned short
index=3,type=unsigned int
index=4,type=short
index=5,type=int
index=6,type=float
index=7,type=double
endbody
body=2
function=0xb2
index=1,type=unsigned char
index=2,type=unsigned short
index=3,type=unsigned int
index=4,type=short
index=5,type=int
index=6,type=float
index=7,type=double
endbody
body=3
function=0xb3
index=1,type=unsigned char
index=2,type=unsigned short
index=3,type=unsigned int
index=4,type=short
index=5,type=int
index=6,type=float
index=7,type=double
endbody
check=crc-ccitt
-----end file-----

模拟下位机发送数据

  为了方便分析,这里使用虚拟串口助手在电脑上模拟出两个串口端口

多功能嵌入式解码软件

编写软件模拟下位机按照协议发送数据

多功能嵌入式解码软件

多功能嵌入式解码软件

类库使用方法

读取协议文件

 1 private void buttonreadprotocol_click(object sender, routedeventargs e)
 2         {
 3             string[] txtread = new string[2];
 4 
 5             txtread = selected_txt();
 6             if (txtread == null)
 7                 return;
 8             textboxsettinglog.appendtext(txtread[0] + "\r\n");
 9             s.pro_read = txtread[1];
10             c_f.process_protocol_readed(s.pro_read);
11             if (c_f.protocolfresh == true)
12                 textboxsettinglog.appendtext(c_f.framemsg);
13         }

保存解码数据

/// <summary>
        /// 2019-05-06
        /// </summary>
        private void savedecodedat()
        {
            string strpath = environment.currentdirectory;
            list<class_frame._savedecodestruct> re = new list<class_frame._savedecodestruct>();
            re = c_f.savedecodedat(listsprxddat);
            for (int i = 0; i < re.count; i++)
            {
                byte id = re[i].function;
                string str = re[i].str;
                string strfile = strpath + "\\doc\\" + datetime.now.tostring("yy-mm-dd-hh.mm.ss") + "dec" + convert.tostring(id, 16) + ".txt";
                if (re[0].str != null)
                    savestring(str, strfile, filemode.create);
                else
                    messagebox.show("null");
            }
        }

 

实时解码数据

 1 /// <summary>
 2         /// 2019-05-07
 3         /// </summary>
 4         private void decode_header_function_sum8()
 5         {
 6             class_frame._decodedattimelystruct re = new class_frame._decodedattimelystruct();
 7             int cnt = listsprxddat.count();
 8 
 9             while (s.dec_lastcnt < cnt)
10             {
11                 re = c_f.decodetimely(listsprxddat[s.dec_lastcnt++]);
12                 list<object> l = re.listre;
13                 byte id = re.function;
14                 if (l != null)
15                 {
16                     byte ui8;
17                     uint16 ui16;
18                     uint32 ui32;
19                     int16 i16;
20                     int32 i32;
21                     float f;
22                     double d;
23 
24                     switch (id)
25                     {
26                         case 0xb1:
27                             {
28                                 ui8 = (byte)l[0];
29                                 ui16 = (uint16)l[1];
30                                 ui32 = (uint32)l[2];
31                                 i16 = (int16)l[3];
32                                 i32 = (int32)l[4];
33                                 f = (float)l[5];
34                                 d = (double)l[6];
35                                 textboxrxd.appendtext("--------0xb1\r\n");
36                                 textboxrxd.appendtext(ui8.tostring() + " ");
37                                 textboxrxd.appendtext(ui16.tostring() + " ");
38                                 textboxrxd.appendtext(ui32.tostring() + " ");
39                                 textboxrxd.appendtext(i16.tostring() + " ");
40                                 textboxrxd.appendtext(i32.tostring() + " ");
41                                 textboxrxd.appendtext(f.tostring() + " ");
42                                 textboxrxd.appendtext(d.tostring() + " ");
43                                 textboxrxd.appendtext("\r\n");
44                             }
45                             break;
46                         case 0xb2:
47                             {
48                                 ui8 = (byte)l[0];
49                                 ui16 = (uint16)l[1];
50                                 ui32 = (uint32)l[2];
51                                 i16 = (int16)l[3];
52                                 i32 = (int32)l[4];
53                                 f = (float)l[5];
54                                 d = (double)l[6];
55                                 textboxrxd.appendtext("--------0xb2\r\n");
56                                 textboxrxd.appendtext(ui8.tostring() + " ");
57                                 textboxrxd.appendtext(ui16.tostring() + " ");
58                                 textboxrxd.appendtext(ui32.tostring() + " ");
59                                 textboxrxd.appendtext(i16.tostring() + " ");
60                                 textboxrxd.appendtext(i32.tostring() + " ");
61                                 textboxrxd.appendtext(f.tostring() + " ");
62                                 textboxrxd.appendtext(d.tostring() + " ");
63                                 textboxrxd.appendtext("\r\n");
64                             }
65                             break;
66                         case 0xb3:
67                             {
68                                 ui8 = (byte)l[0];
69                                 ui16 = (uint16)l[1];
70                                 ui32 = (uint32)l[2];
71                                 i16 = (int16)l[3];
72                                 i32 = (int32)l[4];
73                                 f = (float)l[5];
74                                 d = (double)l[6];
75                                 textboxrxd.appendtext("--------0xb3\r\n");
76                                 textboxrxd.appendtext(ui8.tostring() + " ");
77                                 textboxrxd.appendtext(ui16.tostring() + " ");
78                                 textboxrxd.appendtext(ui32.tostring() + " ");
79                                 textboxrxd.appendtext(i16.tostring() + " ");
80                                 textboxrxd.appendtext(i32.tostring() + " ");
81                                 textboxrxd.appendtext(f.tostring() + " ");
82                                 textboxrxd.appendtext(d.tostring() + " ");
83                                 textboxrxd.appendtext("\r\n");
84                             }
85                             break;
86                         default:
87                             textboxrxd.appendtext("frame id err\r\n");
88                             break;
89                     }
90                 }
91             }
92         }

在uarttool中使用类库

  读取协议文件,协议文件的信息会在textbox框中显示出来。

多功能嵌入式解码软件

如下图模拟下位机软件开始向上位机发送数据

多功能嵌入式解码软件

uarttool打开串口,点击保存数据和解码数据会把原始数据和解码后的数据保存下来

多功能嵌入式解码软件

多功能嵌入式解码软件

 解码后的数据如图,和发送的一致。

多功能嵌入式解码软件