<sub id="znbjl"><var id="znbjl"><output id="znbjl"></output></var></sub>
      <sub id="znbjl"><var id="znbjl"><ins id="znbjl"></ins></var></sub>
        <sub id="znbjl"></sub>

      <address id="znbjl"><dfn id="znbjl"></dfn></address>

            <address id="znbjl"><dfn id="znbjl"></dfn></address>

            <thead id="znbjl"><var id="znbjl"><ins id="znbjl"></ins></var></thead>

            空燃比分析仪,horiba尾气分析仪,CAN总线分析仪,CAN数据记录仪

            广州智维电子科技有限公司

            Guangzhou Triv Electronic Technologies Co.LTD

            行业应用
            APPLICATION

            目前位置: 首页 > 行业应用 > Kvaser分析仪

            2022-11-22

            应用技巧 | 怎样连接到特定的CAN通道

            作者:Triv    点击:83

            用户常问:是否能让我的电脑总是以相同的顺序启动我的Kvaser接口?很遗憾,答案是否定的。但我们可以通过一个简单的方法,容易地打开一条指定的CAN通道。本文分享如何实现让一路CAN通道为指定接口的专用通道。

            通常,如果你的Kvaser设备有多个接口,那么每次都会以相同的顺序启动这些接口,但是如果在电脑工作状态时插入一个新设备,那么顺序就有可能会不同。随着接入CAN设备的增多,进行连接操作的复杂度越来越高,有时候工程师需要消耗大量的精力进行CAN设备与CAN通道的匹配工作,这难免影响工作进度。


            本文将展示怎样通过昵称而不是CANlib通道号,连接到特定的一路Kvaser CAN通道。该方法可实现让一路CAN通道为指定接口的专用通道。

            01

            自定义通道名称

            只需要简单的操作,就能打开一路特定的CAN通道。Kvaser所有的接口都有一个产品代码(EAN)和一个序列号,再加上“卡上的通道号”,这三个数据字段创建了一个独特的组合。

            举例 

            如下图所示,本次演示我使用的“Kvaser USBcan Pro 2xHS v2”接口有两路通道, 0 和1, 它们在CANlib中显示为1和2。

            图片

            02

            查找一路特定通道的信息

            在查看我的“Kvaser USBcan Pro 2xHS v2”接口后, 我们会发现:


            1??设备 EAN 73-30130-00752-9 (这是产品系列号)

            2??系列号 12160

            3??卡上通道 0 (在此第一路通道上)

            4??卡上通道 1 (在此第二路通道上)


            图片


            如果我基于此信息创建一个名称,例如“00752-9:12160/1”,那么此名称将始终指向我的“USBcan Pro”的第二路通道,没有其他Kvaser接口具备此组合。


            因此,如果我将“00752-9:12160/1”连接到一个测试对象,那么我无需了解电脑安装了多少其他接口,而只需打开该名称组合,就能始终与该测试对象通信。这类似于canOpenChannel(‘00752-9:12160/1’,flags)。

            CANlib命令canOpenChannel()

            通常,当调用命令canOpenChannel时,我们会提供一个CANlib通道号和一些FLAG(标志)。


            我们可以改用canOpenChannel(‘00752-9:12160:1’,flags)句式吗?

            实际上,在最理想的情况下,这个命令应该已经是CANlib的一部分了,但是它还尚不存在,所以你需要自己去做。


            用户自定义的MycanOpenChannel()

            首先,我们创建一个命令: MyCanOpenSpecificChannel()


            ?Delphi

            function MyCanOpenSpecificChannel(const NickName: string; const flags: integer; var FoundChannel: integer): canHandle;


            ?Parameters(参数)

            [in] NickName String with “EAN:SN/ChOnCard” (‘00752-9:12160/1’)

            (带有“EAN:SN/ChOnCard”的昵称字符串)

            [in] flags A combination of canOPEN_xxx flags (一个canOPEN_xxx的组合)

            [out] FoundChannel(找到的通道) The number of the opened channel(已打开的通道数)


            ?Returns(返回)

            返回一个给断开回路的句柄,或者,如果调用失败,则返回canERR_xxx (负)。


            完整的MyCanOpenSpecificChannel() 函数目录请见附录。


            我们假设昵称包含‘00752-9:12160/1’。让我们调用函数SplitNickNameStringPlease(), 它将返回EAN、SN和NoOnCard。


            EAN = ‘00752-9’

            SN = 12160

            NoOnCard = 1


            通过canGetChannelData()命令,我们可以获取所连接相关接口的大量信息。我们将使用参数:canCHANNELDATA_CARD_SERIAL_NO, canCHANNELDATA_CHAN_NO_ON_CARD 和 canCHANNELDATA_CARD_UPC_NO。


            canCHANNELDATA_CARD_SERIAL_NO uses a 64bit integer

            canCHANNELDATA_CHAN_NO_ON_CARD uses a 32bit integer

            canCHANNELDATA_CARD_UPC_NO uses a 64bit BCD string


            所以通过调用 (当迭代通过所有通道时 (I)):

            canGetChannelData(I, canCHANNELDATA_CARD_SERIAL_NO , U64_1, sizeof(U64_1));

            canGetChannelData(I, canCHANNELDATA_CHAN_NO_ON_CARD, U32_1, sizeof(U32_1));

            canGetChannelData(I, canCHANNELDATA_CARD_UPC_NO , U64_2, sizeof(U64_2));


            我们将在U64_1,U32_1 和 U64_2中收到一些信息。


            U64_1 and U32_1将包含卡上相应通道号的系列号,并且我们可以很容易地将它与搜索值进行比较。


            U64_2包含EAN编号,我们需要做一些处理才能读取EAN编号。


            首先,将U64_2转换为16位长的十六进制字符串,

            2026405030294825 ToHexString变为: ‘0007330130007529’


            完整的EAN代码是73-30130-00752-9,所以很容易找到要复制的内容:73-30130-00752-9 ‘0007330130007529


            st := copy(st, 11, 5) + ‘-‘ + copy(st, 16, 1);


            我们在寻找状况:

            EAN = ‘00752-9’

            SN = 12160

            NoOnCard = 1


            如果 (U64_1=SN) 和 (U32_1=SN) 以及 (EAN=st),那么我们已经找到了那个接口, 然后返回此通道号并尝试调用 canOpenChannel()??梢栽诟铰贾锌吹胶耐暾斜?。

            03

            结论

            你可以选择任何格式来描述某个特定通道。在此文中要解释的是,通过三次调用canGetChannelData(),你将收到足够的信息来确定,是否它就是你要打开的某个通道。


            希望本文会对你有帮助?;队缆酆吞嵛?!

            04

            附录

            CANlib命令canOpenChannel()

            function MycanOpenChannel(const NickName: stringconst flags: integer; var FoundChannel: integer): canHandle;

                var

                  I: integer;


                  EAN       : string;

                  SN        : UINT64;

                  ChNoOnCard: UINT32;


                  N: integer;

                  UI64   : UINT64;

                  UI32   : UINT32;

                  st     : string;


                begin

                  result       := canERR_NOTFOUND;

                  FoundChannel := canERR_NOTFOUND;


                  /// Most probably, NickName contains something like:'00752-9:12160:0'

                  /// EAN=00752-9 (this is the last part of Device EAN73-30130-00752-9)

                  /// sn = 12160

                  /// NoOnCard=0


                  if SplitNickNameStringPlease(NickName, EAN, SN, ChNoOnCard) then

                  begin

                    // Let us see if we can find the combination of EAN, SN, ChNoOnCard


                    if (canGetNumberOfChannels(N) = canOK) then

                    begin

                      for I := 0 to N - 1 do

                      begin

                        // Look for SN first

                        if (canGetChannelData(I, canCHANNELDATA_CARD_SERIAL_NO, UI64, sizeof(UI64)) = canOK) then

                        begin

                          if (UI64 = SN) then

                          begin

                            if (canGetChannelData(I, canCHANNELDATA_CHAN_NO_ON_CARD, UI32, sizeof(UI32)) = canOK) then

                            begin

                              if (UI32 = ChNoOnCard) then

                              begin

                                // We have found a channel with SN and NoC that is correct, let see if EAN is correct

                                if (canGetChannelData(I, canCHANNELDATA_CARD_UPC_NO, UI64, sizeof(UI64)) = canOK) then

                                begin

                                  st := UI64.ToHexString(16);

                                  st := copy(st, 115) + '-' + copy(st, 161);

                                  if (st = EAN) then

                                  begin

                                    FoundChannel := I;

                                    break// Breaks the FOR-loop

                                  end;

                                end;

                              end;

                            end;

                          end;

                        end;

                      end;


                      if FoundChannel >= then

                      begin

                        // Let us use "FoundChannel" and see what happens

                        result := canOpenChannel(FoundChannel, flags);

                      end;

                    end;

                  end;

                End;


            CANlib命令canOpenChannel()

            function SplitNickNameStringPlease(const NickName: stringvar EAN: stringvar SN: UINT64; var NoC: UINT32): boolean;

                var

                  P   : integer;

                  st  : string;

                  temp: string;

                begin

                  result := false;

                  try

                    // '00752-9:12160/0'

                    temp := NickName;

                    P    := pos(':', temp);

                    if P > 0 then

                    begin

                      EAN  := copy(temp, 1, P - 1);

                      temp := copy(temp, P + 11024);


                      EAN := trim(EAN); // remove leading and trailing spaces

                      while length(EAN) < 7 do

                      begin

                        EAN := '0' + EAN; // add leading zeros if needed

                      end;


                      P := pos('/', temp);

                      if P > 0 then

                      Begin

                        st := copy(temp, 1, P 1);

                        SN := st.ToInteger;


                        st  := copy(temp, P + 11024);

                        NoC := st.ToInteger;


                        result := true;

                      end;

                    end;

                  except

                    result := false;

                  end;

                end;



            返回列表

            上一篇:没有了
            专业玩彩