• ¼¼Êõ²©¿Í

    13/03/2018 ×÷Õß ÔÆº£ÓÎÏ·

    ÔÆº£ÓÎÏ· Èí¼þ¿ª·¢°üSDK ´ÓCAN CLASSIC Éý¼¶µ½CAN FD

    ÕâÆªÎÄÕÂÊǽéÉÜÔõÑù´ÓCAN CLASSIC Éý¼¶µ½ CAN FD¡£ÎÒÃÇÔڴ˽ö½éÉÜÔÚ±à³Ì´úÂëÉÏÐèÒªµÄÐ޸ģ¬Èç¹ûÄãÏÖÔÚÓÐÒ»¸öÔÆº£ÓÎÏ· CANLib SDKÖ§³ÖµÄÏîÄ¿¡£µ±È»ÄãÒ²¿ÉÒÔ½èÖú±¾ÎÄ¿ªÊ¼Ò»¸öÐÂÏîÄ¿¡£

    ÎÒÃǽ«ÔÚ´ËÌø¹ý½éÉÜCAN FDµÄ¶¨ÒåºÍÎïÀí×ÜÏßÏàÓ¦µÄÐ޸ġ£Èç¹ûÄãÐèÒª¶ÔCAN FDÁ˽â¸ü¶à£¬Çë·ÃÎÊÎÒÃǵÄÍøÒ³(https://www.kvaser.com/about-can/can-fd/)¡£

    ÎÒÃÇÅàѵרÀ¸Ò²ÌṩÁ˸ü¶àÐÅÏ¢ (https://www.kvaser.com/training-materials/)¡£ÄãÐèÒª£¨Ãâ·Ñ£©×¢²áºÍµÇ½ÎÒÃǵÄÍøÕ¾À´ÏÂÔØ84Åàѵ×ÊÁÏ

    ÍÆ¼öÏÂÔØºÍÔĶÁ:

    • CAN ×ÜÏßЭÒé½Ì³Ì
    • Ϊ²»Í¬µÄ¿Í»§·þÎñµÄCAN FD
    • ±È½Ï CAN FD ºÍ Classical CAN

    CanFDTest

    ÎÒÃÇÔÚEmbarcadero DELPHI(Pascal)»·¾³Öн¨Á¢ÁËÒ»¸öÏîÄ¿£¬ÃûΪ¡°CanFDTest¡±¡£Èç¹ûÄãûÓÐDELPHI »·¾³, ¿É½èÖúÈκÎÎı¾±à¼­Æ÷À´ÔĶÁ´Ë´úÂë¡£ ×îÖØÒªµÄ´úÂë±»·ÅÔÚRunCanFDExamplePlease ³ÌÐòÖУ¬²¢ÊÕ¼ÔÚ¸½Â¼AÀï¡£

    Ôڴ˳ÌÐòÖУ¬ÎÒÃdzõʼ»¯×ÜÏߣ¬·¢ËÍÒ»¸öÖ¡£¬ÊÕµ½Ò»¸öÖ¡£¬Íê³É×ÜÏß¡£


    ËùÐèÓ²¼þ

    ÎÒÃǽ«ÔÚÐéÄâÒ»¸ö¼ÆËã»ú(Microsoft HYPER-V, WIN10 64bit)ºÍÒ»¸ö±ê×¼±Ê¼Ç±¾µçÄÔÉϽøÐÐÕâ¸ö·¶ÀýµÄ²âÊÔ¡£ÔÚ²âÊÔÖУ¬ÎÒÃǼÈʹÓÃÐéÄâÊÊÅäÆ÷£¬Ò²Ê¹ÓÃÔÆº£ÓÎÏ· ÊÊÅäÆ÷¡£

    • Èç¹ûÓÃÔÆº£ÓÎÏ· Çý¶¯ÉϵÄÐéÄâͨµÀ£¬¾Í²»ÐèÒªÓÃÓ²¼þ (ÔÆº£ÓÎÏ· CANÊÊÅäÆ÷) À´ÔËÐÐÕâ¸ö·¶ÀýÏîÄ¿¡£

    ¡°CanFDTest¡±ÐèÒªµÄ¹¤¾ß

    ´Ë·¶ÀýÀ´×ÔDelphi? ÏîÄ¿ ¡°CanFDTest_xxx¡±¡£

    ÔËÐд˷¶ÀýÊÇû±ØÒªµÄ£¬¸üÖØÒªµÄÊÇ´ò¿ªÎļþ¡°CanFDtestUnit.pas¡±£¬ºÍѧϰRunCanFDExamplePlease()³ÌÐò²½Öè¡£

    EMBARCADERO DELPHI
    Delphi?ÊÇÓÉ EMBARCADERO?ÌṩµÄÒ»¸öÈí¼þ¡£ÔÚд±¾ÎÄʱ(2018Äê1ÔÂ10ÈÕ),ËûÃÇÌṩÁËÒ»¸öÃâ·Ñ°æ±¾¡°DELPHI STARTER¡±, ÄãÄÜÔÚÕâÀï¿´µ½: https://www.embarcadero.com/products/delphi/starter

    ÔÆº£ÓÎÏ· CANlib SDK
    ÄãÐèÒªCANlib Èí¼þ¿ª·¢°ü(ÔÆº£ÓÎÏ· Caleb SDK)À´ÔËÐд˷¶Àý¡£ÎÒÃÇ×ÜÊÇÀë²»¿ªCANlib¡£

    Äã¿ÉÒÔÔÚÕâÀïÕÒµ½SDK : https://www.kvaser.com/downloads-kvaser/

    ÔÆº£ÓÎÏ· CAN Ó²¼þµÄÇý¶¯
    Õâ¸öÇý¶¯°üÀ¨Ò»¸öÐéÄâÓ²¼þ£¬Ëü¿ÉÒÔ×öÎÒÃǵĸ÷¿îÓ²¼þÄÜ×öµÄÈκÎÊ¡£ÕâʹÎÒÃDz»ÓÃÈκÎÎïÀíÊÊÅäÆ÷£¬¾ÍÄܲâÊÔCAN FD ¡£µ±ÄãÓÐÒ»¸öÔÆº£ÓÎÏ· ÊÊÅäÆ÷ÒԺ󣬾ͿÉÒÔÇáËɵشÓÐéÄâÇý¶¯×ªÒƵ½ÕæÊµCAN FD ×ÜÏßÉÏ¡£

    Äã¿ÉÒÔÔÚÕâÀïÏÂÔØÇý¶¯: https://www.kvaser.com/downloads-kvaser/

    ÎÒÃÇÌṩWindows£¬Linux£¬DIADEMµÄÇý¶¯¡£±¾Àý³Ì»ùÓÚWindows Çý¶¯Æ½Ì¨¡£

    We provide drivers for Windows, Linux and DIADEM. This example uses the Windows drivers.

    ÔÆº£ÓÎÏ· HELP Îļþ
    µ±Äã·ÃÎÊKVASERÍøÕ¾, Ò²Ç뿴һϠCANlib Help?(ÕâÀï°üÀ¨¶Ô CANlib SDKÖ§³Ö) (http://www.kvaser.com/kvaser/site/CANlib-webhelp/)

    • DELPHI, CANlib SDK ºÍ DRIVER±ØÐëÔÚÔËÐз¶Àý(CanFDTest)֮ǰ°²×°ºÃ

    CanFDTest³ÌÐò

    CanFDTest·¶Àý³ÌÐòÊÇÓÉ4¸öPAS Îļþ×é³ÉµÄ:

    • CANlib.pas
    • CanFDTestUnit.pas
    • DummyUnit.pas
    • MyHelpUnit.pas

    CANlib.pas
    ͨ³£Õâ¸öÎļþ±»°üÀ¨ÔÚÔÆº£ÓÎÏ· CANlib SDKÀï¡£

    ΪÁË·½±ãÓû§, PASÎļþ±»¸´ÖÆÔÚÎÒÃǵÄÏîÄ¿À¶ø²»ÊÇÔÚDELPHIÀィÁ¢Ò»¸öËÑË÷·¾¶µ½´ËÎļþ¡£

    CanFDTestUnit.pas
    °üÀ¨´Ë·¶ÀýµÄËùÓÐÖ÷ÒªÐÅÏ¢¡£

    ÔÚ±¾ÎĵĽáβ²¿·Ö°üº¬ÔËÐÐRunCanFDExamplePlease() µÄ²½Öè¡£

    DummyUnit.pas
    °üº¬Ò»Ð©²âÊÔÓõġ°·Âº¯Êý£¨dummy functions£©¡± ¡£

    ÕâЩº¯Êý¡°²»×öÈκÎÊ¡±, µ«ËüÃÇÄÜΪ²âÊÔÉèÖ÷ֽçµã¡£±àÒë³ÌÐò²»ÄÜÓÅ»¯·Âº¯ÊýÖеıäÁ¿£¬ËùÒÔËüÃDz»Ó°Ïì²âÊÔ¡£

    MyHelpUnit.pas
    °üº¬Ò»Ð©ÄܰïÖúÎÒÃÇ£¬µ«SDKδ½éÉܵŦÄÜ¡£

    ÔõÑùʹÓ÷¶Àý CanFDTest
    ´ò¿ªÎļþ ¡°CanFDTest.dproj¡± (´Ó DELPHI´ò¿ª)£¬½âѹºÍ´ò¿ª´ËÏîÄ¿¡£

    Èç¹ûÄã²»ÏëÔËÐд˷¶Àý£¬ÔòÓÃÒ»¸öÄãÑ¡µÄÎı¾±à¼­Æ÷´ò¿ªÎļþ¡°CanFDTestUnit.pas¡±¡£


    RunCanFDExamplePleaseÔËÐв½Öè

    Õâ·ÖΪ4²¿·Ö:

    • ³õʼ»¯
    • ·¢ËÍ
    • ½ÓÊÕ
    • Íê³É

    ÕâÀïչʾµÄ´úÂëÊǽÚÑ¡µÄ£¬²»ÊÇÈ«²¿¡£Çë²é¿´Ô´´úÂë¡£

    ²½Öè: ³õʼ»¯
    Ñ¡ÔñCLASSIC CAN »ò CAN FD
    ÉèÖó£Ì¬MyApp Ϊ canFD »òcanCLASSIC CAN¡£
    ½«ÐèÒª×÷Ϊ·¢Ë͵ÄÊÊÅäÆ÷ͨµÀÉèÖÃΪTX_MySelCh ¡£
    ½«ÐèÒª×÷Ϊ½ÓÊÕµÄÊÊÅäÆ÷ͨµÀÉèÖÃΪRX_MySelCh ¡£

    ¼¸ºõËùÓÐÔÆº£ÓÎÏ· CAN ÊÊÅäÆ÷¿ÉͬʱΪ·¢ËÍÆ÷ºÍ½ÓÊÕÆ÷¡£ÎÒÃÇÔÚÕâ¸ö·¶ÀýÀïÑ¡ÔñÒÔÒ»¸öΪTX£¬ÁíÒ»¸öRX £¬ÒÔʹÕâ¸ö·¶ÀýµÄ´úÂëÈÝÒ×±»Àí½â¡£

    Ê×ÏÈÎÒÃÇÔËÐÐ3¸öÃüÁî:
    canInitializeLibrary()
    canGetChannelData()

    • ²»ÐèÒª¸Ä±ä Can FD

    ÏÖÔÚÎÒÃÇÖªµÀ´æÔÚ¶àÉÙ¸öÊÊÅäÆ÷ÒÔ¼°ËüÃǵÄÃû³Æ¡£ÎÒÃÇ¿ÉÒÔ´ò¿ªÆäÖÐÁ½¸ö¡£

    canOpenChannel()

    • ÐèÒª±à¼­ Can FD!

    CAN CLASSIC
    TX_MyHnd := canOpenChannel(TX_MySelCh – 1, canOPEN_ACCEPT_VIRTUAL);
    RX_MyHnd := canOpenChannel(RX_MySelCh – 1, canOPEN_ACCEPT_VIRTUAL);

    CAN FD
    TX_MyHnd := canOpenChannel(TX_MySelCh – 1, canOPEN_ACCEPT_VIRTUAL OR canOPEN_CAN_FD);
    RX_MyHnd := canOpenChannel(RX_MySelCh – 1, canOPEN_ACCEPT_VIRTUAL OR canOPEN_CAN_FD);

    ÔÚ´ò¿ªÒ»¸öFDͨµÀʱ£¬Ê¹ÓÃÆì±ê£¨FLAG£©ÊÇÖØÒªµÄ: canOPEN_CAN_FD

    ÎÒÃÇÓÃÁªºÏÃüÁî¡°canOPEN_ACCEPT_VIRTUAL OR canOPEN_CAN_FD¡± ´ò¿ªÒ»¸öÐéÄâÊÊÅäÆ÷£¬ÉèÖÃģʽΪFD¡£

    ÏÖÔÚÊÊÅäÆ÷´ò¿ªÁË£¬ÎÒÃÇÐèÒªÉèÖÃËüÃǵIJÎÊý¡£

    canSetBusParams() and canSetBusParamsFD()

    • FDÐèÒª±à¼­ºÍ¸½¼ÓÐÅÏ¢FD!
    • ¿ÉÒÔÓÃÆäËûÖµ£¬¶ø²»ÓÃÔ¤ÉèÖµ (±¾ÎIJ»½éÉÜÕⲿ·Ö)¡£

    CAN CLASSIC
    canSetBusParams()½öÄÜÓëcanBITRATE_xxxÒ»ÆðÓÃ.

    TX := canSetBusParams(TX_MyHnd, canBITRATE_500K, 0, 0, 0, 0, 0);
    RX := canSetBusParams(RX_MyHnd, canBITRATE_500K, 0, 0, 0, 0, 0);

    CAN FD
    canSetBusParams() and canSetBusParamsFD()ÄÜÓë canFD_BITRATE_xxxÒ»ÆðÓá£

    TX := canSetBusParams(TX_MyHnd, canFD_BITRATE_500K_80P, 0, 0, 0, 0, 0);
    RX := canSetBusParams(RX_MyHnd, canFD_BITRATE_500K_80P, 0, 0, 0, 0, 0);

    TX := canSetBusParamsFD(TX_MyHnd, canFD_BITRATE_1M_80P, 0, 0, 0);
    RX := canSetBusParamsFD(RX_MyHnd, canFD_BITRATE_1M_80P, 0, 0, 0);

    • Çë×¢Òâ, ²»ÒªÔÚFDÉÏʹÓÃcanBITRATE_xxx Öµ!

    ÏÖÔÚËùÓвÎÊý¶¼ÉèÖúÃÁË£¬ÎÒÃÇ¿ÉÒÔÉÏÏßÁË£¬ËùÒÔÎÒÃÇÒª½áÊø³õʼ»¯¹ý³Ì£¬´ò¿ª×ÜÏߣ¬×öһЩÇåÀí¡£

    canBusOn()
    canFlushTransmitQueue()
    canFlushReceiveQueue()

    • ²»ÐèÒª¸Ä±äCAN FD

    ?

    ²½Öè: ·¢ËÍ
    ÎÒÃǼ¤»îÁË×ÜÏߣ¬ÊÊÅäÆ÷ÔÚµÈÎÒÃǵÄÏÂÒ»²½²Ù×÷¡£ÎÒÃÇÓ¦´ÓÒ»¸öÑ¡³öµÄÊÊÅäÆ÷·¢ËÍÒ»¸öÖ¡¡£

    canWrite()

    • ÐèÒª±à¼­CAN FD!

    (ÎÒÃÇ¿ÉÒÔÓÃcanWrite() »ò canWriteWait()ÃüÁµ«ÔÚ±¾·¶ÀýÖÐÎÒÃÇÖ»ÓÃcanWrite¡£)

    ÍÆ¼ö: ²ÎÔÄTHE HELP!

    CAN CLASSIC
    BUF? := ‘Hello!’;
    id?? := 111;
    dlc? := 8; // For Classic CAN dlc can be at most 8*
    Flag := canMSG_STD;

    R := canWrite(TX_MyHnd, id, @BUF, dlc, Flag);

    CAN FD
    BUF? := ‘Hello World!’;
    id?? := 222;
    dlc? := 16; // for CAN FD dlc CAN be one of the following 0-8,12, 16, 20, 24, 32, 48, 64
    Flag := canMSG_STD OR canFDMSG_FDF OR canFDMSG_BRS;

    R := canWrite(TX_MyHnd, id, @BUF, dlc, Flag);

    • Р»º´æÈÝÁ¿¿É´ï64 bytes
    • ¼Ó canFDMSG_FDF µ½Æì±êflag ÉÏ(±íÃ÷´ËÖ¡ÊÇÒ»¸öFD Ö¡)
    • ¼Ó canFDMSG_BRS µ½Æì±ê flag ÉÏ(±íÃ÷¸ÃÖ¡ÐèÒÔ±ÈÌØÂʵ÷½Ú·¢ËÍ)

    Çë×¢ÒâcanFDMSG_BRS¿ÉÑ¡¿É²»Ñ¡¡£µ±¼ÓÁËBRS flag, Êý¾Ý²¿·ÖÊÇÒÔ FD±ÈÌØÂÊ·¢Ë͵쬶ø²»ÊÇÒÔÖٲñÈÌØÂÊ·¢Ë͵Ä¡£

    ÔÚÄ㼤»îFDÒÔºóÈÔ¿ÉÒÔ·¢ËÍclassic CAN Ö¡! Ö»ÄÜÓÃcanMSG_STD »ò canMSG_EXT Éú³ÉÒ»¸öclassic Ö¡¡£

    ?

    ²½Öè: ½ÓÊÕ
    canRead()

    • ÐèÒª±à¼­ CAN FD!

    (¿ÉÓÃÀ´½ÓÊÕFDͨѶµÄcanRead() (ÖÁÉÙ)ÓÐËĸö°æ±¾µÄ¡£ÔÚ´Ë·¶ÀýÖÐÎÒÃǽöÓÃcanRead()£¬ËùÒÔÎÒÃǽ¨ÒéÄãÔĶÁ¡®Help¡¯ ²¿·Ö!)

    R?? := canRead(RX_MyHnd, id, @BUF, dlc, Flag, myTime);

    ÎÒÃDz»ÐèÒª¶ÔÔĶÁÃüÁî×öÈκÎÐ޸쬵«ÊÇ ¡­

    • È·ÈÏ»º´æ[BUF]µÄ×îСÈÝÁ¿ÊÇ64 bytes¡£¼´Ê¹ÎÒÃDz¢²»Ïë·¢Ëͳ¤¹ý24 bytesµÄÖ¡, ±ðÈË»òÐíÐèÒª¡£
    • Ñо¿±»·µ»ØµÄÆì±êÖµ£¬ËüÃǰüº¬ÁËһЩÐÂÖµ¡£ÕâЩÊÇcanMSG_xxx, canMSGERR_xxx ºÍ canFDMSG_xxx ÖµµÄ×ۺϡ£

    ¼´Ê¹Ö»ÓÐÎÒÃÇÔÚ×ÜÏßÉÏ£¬¶øÇÒÎÒÃǽö·¢ÁËÒ»Ö¡, ½ÓÊܵ½µÄ֡δ±ØÊÇÎÒÃÇÏëÒªµÄ¡£ÀýÈ磬Èç¹ûÆì±êÀï°üÀ¨ÁËÖµcanMSG_ERROR_FRAME, ÄÇô´ËÖ¡ÊÇÒ»¸ö´íÎóÖ¡£¬²»ÊÇÎÒÃÇÏ£Íû¿´µ½µÄ¡£.

    • Ò»¶¨Òª×ÜÊǼì²é·µ»ØµÄÖµ[R] ºÍ·µ»ØµÄÆì±ê!

    ÏÖÔÚÎÒÃÇÒѾ­ÊÕµ½ÁËÎÒÃǵÄÖ¡¡£

     

    ²½Öè: Íê³É
    Íê³É²½Öè²»ÐèÒª±à¼­¡£

    canBusOff()
    canClose()
    canUnloadLibrary()

    • ²»ÐèÒª¸Ä±ä CAN FD

    ×ܽá

    µ±È»£¬¿ÉÒÔÓÃSDK×öºÜ¶àÊÂ, µ«ÎÒÃǽ«´Ë·¶Àý¾ÖÏÞÔÚ·¢ËͺͽÓÊÕÒ»¸öÖ¡¡£

    Èç¹ûÄãÒªÀ©Õ¹´Ë·¶Àý, ¿ÉÒÔ°´ÄãµÄÐèÒªÐÞ¸ÄËü£¬²¢ºÍÔÆº£ÓÎÏ· CANKing Èí¼þ½áºÏÆðÀ´Ê¹Óã¬ÒÔ·¢ËͺͽÓÊÕÖ¡¡£Äã¿ÉÔÚÎÒÃǵÄÍøÕ¾ÉÏ¿´µ½¸ÃÈí¼þ(ºÍ SDK £¬Çý¶¯ÔÚͬһ¸öλÖÃ) ¡£ÄãÄÜÓÃCANKingÉú³ÉÖ¡£¬Ä£Äâ´íÎó(ÒÔ¼°¸ü¶à)¡£

    ÎÒÃÇÏ£Íû±¾ÎÄÄܰïÖúÄãÔÚÔÆº£ÓÎÏ· ²úÆ·ÉÏʹÓÃCAN FD¡£


    ʹÓà CAN FDµÄÃüÁî:

    Çë ¸ñÍâ×¢ÒâÏÂÁÐÃüÁî,ÄãʹÓÃCAN FD ºÍ±à¼­ÄãµÄ´úÂëʱ¶¼ÐèÒªËüÃÇ¡£

    Çë×¢ÒâCAN FD ¿ÉÄÜÐèÒª¸ü¶àÃüÁî/Æì±ê£¬¶ø±¾ÎÄÏÞÓÚÆª·ùûÓÐÖðÒ»½éÉÜ¡£

    ¼ÇסÔÚʹÓÃÎÒÃÇÌáµ½µÄÈκÎÃüÁîÒÔǰ£¬×ÜÊÇÏȲ鿴HELP ¡£

    canOpenChannel()

    canGetBusParamsFD()

    canSetBusParams()
    canSetBusParamsFD()
    canWrite()

    canWriteWait()
    ±¾ÎÄδÓõ½

    canRead()

    canReadSpecific()
    canReadSpecificSkip()
    canReadWait()
    ±¾ÎÄδÓõ½
    ±¾ÎÄδÓõ½
    ±¾ÎÄδÓõ½

    ¸½Â¼ A RunCanFDExamplePleaseÔËÐв½Öè

    procedure TFormCanFDtest.RunCanFDExamplePlease;
      var
        I          : integer;                 // INT32
        N          : integer;                 // INT32
        R          : integer;                 // INT32
        TX         : integer;                 // INT32
        RX         : integer;                 // INT32
        numCh      : integer;                 // INT32
        MyChNames  : array of string;         //
        TX_MyHnd   : canHandle;               // canHandle = integer = INT32
        RX_MyHnd   : canHandle;               // canHandle = integer = INT32
        BUF        : TByteBUF0064;            // Array 64 bytes of 8bit char
        MyStringBuf: TByteBUF1024;            // Array 1024 bytes of 8bit char
        id         : Longint;                 // Warning LONGINT is 32b or 64b depending of
                                              // target platform. check if using iOS or LINUX!
        dlc        : Cardinal;                // UINT32
        Flag       : Cardinal;                // UINT32
        HelpFlag   : THelpFlag absolute Flag; // UINT32, HelpFlag share adress with Flag
        myTime     : Cardinal;                // UINT32
    
      begin
        I := sizeof(id);
        dummy(I);
    
        begin
    
          case MyApp of
            canCL:
              begin
                Memo.Lines.Add('Hello! Starting TestCanLIB_STD. Using CLASSIC CAN')
              end;
            canFD:
              begin
                Memo.Lines.Add('Hello! Starting TestCanLIB_STD. Using FD CAN');
              end;
          end;
    
          /// *********************************************************
          /// Section one, INITIALIZATION
          /// *********************************************************
          // Open CanLib.DLL
          canInitializeLibrary;
          // No errorchecking here, will be done later when opening channel...
    
          // Find out how many channels(interfaces) we can use
          R := canGetNumberOfChannels(numCh);
          if MyErrorCheck(Memo, R, 'canGetNumberOfChannels') then
          begin
            exit;
          end;
          Memo.Lines.Add('Found ' + numCh.ToString + ' channels');
    
          setlength(MyChNames, numCh);
          for I := Low(MyChNames) to High(MyChNames) do
          begin
            canGetChannelData(I, canCHANNELDATA_DEVDESCR_ASCII, MyStringBuf, sizeof(MyStringBuf));
            canGetChannelData(I, canCHANNELDATA_CHAN_NO_ON_CARD, N, sizeof(N));
            MyChNames[I] := (I+1).ToString+'  '+string(MyStringBuf)+' ' + (N+1).ToString;
            Memo.Lines.Add('Found channel: ' + MyChNames[I]);
          end;
    
          // Check that the selected channels exist
          if MyErrorCheck(Memo, TX_MySelCh, RX_MySelCh, 1, numCh, 'numCh') then
          begin
            exit;
          end;
    
          Memo.Lines.Add('Selected TX:' + MyChNames[TX_MySelCh - 1]);
          Memo.Lines.Add('Selected RX:' + MyChNames[RX_MySelCh - 1]);
    
          // Next step is to open the Channels
          // Please check the FLAGs!
          // CAN FD needs different settings!
          case MyApp of
            canCL: // Classic CAN communication
              begin
                TX_MyHnd := canOpenChannel(TX_MySelCh - 1, canOPEN_ACCEPT_VIRTUAL);
                RX_MyHnd := canOpenChannel(RX_MySelCh - 1, canOPEN_ACCEPT_VIRTUAL);
                if MyErrorCheck(Memo, TX_MyHnd, RX_MyHnd, 'canOpenChannel') then
                begin
                  exit;
                end;
              end;
            canFD: // CAN FD communication
              begin
                TX_MyHnd:=canOpenChannel(TX_MySelCh-1, canOPEN_ACCEPT_VIRTUAL OR canOPEN_CAN_FD);
                RX_MyHnd:=canOpenChannel(RX_MySelCh-1, canOPEN_ACCEPT_VIRTUAL OR canOPEN_CAN_FD);
                if MyErrorCheck(Memo, TX_MyHnd, RX_MyHnd, 'canOpenChannel FD') then
                begin
                  exit
                end;
              end;
          end;
    
          /// *****************************************************************************
          ///
          /// Now is a good time to enable messages, but we do not need it in this example
          /// canSetNotify(MyHnd, Self.Handle, $FFFFFFFF);
          ///
          /// *****************************************************************************
          case MyApp of
            canCL: // Classic CAN communication
              begin
                TX := canSetBusParams(TX_MyHnd, canBITRATE_500K, 0, 0, 0, 0, 0);
                RX := canSetBusParams(RX_MyHnd, canBITRATE_500K, 0, 0, 0, 0, 0);
                if MyErrorCheck(Memo, TX, RX, 'canSetBusParams') then
                begin
                  exit
                end;
              end;
            canFD: // CAN FD communication
              begin
                TX := canSetBusParams(TX_MyHnd, canFD_BITRATE_500K_80P, 0, 0, 0, 0, 0);
                RX := canSetBusParams(RX_MyHnd, canFD_BITRATE_500K_80P, 0, 0, 0, 0, 0);
                if MyErrorCheck(Memo, TX, RX, 'canSetBusParams') then
                begin
                  exit
                end;
    
                TX := canSetBusParamsFD(TX_MyHnd, canFD_BITRATE_1M_80P, 0, 0, 0);
                RX := canSetBusParamsFD(RX_MyHnd, canFD_BITRATE_1M_80P, 0, 0, 0);
                if MyErrorCheck(Memo, TX, RX, 'canSetBusParamsFD') then
                begin
                  exit
                end;
              end;
          end;
    
          // Turn BUS on
          TX := canBusOn(TX_MyHnd);
          RX := canBusOn(RX_MyHnd);
          if MyErrorCheck(Memo, TX, RX, 'canBusOn') then
          begin
            exit
          end;
    
          // Remove all pending transmissions, might not be needed
          TX := canFlushTransmitQueue(TX_MyHnd);
          RX := canFlushTransmitQueue(RX_MyHnd);
          if MyErrorCheck(Memo, TX, RX, 'canFlushTransmitQueue') then
          begin
            exit
          end;
    
          sleep(250); // Take a short nap...
    
          // Remove all pending transmissions, do we really wanna do this in a sharp application?
          // Might remove wanted frames.
          TX := canFlushReceiveQueue(TX_MyHnd);
          RX := canFlushReceiveQueue(RX_MyHnd);
          if MyErrorCheck(Memo, TX, RX, 'canFlushReceiveQueue') then
          begin
            exit
          end;
    
          // CAN is open for traffic
          Memo.Lines.Add('CAN open, waiting');
    
          /// *********************************************************
          /// Section two, Sending
          /// *********************************************************
          // Create one frame and transmit
          // Transmitting from TX_MySelCh
    
          case MyApp of
            canCL: // Classic CAN communication
              begin
                BUF := 'Hello!';
                id  := 111;
                dlc := 8;
                /// For Classic CAN dlc can be at most 8, unless canOPEN_ACCEPT_LARGE_DLC is used.
                /// CanWrite can only transfer max 8 bytes, regardless of dlc
                /// In this example BUF is 64 bytes wide, but only 8 bytes can be sent.
                Flag := canMSG_STD;
    
                R := canWrite(TX_MyHnd, id, @BUF, dlc, Flag);
                if MyErrorCheck(Memo, R, 'canWrite') then
                begin
                  exit
                end;
    
                Memo.Lines.Add('TX ID:'+id.ToString+' dlc:'+dlc.ToString+' B :'+MyConvert(BUF, dlc));
              end;
            canFD: // CAN FD communication
              begin
                BUF  := 'Hello World!';
                id   := 222;
                dlc  := 16; 
                // for CAN FD dlc CAN be one of the following 0-8, 12, 16, 20, 24, 32, 48, 64
                Flag := canMSG_STD OR canFDMSG_FDF OR canFDMSG_BRS;
    
                R := canWrite(TX_MyHnd, id, @BUF, dlc, Flag);
                if MyErrorCheck(Memo, R, 'canWrite (FD)') then
                begin
                  exit
                end;
    
                Memo.Lines.Add('TX ID:' + id.ToString + ' dlc:' + dlc.ToString + ' bytes :' +
                 MyConvert(BUF, dlc));
              end;
          end;
    
          /// *********************************************************
          /// Section three, Recieving
          /// *********************************************************
          // Now if we are lucky, some bytes have arrived to RX
          BUF := '';
          I   := 0;
          repeat
            inc(I);
            sleep(100);
    
            // Always use 64 byte wide buffer to avoid errors!!!
            dlc  := 4;
            Flag := 0;
            R    := canRead(RX_MyHnd, id, @BUF, dlc, Flag, myTime);
            /// WARNING, make sure that BUF is mminimum 64 bytes wide!
            Memo.Lines.Add('Read attemp no ' + I.ToString + ' Result :' + R.ToString);
          until (I >= 5) OR (R = canOK);
    
          case R of
            canOK:
              begin
                dummy(id, BUF, dlc, Flag, HelpFlag.canMSG_Flag, myTime);
    
                // Examine the Flag(HelpFlag) and do someting...
                if MycanMSG_RTR in HelpFlag.canMSG_Flag then
                  Memo.Lines.Add('RX Flag: <MycanMSG_RTR>');
    
                if MycanMSG_STD in HelpFlag.canMSG_Flag then
                  Memo.Lines.Add('RX Flag: <MycanMSG_STD>');
    
                if MycanMSG_EXT in HelpFlag.canMSG_Flag then
                  Memo.Lines.Add('RX Flag: <MycanMSG_EXT>');
    
                if MycanMSG_ERROR_FRAME in HelpFlag.canMSG_Flag then
                  Memo.Lines.Add('RX Flag: <MycanMSG_ERROR_FRAME>');
    
                if MycanFDMSG_FDF in HelpFlag.canMSG_Flag then
                  Memo.Lines.Add('RX Flag: <MycanFDMSG_FDF>');
    
                if MycanFDMSG_BRS in HelpFlag.canMSG_Flag then
                  Memo.Lines.Add('RX Flag: <MycanFDMSG_BRS>');
    
                Memo.Lines.Add('RX ID:' + id.ToString + ' dlc:' + dlc.ToString + ' bytes :' +
                 MyConvert(BUF, dlc));
              end;
            canERR_NOMSG:
              begin
                Memo.Lines.Add('Ooops, no data????');
              end;
          else
            begin
              Memo.Lines.Add('Some error happened, check! ' + R.ToString);
            end;
          end;
    
          /// *********************************************************
          /// Section three, Finalizing
          /// *********************************************************
          // We are done
          Memo.Lines.Add('DONE, start the cleanup process');
    
          TX := canBusOff(TX_MyHnd);
          RX := canBusOff(RX_MyHnd);
          if MyErrorCheck(Memo, TX, RX, 'canBusOff') then
          begin
            exit
          end;
    
          TX := canClose(TX_MyHnd);
          RX := canClose(RX_MyHnd);
          if MyErrorCheck(Memo, TX, RX, 'canClose') then
          begin
            exit
          end;
    
          Memo.Lines.Add('If you can read this, everything worked!');
        end;
      end;
    
    Author Image

    Lars-G?ran Fredriksson

    Lars-G?ran FredrikssonÏÖÈÎÔÆº£ÓÎÏ· ABµÄÏÖ³¡Ó¦Óù¤³Ìʦ¡£ËûÓµÓеØÀíÐÅϢϵͳ£¨GIS£©ºÍÒ£¸ÐÁìÓòµÄ±³¾°£¬Ä¿Ç°×¨×¢ÓÚ½«Ôƺ£ÓÎÏ·¿ª·¢ÍŶӵÄרҵ֪ʶÓëÖÕ¶ËÓû§µÄʵ¼ÊÐèÇóÏà½áºÏ¡£Ëû¶ÔCAN¼¼ÊõµÄÈÈÇé¿É¼ûÒ»°ß£ºÈëÖ°Ê×ÖÜ£¬Ëû±ãÉè¼ÆÁËÒ»¿î»¥¶¯Ê½CAN֪ʶÎÊ´ðÓÎÏ·£¬Òý·¢Á˰칫ÊÒȫԱѰÕÒÕýÈ·´ð°¸µÄÈȳ±¡£´ËÍ⣬Ëû»¹ÊÇһλ¶Ô»·±£²¶Óã³äÂúÈÈÇéµÄÓæÃñ£¬ÖÂÁ¦ÓÚÑз¢ÐÂÐÍ»·±£²¶Óã¼¼Êõ¡£Ä¿Ç°£¬Ëû·ÅÉúµÄ×î´óÓãÖÖÊÇÒ»Î²ÖØÔ¼325¹«½ï£¨715°õ£©µÄÀ¶÷¢½ðǹÓã¡£

    ¡¾ÍøÕ¾µØÍ¼¡¿¡¾sitemap¡¿