"""周立功USBCANFD200U数据读取并保存到BLF文件 (使用zlgcan Python库)此程序使用zlgcan Python库连接周立功USBCANFD200U设备,读取通道0的CAN数据,并保存到BLF文件。使用前请确保:1. 已安装python-can库: pip install python-can2. 已安装zlgcan库: pip install zlgcan3. 已安装周立功USBCANFD200U设备驱动4. 设备已正确连接到电脑"""from zlgcan import *import timeimport canfrom can import Messagedef read_canfd_and_save_to_blf(device_type, device_index, channel, blf_file_path): """ 读取CANFD设备数据并保存到BLF文件 Args: device_type: 设备类型 device_index: 设备索引 channel: 通道号 blf_file_path: BLF文件保存路径 """ print(f"开始读取周立功USBCANFD200U设备数据...") print(f"设备类型: USBCANFD-200U") print(f"设备索引: {device_index}") print(f"通道: {channel}") print(f"BLF文件: {blf_file_path}") print("=" * 70) try:1. 初始化zcanlib print("正在初始化zcanlib...") zcanlib = ZCAN() # 2. 打开设备 print("正在打开设备...") device_handle = zcanlib.OpenDevice(device_type, device_index, 0) if device_handle == INVALID_DEVICE_HANDLE: print("✗ 打开设备失败") return print(f"✓ 设备打开成功,句柄: {device_handle}") # 3. 获取设备信息 info = zcanlib.GetDeviceInf(device_handle) print(f"设备信息: {info}") # 4. 配置通道 print("正在配置通道...") # 设置仲裁域波特率 和 数据域波特率 ret = zcanlib.ZCAN_SetValue(device_handle, str(channel) + "/canfd_abit_baud_rate", "500000".encode("utf-8")) ret = zcanlib.ZCAN_SetValue(device_handle, str(channel) + "/canfd_dbit_baud_rate", "2000000".encode("utf-8")) if ret != ZCAN_STATUS_OK: print("✗ 设置波特率失败!") zcanlib.CloseDevice(device_handle) return # 终端电阻 ret = zcanlib.ZCAN_SetValue(device_handle, str(channel) + "/initenal_resistance", "1".encode("utf-8")) if ret != ZCAN_STATUS_OK: print("✗ 设置终端电阻失败!") zcanlib.CloseDevice(device_handle) return # 初始化通道 chn_init_cfg = ZCAN_CHANNEL_INIT_CONFIG() chn_init_cfg.can_type = ZCAN_TYPE_CANFD # USBCANFD 必须选择CANFD chn_init_cfg.config.canfd.mode = 0 # 0-正常模式 1-只听模式 chn_handle = zcanlib.InitCAN(device_handle, channel, chn_init_cfg) if chn_handle is None: print("✗ 初始化通道失败!") zcanlib.CloseDevice(device_handle) return # 启动通道 ret = zcanlib.StartCAN(chn_handle) if ret != ZCAN_STATUS_OK: print("✗ 启动通道失败!") zcanlib.CloseDevice(device_handle) return print(f"✓ 通道启动成功,句柄: {chn_handle}") # 5. 创建BLF文件记录器 logger = can.Logger(blf_file_path) print(f"✓ BLF文件创建成功: {blf_file_path}") message_count = 0 start_time = time.time() print("开始接收CAN数据...") print("按Ctrl+C停止") print("=" * 70) try: while True: # 读取CAN消息 rcv_num = zcanlib.GetReceiveNum(chn_handle, ZCAN_TYPE_CAN) if rcv_num: if rcv_num > 100: rcv_msg, rcv_num = zcanlib.Receive(chn_handle, 100, 100) else: rcv_msg, rcv_num = zcanlib.Receive(chn_handle, rcv_num, 100) for msg in rcv_msg[:rcv_num]: message_count += 1 frame = msg.frame direction = "TX" if frame._pad & 0x20 else "RX" frame_type = "扩展帧" if frame.can_id & (1 << 31) else "标准帧" frame_format = "远程帧" if frame.can_id & (1 << 30) else "数据帧" can_id = frame.can_id & 0x1FFFFFFF if frame.can_id & (1 << 30): data = [] dlc = 0 else: dlc = frame.can_dlc data = list(frame.data[:dlc]) # 转换为python-can的Message对象 can_msg = Message( arbitration_id=can_id, data=data, is_extended_id=(frame.can_id & (1 << 31) != 0), timestamp=time.time() ) # 写入BLF文件 logger(can_msg) # 显示接收到的消息 data_str = " ".join([f"{num:02X}" for num in data]) print(f"CAN消息 #{message_count}:") print(f" ID: 0x{can_id:X}") print(f" DLC: {dlc}") print(f" 数据: {data_str}") print(f" 方向: {direction}") print(f" 类型: {frame_type} {frame_format}") print(f" 时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}") print("-" * 70) # 读取CANFD消息 rcv_canfd_num = zcanlib.GetReceiveNum(chn_handle, ZCAN_TYPE_CANFD) if rcv_canfd_num: if rcv_canfd_num > 100: rcv_canfd_msgs, rcv_canfd_num = zcanlib.ReceiveFD(chn_handle, 100, 100) else: rcv_canfd_msgs, rcv_canfd_num = zcanlib.ReceiveFD(chn_handle, rcv_canfd_num, 100) for msg in rcv_canfd_msgs[:rcv_canfd_num]: message_count += 1 frame = msg.frame brs = "加速" if frame.flags & 0x1 else " " direction = "TX" if frame.flags & 0x20 else "RX" frame_type = "扩展帧" if frame.can_id & (1 << 31) else "标准帧" frame_format = "远程帧" if frame.can_id & (1 << 30) else "数据帧" can_id = frame.can_id & 0x1FFFFFFF data = list(frame.data[:frame.len]) # 转换为python-can的Message对象 can_msg = Message( arbitration_id=can_id, data=data, is_extended_id=(frame.can_id & (1 << 31) != 0), timestamp=time.time() ) # 写入BLF文件 logger(can_msg) # 显示接收到的消息 data_str = " ".join([f"{num:02X}" for num in data]) print(f"CANFD消息 #{message_count}:") print(f" ID: 0x{can_id:X}") print(f" DLC: {frame.len}") print(f" 数据: {data_str}") print(f" 方向: {direction}") print(f" 类型: {frame_type} {frame_format} {brs}") print(f" 时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}") print("-" * 70) # 每100条消息显示一次进度 #if message_count % 100 == 0: #print(f"... 已接收 {message_count} 条消息 ...") except KeyboardInterrupt: print("\n用户停止程序") finally: # 停止记录器 logger.stop() # 关闭通道 zcanlib.ResetCAN(chn_handle) # 关闭设备 zcanlib.CloseDevice(device_handle) elapsed_time = time.time() - start_time print("=" * 70) print(f"✓ 数据读取完成") print(f"✓ 共接收 {message_count} 条CAN消息") print(f"✓ 数据已保存到: {blf_file_path}") print(f"✓ 运行时间: {elapsed_time:.2f} 秒") print("=" * 70) except Exception as e: print(f"✗ 发生错误: {e}") import traceback traceback.print_exc()def main(): """ 主函数 """ print("周立功USBCANFD200U数据读取工具 (使用zlgcan Python库)") print("=" * 70) # 设备配置 device_type = ZCAN_USBCANFD_200U device_index = 0 # 设备索引,通常为0 channel = 0 # 通道0 # BLF文件路径 blf_file_path = input("请输入BLF文件保存路径 (默认: canfd_data_zlg_lib.blf): ") or "canfd_data_zlg_lib.blf" print("=" * 70) # 开始读取数据 read_canfd_and_save_to_blf(device_type, device_index, channel, blf_file_path)if name == "main": main()