目录[-]

目录:

  1. 触发设置
  2. Python连接ZCANPRO

——————————————————————————————————————————————————

一、触发设置

比如当前有2个通道,can0和can1,有一个场景,就是我想要在通道0发送一个报文0x100,当发送成功后,再发送一个报文0x101,实现步骤如下

ZCANPRO—高级设置—触发设置,添加一个规则

看响应结果,在通道0发送0x100报文后,通道1收到0x100报文;同时,在通道1发送报文0x100,通道0收到0x101

造成这样的情况很简单,看上图,目前使用的是双并联短路接法,can0和can1通道的线路接在一起,导致通道0发送,通道1接收,但由于没有连接真实设备,所以只能造成这种情况

——————————————————————————————————————————————————

二、Python连接ZCANPRO

1、在ZLG官网,下载依赖文件:

2、Demo版下载并压缩后的目录结构

  • 其中 zlgcan.py 是原版的Demo,新建的一个文件 ZLG_POST.py 是自己拆功能键的文件,目录如下

3、Demo版代码提取

  • 本地使用的USB-CAN || 设备,包含在USB-CAN型号集合里
from zlgcan import *
import time


# 初始化数据
def reset_can_channel(zcanlib, dev_handle):
    # 停止通道
    zcanlib.ResetCAN(dev_handle)
    # 重新初始化
    chn_init_cfg = ZCAN_CHANNEL_INIT_CONFIG()
    chn_init_cfg.can_type = ZCAN_TYPE_CAN
    chn_init_cfg.config.can.timing0 = 0x00  # 波特率相关参数(低位) 500Kbps  波特率
    chn_init_cfg.config.can.timing1 = 0x1C  # 波特率相关参数(高位)
    chn_handle = zcanlib.InitCAN(dev_handle, 0, chn_init_cfg)
    zcanlib.StartCAN(chn_handle)
    return chn_handle

# 主程序
def main():
    # 周立功官方主控制类,用于操作USBCAN硬件,ZCAN()调用周立功底层DLL(zlgcan.dll),该DLL负责与硬件通信
    # 1、创建控制实例
    zcanlib = ZCAN()
    # 2、打开 ZCAN_USB 设备
    dev_handle = zcanlib.OpenDevice(ZCAN_USBCAN2, 0, 0)
    if dev_handle == INVALID_DEVICE_HANDLE:
        print("打开设备失败!")
        return

    # 3、初始化 CAN 通道
    chn_handle = reset_can_channel(zcanlib, dev_handle)
    # 3.1 判断通道是否连接
    if chn_handle == INVALID_CHANNEL_HANDLE:
        print("初始化通道失败!")
        zcanlib.CloseDevice(dev_handle)
        return

    # 4、启动通道
    zcanlib.StartCAN(chn_handle)
    print("设备已启动,等待2秒...")
    time.sleep(2)

    # 发送自发自收报文(单个报文)
    # msgs = (ZCAN_Transmit_Data * 1)()
    # msgs[0].frame.can_id = 0x100
    # msgs[0].frame.can_dlc = 8
    # msgs[0].frame.data = (00, 11, 22, 33, 44, 55, 66, 77)
    # # 第一次:自发自收(可能被覆盖)
    # msgs[0].transmit_type = 2  # 自发自收
    # zcanlib.Transmit(chn_handle, msgs, 1)
    # # 第二次:正常发送(刷新队列)
    # msgs[0].transmit_type = 0  # 正常发送
    # ret = zcanlib.Transmit(chn_handle, msgs, 1)
    # 报文发送数量
    # transmit_num = 10

    # 5、发送报文
    msgs = (ZCAN_Transmit_Data * len(frame_list))()
    # print(memset(byref(msgs), 0, sizeof(msgs)))

    # 5.1 普通发送,刷新队列
    msgs[0].transmit_type = 0  # 正常发送
    zcanlib.Transmit(chn_handle, msgs, 1)
    # 5.2 主要运行报文内容
    for i in range(len(frame_list)):
        # print(i)
        msgs[i].transmit_type = 2  # 2自发自收,0普通发送
        msgs[i].frame.eff = 0  # extern frame
        msgs[i].frame.rtr = 0  # remote frame
        msgs[i].frame.can_id = 0x200  # 报文ID
        # msgs[i].frame.data = (00, 11, 22, 33, 44, 55, 66, 77)
        msgs[i].frame.can_dlc = 8  # 报文长度
        msgs[i].frame.__pad = 0x80  # 队列发送,0x80单位ms,0xc0单位是100us
        msgs[i].frame.__res0 = 0x64  # 帧间隔低位,定时100ms,6*16^1+4*16^0=96+4=100
        msgs[i].frame.__res1 = 0xc8  # 帧间隔高位,定时200ms,12*16^1+8*16^0=192+8=200
        # 报文内容
        msgs[i].frame.data = frame_list[i]
    # 5.3 发送报文
    ret = zcanlib.Transmit(chn_handle, msgs, len(frame_list))
    print(f"发送结果: {ret} (0=成功)")


    # 5.4 接收数据(增加重试机制)
    max_retry = 3
    for _ in range(max_retry):
        # 此时可以读到第一次的自发自收报文
        rcv_num = zcanlib.GetReceiveNum(chn_handle, ZCAN_TYPE_CAN)
        # print(rcv_num)
        if rcv_num > 0:
            rcv_msg, _ = zcanlib.Receive(chn_handle, rcv_num)
            for i in range(rcv_num):
                print(f"收到报文: ID={hex(rcv_msg[i].frame.can_id)}, Data={list(rcv_msg[i].frame.data[:rcv_msg[i].frame.can_dlc])}")
            break
        time.sleep(0.5)  # 每次重试间隔500ms
    else:
        print("未收到数据")

    # 6、清除库接收缓存区
    zcanlib.ClearBuffer(dev_handle)
    # 6.1 启动通道前复位(关键!)
    zcanlib.ResetCAN(dev_handle)  # 复位通道0
    time.sleep(2)  # 关键!等待硬件完全复位
    # 6.2 关闭设备
    zcanlib.CloseDevice(dev_handle)

if __name__ == "__main__":
    frame_list=[(0,1,2,3,4,5,6,7),
                (1,2,3,4,5,6,7,8),
                (10,20,30,40,50,60,70)]
    main()

波特率对照表

4、Python 与 CAN盒连接

  • 在保证本地使用 ZCANPRO 可以成功连接到硬件并且可以正确发送和接收报文后,就可以尝试Python连接了,运行后,显示如下信息

5、异常情况解析:

  • 设备连接失败:本地是否存在已连接CAN盒的情况,比如ZCANPRO已经连接了硬件设备,而此时还用python调用,就会提示错误,需要在软件关闭通道并停止设备
  • python运行库报错,如找不到zlgcan文件等等情况,都是python相关的错误,一一排查即可解决,python需要用到至少3.6版本
  • 运行时,第一次运行返回报文,但是第二次运行就不返回报文,这是由于,当transmit_type=2(自发自收)时,报文会同时写入“发送队列”和“接收队列”,如果队列满时,硬件暂停发送,但已存入接收队列的自发自收报文仍存在,所以需要再发一次“正常报文”,强制刷新队列,否则永远也不能得到响应报文

 

END