周立功、致远电子usbcan2代码开发配置过程

周立功、致远电子usbcan2代码开发配置过程 梳理基于致远电子USBCAN2的项目创建、环境配置以及模拟D520发送CAN报文的代码编写步骤。ZLGCAN二次开发说明/函数库/例程下载 连接https://manual.zlg.cn/web/#/152?page_id5332你现在需要按照「文件类型分类存放」的原则将ZLG致远电子的开发文件放入对应目录既要让Visual Studio编译器能找到头文件/库文件又要让程序运行时能调用动态库文件下面结合你的项目结构给出精准操作步骤创建 控制台应用C 项目第一步先整理ZLG开发文件先分类避免混乱先把你下载的ZLG开发资料中的文件按类型归类明确核心文件文件类型核心文件用途头文件.hzlgcan.h、canframe.h等让编译器识别ZCAN相关函数/结构体静态库文件.libzlgcan.lib编译时链接CAN库接口动态库文件.dllzlgcan.dll程序运行时调用CAN设备功能内核依赖文件夹kerneldlls整个文件夹支撑zlgcan.dll运行的底层依赖其他可选文件示例代码、帮助文档等参考使用无需放入项目目录第二步在项目根目录新建SDK文件夹统一存放头文件lib文件你的项目根目录是D:\......\ZLG_CAN\ConsoleApplication1进入该根目录新建一个文件夹命名为ZLG_SDK名称可自定义方便识别即可进入ZLG_SDK文件夹再新建两个子文件夹分别命名为include存放头文件.h和lib存放静态库.lib将ZLG开发资料中的所有.h文件复制到ZLG_SDK\include目录下将ZLG开发资料中的zlgcan.lib文件复制到ZLG_SDK\lib目录下。第三步存放动态库.dll和kerneldlls文件夹关键放可执行输出目录程序运行时需要加载zlgcan.dll和kerneldlls文件夹必须放入项目编译后的可执行文件输出目录你的项目有两个x64\Debug目录优先放入「外层核心输出目录」操作如下方案1优先放入外层x64\Debug推荐VS默认输出目录直接将以下文件/文件夹复制到D:\AppFile\铲运机代码资料\CAN\ZLG_CAN\ConsoleApplication1\x64\Debugzlgcan.dll动态库文件kerneldlls整个文件夹包含其内部所有文件不要拆分方案2额外备份到内层x64\Debug保险起见避免路径不匹配再将上述zlgcan.dll和kerneldlls文件夹复制到内层目录D:\AppFile\铲运机代码资料\CAN\ZLG_CAN\ConsoleApplication1\ConsoleApplication1\x64\Debug说明VS项目的输出目录可能因配置不同指向外层或内层x64\Debug两个目录都放入可避免“缺少dll文件”的运行错误。第四步验证文件存放结构确保无误存放完成后你的项目目录结构应如下关键节点标注D:. ├─ConsoleApplication1 项目子目录 │ └─x64 │ └─Debug 内层可执行目录已放zlgcan.dll kerneldlls ├─ZLG_SDK 新建的SDK文件夹存放头文件和lib │ ├─include zlgcan.h、canframe.h等 │ └─lib zlgcan.lib └─x64 └─Debug 外层可执行目录已放zlgcan.dll kerneldlls核心输出目录第五步衔接之前的项目属性配置关键让VS识别SDK文件文件存放完成后回到Visual Studio中右键你的项目ConsoleApplication1→「属性」按以下配置对应你新建的ZLG_SDK路径配置包含目录让编译器找到.h文件路径C/C → 常规 → 附加包含目录添加$(ProjectDir)ZLG_SDK\include$(ProjectDir)是VS内置变量自动对应项目根目录无需手动输入完整路径更灵活配置库目录让链接器找到.lib文件路径链接器 → 常规 → 附加库目录添加$(ProjectDir)ZLG_SDK\lib配置附加依赖项链接zlgcan.lib路径链接器 → 输入 → 附加依赖项添加zlgcan.lib补充注意事项不要随意修改ZLG文件的文件名如zlgcan.dll改为zlgcan1.dll否则程序会无法识别若后续切换Release模式发布版本需将zlgcan.dll和kerneldlls同样复制到x64\Release目录下若运行程序时提示“找不到zlgcan.dll”说明动态库放错了目录优先检查外层x64\Debug目录是否存在该文件。以下为我自己写的测试程序根据键盘不同按键发送不同报文内容可按需摘取改动。#includestdio.h#includewindows.h#includeprocess.h#includestring.h#includestdarg.h#defineZLG_CAN_API_ENABLE#defineUSBCAN2_SUPPORT#includezlgcan.h#includecanframe.h#includetypedef.h#includeconfig.h#defineDEVICE_TYPEZCAN_USBCAN2#defineDEVICE_INDEX0#defineCAN_INDEX0CRITICAL_SECTION g_printLock;/* 安全打印 */voidsafe_printf(constchar*fmt,...){EnterCriticalSection(g_printLock);va_list args;va_start(args,fmt);vprintf(fmt,args);va_end(args);LeaveCriticalSection(g_printLock);}/* 周期报文 *//* 1BB / 2BB / 3BB / 4BB / 73B */ZCAN_Transmit_Data g_frames[]{/* 0: 1BB 行走/作业 */{{MAKE_CAN_ID(0x1BB,0,0,0),8,0,0,0,{0,0,0,0,0,0,0x01,0x20}},0},/* 1: 2BB 点火/驻车/喇叭 */{{MAKE_CAN_ID(0x2BB,0,0,0),8,0,0,0,{0,0,0,0,0,0,0x04,0x07}},0},/* 2: 3BB */{{MAKE_CAN_ID(0x3BB,0,0,0),2,0,0,0,{0x00,0x0F}},0},/* 3: 4BB */{{MAKE_CAN_ID(0x4BB,0,0,0),7,0,0,0,{0x30,0x8A,0x03,0x00,0xFF,0xFF,0x00}},0},/* 4: 73B 初始化完成 */{{MAKE_CAN_ID(0x73B,0,0,0),1,0,0,0,{0x05}},0}};#defineIDX_1BB0#defineIDX_2BB1constUINT FRAME_COUNTsizeof(g_frames)/sizeof(g_frames[0]);/* 上电一次 5BB */ZCAN_Transmit_Data g_frame_5BB{{MAKE_CAN_ID(0x5BB,0,0,0),8,0,0,0,{0x60,0x00,0x28,0x01,0x00,0x35,0x00,0x08}},0};/* 1BB 键盘 */voidUpdate1BB(){BYTE*dg_frames[IDX_1BB].frame.data;memset(d,0,8);d[6]0x01;d[7]0x20;/* 刹车 */if(GetAsyncKeyState(VK_SPACE)0x8000){d[7]0x21;return;}/* 作业 */if(GetAsyncKeyState(W)0x8000)d[3]0x64;if(GetAsyncKeyState(S)0x8000)d[3]0x9C;if(GetAsyncKeyState(A)0x8000)d[4]0x64;if(GetAsyncKeyState(D)0x8000)d[4]0x9C;/* 行走 / 转向 */if(GetAsyncKeyState(VK_LEFT)0x8000){d[0]0x9C;d[7]0x22;}if(GetAsyncKeyState(VK_RIGHT)0x8000){d[0]0x64;d[7]0x22;}if(GetAsyncKeyState(VK_DOWN)0x8000){d[1]0x64;d[7]0x22;}if(GetAsyncKeyState(VK_UP)0x8000){d[1]0x9C;d[7]0x22;}}/* 2BB 键盘 */voidUpdate2BB(){BYTE*dg_frames[IDX_2BB].frame.data;memset(d,0,8);d[6]0x04;d[7]0x07;if(GetAsyncKeyState(F)0x8000)// 点火{d[2]0x01;d[3]0x01;}if(GetAsyncKeyState(P)0x8000)// 驻车{d[1]0x08;d[2]0x01;}if(GetAsyncKeyState(H)0x8000)// 喇叭{d[2]0x01;}}/* 接收线程 */unsigned__stdcallCanRxThread(void*param){CHANNEL_HANDLE hCan(CHANNEL_HANDLE)param;ZCAN_Receive_Data rx[100];safe_printf([CAN RX] 启动\n);while(1){UINT cntZCAN_Receive(hCan,rx,100,100);for(UINT i0;icnt;i){safe_printf([RX] %03X :,rx[i].frame.can_id0x7FF);for(intj0;jrx[i].frame.can_dlc;j)safe_printf( %02X,rx[i].frame.data[j]);safe_printf(\n);}}}/* 主函数 */intmain(){DEVICE_HANDLE hDev;CHANNEL_HANDLE hCan;ZCAN_CHANNEL_INIT_CONFIG cfg{0};InitializeCriticalSection(g_printLock);hDevZCAN_OpenDevice(DEVICE_TYPE,DEVICE_INDEX,0);if(hDevINVALID_DEVICE_HANDLE){safe_printf(CAN 打开失败\n);return-1;}cfg.can_typeTYPE_CAN;cfg.can.acc_code0;cfg.can.acc_mask0xFFFFFFFF;cfg.can.filter0;cfg.can.timing00x00;cfg.can.timing10x16;// 250Kcfg.can.mode0;// ★ 正常模式hCanZCAN_InitCAN(hDev,CAN_INDEX,cfg);ZCAN_StartCAN(hCan);safe_printf(CAN0 已启动正常模式\n);_beginthreadex(NULL,0,CanRxThread,hCan,0,NULL);ZCAN_Transmit(hCan,g_frame_5BB,1);safe_printf(已发送 0x5BB\n);while(!(GetAsyncKeyState(VK_ESCAPE)0x8000)){Update1BB();Update2BB();ZCAN_Transmit(hCan,g_frames,FRAME_COUNT);Sleep(50);}ZCAN_CloseDevice(hDev);DeleteCriticalSection(g_printLock);return0;}