精华内容
下载资源
问答
  • DBC文件解析

    2021-01-07 14:28:15
    这里写自定义目录标题1、基础介绍2、DBC文件2.1、开头是Version 和 new_symbols两个Tag。2.2、波特率定义2.3、网络节点的定义2.4、报文帧的定义2.5、信号的定义2.6、注解部分2.7、特征(属性)定义部分:2.8、数值表...
  • DBC文件解析CAN信息》由会员分享,可在线阅读,更多相关《DBC文件解析CAN信息(15页珍藏版)》请在人人文库网上搜索。1、DBCCAN数据包-基于CANAPE,打开CANape,新建一个工程,如右图所示,如图示过程,建立新的...

    《DBC文件解析CAN信息》由会员分享,可在线阅读,更多相关《DBC文件解析CAN信息(15页珍藏版)》请在人人文库网上搜索。

    1、DBCCAN数据包-基于CANAPE,打开CANape,新建一个工程,如右图所示,如图示过程,建立新的project(例如名称为demo),存储路径自行定义。点击“完成”后,弹出的提示信息点击“确定”或“ok”跳过,进入CANape主界面,上图为CANape主界面。可以把已有的dbc文件最后放到工程的路径下,在“Device”中选择“New from database,找到放在工程路径下的.dbc文件,导入。此时上图红色框位置由灰色变为蓝色,说明成功导入,点击上述变为蓝色的按钮,弹出.dbc文件中包含的信息,如下图所示,Message下为各帧信息,Signals子目录下为所有的信号,各信号需要。

    2、在Signals下面定义好。如需增加,可以在空白处点击鼠标右键,New,新建信号,根据通讯协议定义好信号的名称,长度,偏移量,缩放因子等参数,双击Message下某一帧,弹出如图示对话框,可以在definition中定义 数据帧名称,类型,ID,长度等,在Signals下可以为数据帧添加所需 包含的且已经在Signals下定义好的信号,在Layout下可以为某一帧信息中各信号的存储位置,存储方式进行自定义,要观测信号,可在主界面右键,在Display windows中选择显示的方式, 如图形,数显等,以图形显示(Graphic window)为例,如图示,加入.dbc文件中包含的 数据帧或信号,如图,选择一帧信号的全部或是某些,点击Apply,点击Apply,即可以图形的形式观测相关的信号变化情况,谢谢。

    展开全文
  • DBC文件解析CAN信息.ppt

    2021-09-15 20:10:27
    DBC文件解析CAN信息.ppt
  • CAN通讯进阶-基于Python使用DBC文件解析CAN数据配置环境1.环境配置1.1安装CAN通讯需要的包1.2 安装kvaser_drivers以及Kvaser CanKing2.使用DBC文件解析CAN帧2.1DBC文件2.2本博客布局3.DBC文件的创建3.1创建DBC文件...

    配置环境

    使用环境:python3.6
    平台:Windows10
    IDE:PyCharm

    1.环境配置

    1.1安装CAN通讯需要的包

    pip install canlib
    

    1.2 安装kvaser_drivers以及Kvaser CanKing

    这些软件可以在官网下载https://www.kvaser.com/download/

    官网是英文的,看起来可能有点吃力,这里也给出云盘连接:
    链接:https://pan.baidu.com/s/1LDKyIlOV0Ky4d2qxryLZGQ
    提取码:vwiv

    下载下来之后的文件是这样的,三个文件依次双击安装就行了

    在这里插入图片描述
    安装完后,在开始栏可以查看到已经安装好了
    在这里插入图片描述

    2.使用DBC文件解析CAN帧

    2.1DBC文件

    DBC是Database Can的缩写,其代表的是CAN的数据库文件,在这个文件中把CAN通讯的信息定义的非常完整清楚,在Windows下其存在的格式便是dbc,如图所示:
    在这里插入图片描述
    有了DBC文件便可以对接收到的CAN帧进行解析,分析一系列CAN帧代表的真实物理含义。
    正因为如此,每一个DBC文件都对应着一种CAN帧的规则,使用CAN作为通讯手段的设备(如汽车中发动机、车灯、车载空调等等)都有对应的DBC文件。

    2.2本博客布局

    本博客将从DBC文件的创建、使用DBC文件发送指定格式的CAN数据、使用DBC文件解析接收到的CAN数据来展开。

    3.DBC文件的创建

    3.1创建DBC文件代码

    # author:Hurricane
    # date:  2021/4/16
    # File : CAN_Create_Database.py 
    # E-mail:hurri_cane@qq.com
    
    
    
    import argparse
    from collections import namedtuple
    
    from canlib import kvadblib
    
    Message = namedtuple('Message', 'name id dlc signals')
    Signal = namedtuple('Signal', 'name size scaling limits unit')
    EnumSignal = namedtuple('EnumSignal', 'name size scaling limits unit enums')
    
    _messages = [
    	Message(
    		name='EngineData',
    		id=100,
    		dlc=8,
    		signals=[
    			Signal(
    				name='PetrolLevel',
    				size=(24, 8),
    				scaling=(1, 0),
    				limits=(0, 255),
    				unit="l",
    			),
    			Signal(
    				name='EngPower',
    				size=(48, 16),
    				scaling=(0.01, 0),
    				limits=(0, 150),
    				unit="kW",
    			),
    			Signal(
    				name='EngForce',
    				size=(32, 16),
    				scaling=(1, 0),
    				limits=(0, 0),
    				unit="N",
    			),
    			EnumSignal(
    				name='IdleRunning',
    				size=(23, 1),
    				scaling=(1, 0),
    				limits=(0, 0),
    				unit="",
    				enums={'Running': 0, 'Idle': 1},
    			),
    			Signal(
    				name='EngTemp',
    				size=(16, 7),
    				scaling=(2, -50),
    				limits=(-50, 150),
    				unit="degC",
    			),
    			Signal(
    				name='EngSpeed',
    				size=(0, 16),
    				scaling=(1, 0),
    				limits=(0, 8000),
    				unit="rpm",
    			),
    		]),
    	Message(
    		name='GearBoxInfo',
    		id=1020,
    		dlc=1,
    		signals=[
    			Signal(
    				name='EcoMode',
    				size=(6, 2),
    				scaling=(1, 0),
    				limits=(0, 1),
    				unit="",
    			),
    			EnumSignal(
    				name='ShiftRequest',
    				size=(3, 1),
    				scaling=(1, 0),
    				limits=(0, 0),
    				unit="",
    				enums={'Shift_Request_On': 1, 'Shift_Request_Off': 0},
    			),
    			EnumSignal(
    				name='Gear',
    				size=(0, 3),
    				scaling=(1, 0),
    				limits=(0, 5),
    				unit="",
    				enums={
    					'Idle': 0,
    					'Gear_1': 1,
    					'Gear_2': 2,
    					'Gear_3': 3,
    					'Gear_4': 4,
    					'Gear_5': 5,
    				},
    			),
    		]),
    ]
    
    
    def create_database(name, filename):
    	db = kvadblib.Dbc(name=name)
    
    	for _msg in _messages:
    		message = db.new_message(
    			name=_msg.name,
    			id=_msg.id,
    			dlc=_msg.dlc,
    		)
    
    		for _sig in _msg.signals:
    			if isinstance(_sig, EnumSignal):
    				_type = kvadblib.SignalType.ENUM_UNSIGNED
    				_enums = _sig.enums
    			else:
    				_type = kvadblib.SignalType.UNSIGNED
    				_enums = {}
    			message.new_signal(
    				name=_sig.name,
    				type=_type,
    				byte_order=kvadblib.SignalByteOrder.INTEL,
    				mode=kvadblib.SignalMultiplexMode.MUX_INDEPENDENT,
    				size=kvadblib.ValueSize(*_sig.size),
    				scaling=kvadblib.ValueScaling(*_sig.scaling),
    				limits=kvadblib.ValueLimits(*_sig.limits),
    				unit=_sig.unit,
    				enums=_enums,
    			)
    
    	db.write_file(filename)
    	db.close()
    
    
    if __name__ == '__main__':
    	parser = argparse.ArgumentParser(
    		description="Create a database from scratch.")
    	parser.add_argument('--filename', default=r'..\engine_example.dbc', help=(
    		"The filename to save the database to."))
    	parser.add_argument('-n', '--name', default='Engine example', help=(
    		"The name of the database (not the filename, the internal name."))
    	args = parser.parse_args()
    
    	create_database(args.name, args.filename)
    
    
    

    3.2使用方法

    代码中if __name__ == '__main__':下:

    parser.add_argument('--filename', default=r'..\engine_example.dbc', help=(
    		"The filename to save the database to."))
    

    指定的filename为创建的DBC文件的路径以及文件名,本代码中便是将DBC文件存在代码所在目录的上层目录中,以engine_example.dbc文件名保存

    代码中_messages列表
    在这里插入图片描述
    便是定义CAN帧解析的规则,可以定义:

    • CAN帧的id

    • CAN帧的数据长度

    • CAN帧的解析single规则
      等等…

      创建方式如下:

    在这里插入图片描述

    4.DBC文件发送指定格式的CAN数据

    4.1DBC文件发送指定格式的CAN数据代码

    # author:Hurricane
    # date:  2021/4/12
    # File : CAN_Random_Send.py 
    # E-mail:hurri_cane@qq.com
    
    import argparse
    import time
    import random
    
    from canlib import canlib, kvadblib
    
    
    bitrates = {
        '1M': canlib.canBITRATE_1M,
        '500K': canlib.canBITRATE_500K,
        '250K': canlib.canBITRATE_250K,
        '125K': canlib.canBITRATE_125K,
        '100K': canlib.canBITRATE_100K,
        '62K': canlib.canBITRATE_62K,
        '50K': canlib.canBITRATE_50K,
        '83K': canlib.canBITRATE_83K,
        '10K': canlib.canBITRATE_10K,
    }
    
    
    # 随机在dbc结构中抽取一个结构
    def set_random_framebox_signal(db, framebox, signals):
        sig = random.choice(signals)
        value = get_random_value(db, sig)
        framebox.signal(sig.name).phys = value
    
    # 随机在抽取到的结构帧的数值范围中产生一个值
    def get_random_value(db, sig):
        limits = sig.limits
        value = random.uniform(limits.min, limits.max)
    
        # round value depending on type...
        if (
                sig.type is kvadblib.SignalType.UNSIGNED or
                sig.type is kvadblib.SignalType.SIGNED
        ):
            # ...remove decimals if the signal was of type unsigned
            value = int(round(value))
        else:
            # ...otherwise, round to get only one decimal
            value = round(value, 1)
    
        return value
    
    
    def ping_loop(channel_number, db_name, num_messages, quantity, interval, bitrate, seed=0):
        db = kvadblib.Dbc(filename=db_name)
    
        ch = canlib.openChannel(channel_number, canlib.canOPEN_ACCEPT_VIRTUAL)
        ch.setBusOutputControl(canlib.canDRIVER_NORMAL)
        ch.setBusParams(bitrate)
        ch.busOn()
    
        random.seed(seed)
    
        if num_messages == -1:
            # used_messages为dbc文件定义的所有帧结构
            used_messages = list(db)
        else:
            used_messages = random.sample(list(db), num_messages)
    
        print()
        print("Randomly selecting signals from the following messages:")
        print(used_messages)
        print("Seed used was " + repr(seed))
        print()
    
        while True:
            # Create an empty framebox each time, ignoring previously set signal
            # values.
            framebox = kvadblib.FrameBox(db)
    
            # Add all messages to the framebox, as we may use send any signal from
            # any of them.
            for msg in db:
                framebox.add_message(msg.name)
    
            # Make a list of all signals (which framebox has found in all messages
            # we gave it), so that set_random_framebox_signal() can pick a random
            # one.
            signals = [bsig.signal for bsig in framebox.signals()]
    
            # Set some random signals to random values
            for i in range(quantity):
                set_random_framebox_signal(db, framebox, signals)
    
            # Send all messages/frames
            for frame in framebox.frames():
                print('Sending frame', frame)
                ch.writeWait(frame, timeout=5000)
    
            time.sleep(interval)
    
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(
            description="Send random CAN message based on a database.")
        parser.add_argument('channel', type=int, default=0, nargs='?', help=(
            "The channel to send messages on."))
        parser.add_argument('--bitrate', '-b', default='500k', help=(
            "Bitrate, one of " + ', '.join(bitrates.keys())))
        parser.add_argument('--db', default="../Mobileye.dbc", help=(
            "The database file to base messages on."))
        parser.add_argument('-Q', '--quantity', type=int, default=5, help=(
            "The number of signals to send each tick."))
        parser.add_argument('-I', '--interval', type=float, default=0.2, help=(
            "The time, in seconds, between ticks."))
        parser.add_argument('-n', '--num-messages', type=int, default=-1, help=(
            "The number of message from the database to use, or -1 to use all."))
        parser.add_argument('-s', '--seed', nargs='?', default='0', help=(
            "The seed used for choosing messages. If possible, will be converted to an int. If no argument is given, a random seed will be used."))
        args = parser.parse_args()
    
        if args.seed is None:
            seed = None
        else:
            try:
                seed = int(args.seed)
            except ValueError:
                seed = args.seed
    
        ping_loop(
            channel_number=args.channel,
            db_name=args.db,
            num_messages=args.num_messages,
            quantity=args.quantity,
            interval=args.interval,
            bitrate=bitrates[args.bitrate.upper()],
            seed=args.seed,
        )
    
    

    4.2使用方法

    这份代码的功能为:
    以DBC文件规定的数据格式,随机发送一些数据帧出去

    代码中if __name__ == '__main__':下:

        parser.add_argument('--db', default="../Mobileye.dbc", help=(
            "The database file to base messages on."))
    

    指定的filename为读取的DBC文件的路径,本代码中读取的DBC文件存在代码所在目录的上层目录中,以Mobileye.dbc文件名存在

    PS:这里面的DBC文件也可以改为3.1创建DBC文件代码中生成的engine_example.dbc文件

    此处附上两个DBC文件的云盘链接

    链接:https://pan.baidu.com/s/1JAT2o2fPzto8555qU-lVKg
    提取码:49bv

    为了测试发送数据是否成功,采用上篇博客2.2.1使用Kvaser Can King接收数据中的方法。链接如下:
    https://blog.csdn.net/ShakalakaPHD/article/details/115767739

    运行4.1代码:
    在这里插入图片描述

    可以看到Kvaser Can King接收到各式各样的数据,但是其中的具含义我们并不清楚,这边涉及到第5节,使用DBC文件解析接收到的CAN帧。

    5.使用DBC文件解析接收到的CAN数据

    5.1使用DBC文件解析接收到的CAN数据代码

    # author:Hurricane
    # date:  2021/4/16
    # File : CAN_Using_Database.py
    # E-mail:hurri_cane@qq.com
    
    import argparse
    
    from canlib import canlib, kvadblib
    
    
    bitrates = {
        '1M': canlib.canBITRATE_1M,
        '500K': canlib.canBITRATE_500K,
        '250K': canlib.canBITRATE_250K,
        '125K': canlib.canBITRATE_125K,
        '100K': canlib.canBITRATE_100K,
        '62K': canlib.canBITRATE_62K,
        '50K': canlib.canBITRATE_50K,
        '83K': canlib.canBITRATE_83K,
        '10K': canlib.canBITRATE_10K,
    }
    
    
    def printframe(db, frame):
        try:
            bmsg = db.interpret(frame)
        except kvadblib.KvdNoMessage:
            print("<<< No message found for frame with id %s >>>" % frame.id)
            return
    
        msg = bmsg._message
    
        # form = '═^' + str(width)
        # print(format(" %s " % msg.name, form))
    
        print('┏', msg.name)
    
        if msg.comment:
            print('┃', '"%s"' % msg.comment)
    
        for bsig in bmsg:
            print('┃', bsig.name + ':', bsig.value, bsig.unit)
    
        print('┗')
    
    
    def monitor_channel(channel_number, db_name, bitrate, ticktime):
        db = kvadblib.Dbc(filename=db_name)
    
        ch = canlib.openChannel(channel_number, canlib.canOPEN_ACCEPT_VIRTUAL)
        ch.setBusOutputControl(canlib.canDRIVER_NORMAL)
        ch.setBusParams(bitrate)
        ch.busOn()
    
        timeout = 0.5
        tick_countup = 0
        if ticktime <= 0:
            ticktime = None
        elif ticktime < timeout:
            timeout = ticktime
    
        print("Listening...")
        while True:
            try:
                frame = ch.read(timeout=int(timeout * 1000))
                printframe(db, frame)
            except canlib.CanNoMsg:
                if ticktime is not None:
                    tick_countup += timeout
                    while tick_countup > ticktime:
                        print("tick")
                        tick_countup -= ticktime
            except KeyboardInterrupt:
                print("Stop.")
                break
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(
            description="Listen on a CAN channel and print all signals received, as specified by a database.")
        parser.add_argument('channel', type=int, default=1, nargs='?', help=(
            "The channel to listen on."))
        parser.add_argument('--db', default="../Mobileye.dbc", help=(
            "The database file to look up messages and signals in."))
        parser.add_argument('--bitrate', '-b', default='500k', help=(
            "Bitrate, one of " + ', '.join(bitrates.keys())))
        parser.add_argument('--ticktime', '-t', type=float, default=0, help=(
            "If greater than zero, display 'tick' every this many seconds"))
        args = parser.parse_args()
    
        monitor_channel(args.channel, args.db, bitrates[args.bitrate.upper()], args.ticktime)
    
    

    5.2使用方法

    代码中if __name__ == '__main__':下:

        parser.add_argument('--db', default="../Mobileye.dbc", help=(
            "The database file to look up messages and signals in."))
    

    指定的filename为读取的DBC文件的路径,本代码中读取的DBC文件存在代码所在目录的上层目录中,以Mobileye.dbc文件名存在

    PS:这里面的DBC文件也可以改为3.1创建DBC文件代码中生成的engine_example.dbc文件

    为了测试解析数据是否有效,采用此博客中4.DBC文件发送指定格式的CAN数据节下的随机发送数据的代码发送数据。

    运行4.1节代码后,再运行5.1节代码来解析数据:

    在这里插入图片描述
    可以看到相较于Kvaser Can King接收到各式各样的数据,使用DBC文件解析后的数据都已准换为了真实的物理含义:
    在这里插入图片描述

    6.参考文献

    Python Canlib Documentation
    file:///D:/Program%20Files%20(x86)/kvaserCAN/canlib/python/pycanlib/docs/index.html

    7.结束语

    如果本文对你有帮助的话还请点赞、收藏一键带走哦,你的支持是我最大的动力!(づ。◕ᴗᴗ◕。)づ
    在这里插入图片描述

    展开全文
  • DBC文件解析,基于致远电子DBC_demo

    万次阅读 热门讨论 2018-10-19 14:49:50
    致远电子官网上有DBC文件解析的demo,不过是用C++做的,我就用C#和致远电子提供的LibDBCManager.dll做了一个小软件。 大学的时候也学过C++,好长时间没看过了,而且感觉当时完全没学好,云里雾里的。致远电子网上...

    致远电子官网上有DBC文件解析的demo,不过是用C++做的,我就用C#和致远电子提供的LibDBCManager.dll做了一个小软件。

    大学的时候也学过C++,好长时间没看过了,而且感觉当时完全没学好,云里雾里的。致远电子网上还有一个can数据收发的demo,有C#的例子,那我想就参考这个例子用C#做个DBC解析的软件好了,反正公司的软件也是用C#做的。

    其实LibDBCManager.dll已经做好解析功能了,只要调用提供的接口就行了。

    首先要定义结构体,首先是  DBCSignal和DBCMessage。

    public struct DBCSignal
        {
            public UInt32 nStartBit;//起始位
            public UInt32 nLen;//位长度
            public Double nFactor;//转换因子
            public Double nOffset;//转换偏移 实际值=原始值*nFactor+nOffset
            public Double nMin;    // 最小值
            public Double nMax;    // 最大值
            public Double nValue;  //实际值
            public UInt64 nRawValue;//原始值 
            public Byte is_signed; //1:有符号数据, 0:无符号
            public Byte is_motorola;//是否摩托罗拉格式
            public Byte multiplexer_type;//see 'multiplexer type' above
            public Byte multiplexer_value;
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
            public Byte[] unit;
    
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
            public Byte[] strName;
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 201)]
            public Byte[] strComment;
    
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
            public Byte[] strValDesc;
        }
    
    public struct DBCMessage
        {
    
            public UInt32 nSignalCount; //信号数量
            public UInt32 nID;
            public Byte nExtend; //1:扩展帧, 0:标准帧
            public UInt32 nSize;   //消息占的字节数目
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
            public DBCSignal[] vSignals; //信号集合
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
            public byte[] strName;
    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 201)]
            public byte[] strComment;
        }

    让人讨厌的就是C++和C#数据类型对应的问题,网上有对应的表。C++中BOOL对应C#中BYTE。

    数组要用[MarshalAs(UnmanagedType.ByValArray, SizeConst = 201)]限定数组长度,或者用 public fixed  byte  XXXX[n];

    接下来是接口函数定义

            [DllImport("LibDBCManager.dll")]
            static extern Int32 DBC_Init();
            [DllImport("LibDBCManager.dll")]
            static extern void DBC_Release(UInt32 hDBChandle);
            [DllImport("LibDBCManager.dll")]
            static extern bool DBC_LoadFile(Int32 hDBC, ref FileInfo fileinfo);
    
            [DllImport("LibDBCManager.dll")]
            static extern bool DBC_GetFirstMessage(Int32 hDBC, IntPtr pMsg);
           
            [DllImport("LibDBCManager.dll")]
            static extern bool DBC_GetNextMessage(Int32 hDBC, IntPtr pMsg);
    
            [DllImport("LibDBCManager.dll")]
            static extern bool DBC_GetMessageById(UInt32 hDBC, UInt32 nID, ref DBCMessage pMsg);
            [DllImport("LibDBCManager.dll")]
            static extern UInt32 DBC_GetMessageCount(Int32 hDBC);
    
            //此函数用以解析帧数据,返回解析结果.返回值为 true 表示解析成功, false 表示失败。
            [DllImport("LibDBCManager.dll")]
            static extern bool DBC_Analyse(UInt32 hDBC, IntPtr pOb, ref DBCMessage pMsg);
    
            //用户需要调用该函数把接收到的帧数据传进来, 涉及多帧传输必须要调用, 否则无法实
            //现报文交互, 可以实现为接收到每一个帧都调用该函数一次。
            [DllImport("LibDBCManager.dll")]
            static extern void DBC_OnReceive(UInt32 hDBC, IntPtr pObj);
    
            //此函数用以设置实际发送数据的回调函数, 涉及数据发送时必须设置,只需要设置一次
            [DllImport("LibDBCManager.dll")]
            static extern void DBC_SetSender(Int32 hDBC, Onsend sender, IntPtr ctx);
    
            //
            [DllImport("LibDBCManager.dll")]
            static extern void DBC_SetOnMultiTransDoneFunc(UInt32 hDBC, OnMultiTransDone func, IntPtr ctx);
    
            [DllImport("LibDBCManager.dll")]
            static extern bool DBC_Send(UInt32 hDBC, ref DBCMessage pMsg);

    好久才搞明白接口函数中C++指针在C#中应该怎么写。参考https://blog.csdn.net/liguo9860/article/details/37043911,讲的很明白。

    调用的时候先定义指针开辟处结构体大小的内存。如

    IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DBCMessage)));

    这样pt就指向DBCMessage结构大小的内存了。

    调用

    DBC_GetFirstMessage(m_hDBC,pt)

    就把pt指向的内存填充了。如果在定义结构体的时候数据类型用的不对,就会发生错误,比如把C++中BOOL量对应成C#中bool量了,C#中BOOL量好像占4个字节,而C++中bool量占1个字节,接口函数在填充的时候会把下一个字段的内容放在bool量的后三个字节中,然后这字段又被其他内容填充,就混乱了。

    内存被填充后再用Marshal.PtrToStructure转换为结构体

    DBCMessage msg = (DBCMessage)Marshal.PtrToStructure(pt, typeof(DBCMessage));

    这样就得到DBC文件里的消息了。

    还有个问题就是释放资源,用参考的博文的方法,有的消息没有注释解析出来却和上一个消息的注释一样,调试的时候发现应该是pt指针指向的内存没有被释放,就算用参考博文的方法释放还是一样的现象。可能是释放的时候没有清零,再创建指针的时候内存还是上一个消息的数据,这个消息没有注释就不能改写内存里的注释。后来用Marshal.DestroyStructure解决了,我也不知道啥原因。

           在ZLG给的can数据收发的demo上加一个按钮

    点击按钮实例化一个FrmDBC的对象。

    FrmDBC frmDBC = new FrmDBC();
                frmDBC.Show();

    frmDBC加载

    的时候(有初始化的语句):

     private void FrmDBC_Load(object sender, EventArgs e)
            {
                 m_hDBC = DBC_Init();
                if (m_hDBC==-1)
                {
                    MessageBox.Show("生成DBC句柄失败");
                }
                //Marshal.
                m_ctx.powner = this.Handle;
                m_ctx.devinfo = m_devInfo;
    
                IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Ctx)));
    
                DBC_SetSender(m_hDBC, onsend, pt);
    
                //DBC_SetOnMultiTransDoneFunc(m_hDBC, OnMultiTransDone, pt);
            }

    frmDBC的UI是这个样子的,

    点“加载协议”按钮的代码:

     unsafe   private void btnLoadDBC_Click(object sender, EventArgs e)
            {
                openFileDialogDBC.InitialDirectory = @"C:\Users\pechc\Desktop";
                openFileDialogDBC.Filter = "DBC文件|*.dbc";
                openFileDialogDBC.RestoreDirectory = true  ;// *如果值为false,那么下一次选择文件的初始目录是上一次你选择的那个目录,
                openFileDialogDBC.FilterIndex = 1;
                if (openFileDialogDBC .ShowDialog() == DialogResult.OK)
                {
                    filename = openFileDialogDBC .FileName;
                    string strFile = Path.GetFullPath(openFileDialogDBC.FileName);//不能只取得路径
                    if (strFile==null)
                    {
                        MessageBox.Show("路径为空");
                        return;
                    }
                    FileInfo fileInfo;
                    byte[] str = System.Text.Encoding.Default.GetBytes(strFile);
                    Marshal.Copy(str, 0, (IntPtr)fileInfo.strFilePath, str.Length);
                    //Marshal.StructureToPtr(str, (IntPtr)fileInfo.strFilePath, true);
                   
    
                    fileInfo.nType = ProtocolType.DBC_CAN;
                    fileInfo.merge = 0;
    
                   // IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileInfo)));
    
                   // Marshal.StructureToPtr(fileInfo ,)
    
                    if (!DBC_LoadFile(m_hDBC,ref fileInfo))
                    {
                        MessageBox.Show("加载文件错误");
                        return;
                    }
                    uint nCount = DBC_GetMessageCount(m_hDBC);
                    if (DBC_GetMessageCount(m_hDBC)==0)
                    {
                        MessageBox.Show("文件中不含有消息");
                    }
                    ReadAllMessage();
                }
            }

    最后看一看效果吧!

    界面
    界面

    关于这个软件的问答

    https://ask.csdn.net/questions/702321

    https://ask.csdn.net/questions/702976

    生成的软件

    https://download.csdn.net/download/liulangdelangzi/10732030

    源代码

    https://download.csdn.net/download/liulangdelangzi/11237538

    展开全文
  • Labview 用DBC文件解析CAN报文以及DBC格式发送CAN 载入DBC格式文件,解析数据,修改后可以发送,调用的dll有使用说明。 参考程序后续可以自己改动 复制这条消息后,打开闲鱼€1y5gcYErL74€后打开闲鱼 ...

    Labview 用DBC文件解析CAN报文以及DBC格式发送CAN

    载入DBC格式文件,解析数据,修改后可以发送,调用的dll有使用说明。
    参考程序后续可以自己改动
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    程序代码包括CAN通讯部分和CAN解析两部分。

    只需一包烟,可节约大量开发时间,可复制这条消息后€BDGqcWRUsHD€,打开闲鱼获得例程。

    文件里包含2013版demo,2016版以及2019版。包含不同版本的dll调用解析说明。

    闲鱼搜不到的话可加我VX:L201467。

    在这里插入图片描述

    展开全文
  • DBC文件解析 ——基于DBCView工具

    千次阅读 2018-01-22 11:44:10
    DBC文件解析 ——基于DBCView工具 1)DBC解析---网络节点 DBC是描述CAN网络节点间的数据通讯的文件: 例如下面的3.dbc文件,包括了6个节点连接在CAN网络上 2)DBC解析---节点收发MSG dbc文件中会为每个节点定义...
  • DBC文件解析——基于DBCVIew3.1(中文版) DBCView由5个部分构成:1)菜单和工具。2)树状图。3)拓扑图。4)细节描述区。5)属性区。 拓扑图是主要区间,我们以拓扑图来解析dbc文件。 1)DBC解析—网络节点 如图...
  • 环境:操作系统。 语言:C++/C# 版本:V1.04。 描述:CAN、DBC解析与收发、多帧传输。 详情:周立功官方的DBC解析模块接口案例。
  • DBC文件解析——基于DBCView工具

    千次阅读 2018-01-22 11:22:19
    汽车电子少不了使用dbc文件,这里我们用DBCView这个工具来解析DBC文件 ——基于DBCView工具 DBCView由5个部分构成:1)菜单和工具。2)树状图。3)拓扑图。4)属性区。5)细节描述区。 拓扑图是主要区间,...
  • 软件介绍: 一款用于解析DBC文件的小工具,这个最新的1.0版,希望各位提供建议。使用时需要扫描二维码才能使用。
  • CANas分析软件,DBC文件解析,仿CANoe曲线显示

    千次阅读 热门讨论 2020-09-12 14:56:32
    1、CAN连接,支持周立功CAN及PCAN ...2、DBC解析与生成 3、历史报文解析,支持asc,csv,blf等格式 4、曲线生成,仿CANOE的曲线显示 下载地址:https://download.csdn.net/download/amw2738/12833259
  • 关于DBC文件的格式解析DBC文件系列其二)

    万次阅读 多人点赞 2019-04-04 19:15:07
    关于DBC文件解析摘要创建步骤1、新建一个CAN数据库文件2、创建信号要用到的数值表Value Tables3、创建信号Signals,关联该信号的数值表4、创建报文Messages5、创建网络节点Network nodes6、将信号、报文及网络节点...
  • DBC文件源码解析

    千次阅读 2020-03-16 19:04:39
    DBC文件源码解析   DBC(data base CAN)文件是由德国Victor公司发布的,它被用来描述单一CAN网络中各逻辑节点信息,依据该文件可以开发出来监视和分析CAN网络中所有逻辑节点的运行状态。DBC是一种文件格式,.dbc...
  • JAVA解析DBC文件

    2019-04-17 20:39:59
    用JAVA解析DBC文件,考虑大小端,生成文件内容跟Vector CANDB++相同。
  • 功能:读取DBC文件,将Bo_、SG_解析封装到实体类里,方便下一步的开发。
  • DBC文件格式解析

    2020-08-30 13:31:12
    DBC文件描述了单个网络节点的通信信息。这些信息可以监测分析网络以及模拟网络节点。 2.基础定义 对象类型: Network : Node: Message: 符号 关键字 BU_ 网络节点 BO_ 消息、报文 SG_ 信号 EV_ ...
  • 解析dbc文件

    2018-05-07 17:38:39
    简洁明了,可以为相关人员提供一个解析文件的思路,没有复杂的代码,比较容易理解
  • 关于DBC文件的格式解析(转)

    千次阅读 2019-08-31 17:31:54
    如上图所示,一般dbc文件中包含了如下的8种信息: 1、版本与新符号 2、波特率定义 ...接下来我们结合例子对dbc文件的这几项信息进行逐步解析介绍。 1、版本与新符号 如下图,Dbc文件头部包含着”v...
  • 【DBC专题】-5-DBC文件格式解析

    千次阅读 热门讨论 2020-12-23 20:44:38
    0 DBC文件中“符号字符串”命名要求 1 DBC文件的标头 1 Bit Timing波特率定义 2 Node节点定义 3 Value Table值表定义 4 Message消息定义 4.1 标准帧Message定义举例 4.2 扩展帧Message定义举例 5 Signal信号...
  • 1.可以根据DBC文件自动解析实时收发的CAN数据 2.可以把cantest软件保存的CAN数据(txt文件)进行解析后导出保存 3.可以自定义选取某个帧内容显示实时曲线 4.可以保存已接收的数据帧 5.可以主动发送单个数据或导入文件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,519
精华内容 1,007
关键字:

dbc文件解析