python使用zlgcan


前言

程序猿总少不了尝试体验不一样的工具,在”能跑“但是有冲突的情况下,要么我改,要么还是我改…
今天分享一个python使用zlgcan的方法。


关联文件放置

首先需要将zlgcan中的zlgcan.dll,kerneldlls文件夹以及zlgcan.py转移到自己程序的根目录下,需注意DLL文件位数需要与python位数一致,如python32需要32位的DLL。
zlgcan

通道配置

# 创建对象实例
zcanlib = ZCAN()
# 打开通道OpenDevice(device_type =ZCAN_USBCAN2, device_index=0, reserved=0)
dev_handle = zcanlib.OpenDevice(ZCAN_USBCAN2, 0, 0)
# 检测是否打开成功
if dev_handle == INVALID_DEVICE_HANDLE:
   win32api.MessageBox(0, "Open Device failed", "Error")
   sys.exit(0)
    
chn_init_cfg = ZCAN_CHANNEL_INIT_CONFIG()
#	设置通道为CAN模式
chn_init_cfg.can_type = ZCAN_TYPE_CAN
chn_init_cfg.config.can.acc_mode = 0
chn_init_cfg.config.can.acc_mask = 0xFFFFFFFF

# 波特率设置,250k,具体参考表1
chn_init_cfg.config.can.timing0 = 1
chn_init_cfg.config.can.timing1 = 28

# 初始化通道InitCAN(device_handle, can_index, byref(init_config))
chn_handle = zcanlib.InitCAN(dev_handle, 0, chn_init_cfg)

if chn_handle is None:
	return None
	
# 将通道连接入总线
zcanlib.StartCAN(chn_handle)

return chn_handle

表1:波特率时序对照表
波特率

CAN发送

# Transmit(chn_handle, std_msg, len)
# TransmitFD(chn_handle, fd_msg, len)
# 需要提供通道句柄,发送的信息,长度(发送多组信息的组数)

# 创建CAN发送信息实例
msgs = (ZCAN_Transmit_Data * transmit_num)()
for i in range(transmit_num):
	# 发送方式,0=正常发送,1=单次发送,2=自发自收,3=单次自发自收。
	msgs[i].transmit_type = 2
	msgs[i].frame.eff = 0  # 扩展帧
	msgs[i].frame.rtr = 0  # 远程帧
	msgs[i].frame.can_id = i # CAN ID
	msgs[i].frame.can_dlc = 8 # 长度
	# 根据CAN数据长度(dlc)输入数据
	for j in range(msgs[i].frame.can_dlc):
		msgs[i].frame.data[j] = j

# 发送数据
ret = zcanlib.Transmit(chn_handle, msgs, transmit_num)


CAN接收

# Receive(chn_handle, rcv_num, wait_time)
# ReceiveFD(chn_handle,rcv_num, wait_time)
# 数据接收函数,需提供CAN/FD通道句柄,接收信息数,超时(默认:-1 永不超时)

# 获取CAN接收数
rcv_num = zcanlib.GetReceiveNum(chn_handle, ZCAN_TYPE_CAN)
rcv_canfd_num = zcanlib.GetReceiveNum(chn_handle, ZCAN_TYPE_CANFD)



if rcv_num:
    print("Receive CAN message number:%d" % rcv_num)
    # 
    rcv_msg, rcv_num = zcanlib.Receive(chn_handle, rcv_num)
         for i in range(rcv_num):
            print("[%d]:ts:%d, id:%d, dlc:%d, eff:%d, rtr:%d, data:%s" 
            % (i, rcv_msg[i].timestamp,
                rcv_msg[i].frame.can_id,
                rcv_msg[i].frame.can_dlc,
                rcv_msg[i].frame.eff,
                rcv_msg[i].frame.rtr,
                # 根据dlc循环输出数据
                ''.join(str(rcv_msg[i].frame.data[j]) + ' ' for j in range(rcv_msg[i].frame.can_dlc))
                ))

输出样式
output

Demo

from zlgcan import *
import win32api

def busOn(zcanlib):
	dev_handle = self.zcanlib.OpenDevice(ZCAN_USBCAN2, 0, 0)
	if dev_handle == INVALID_DEVICE_HANDLE:
		win32api.MessageBox(0, "Open Device failed", "Error")
		sys.exit(0)
	chn_init_cfg = ZCAN_CHANNEL_INIT_CONFIG()
	chn_init_cfg.can_type = ZCAN_TYPE_CAN
	chn_init_cfg.config.can.acc_mode = 0
	chn_init_cfg.config.can.acc_mask = 0xFFFFFFFF
	chn_init_cfg.config.can.timing0 = 1
	chn_init_cfg.config.can.timing1 = 28
	chn_handle = self.zcanlib.InitCAN(dev_handle, 0, chn_init_cfg)
	if chn_handle is None:
		return None
	zcanlib.StartCAN(chn_handle)
	return chn_handle

if __name__ == "__main__":
	zcanlib = ZCAN()
	bus = busOn(zcanlib)
	
	# 发送数据
	msg = ZCAN_Transmit_Data()
	msg.transmit_type = 0
	msg.frame.eff = 0  # 1为扩展帧
	msg.frame.rtr = 0
	msg.frame.can_id = 123
	msg.frame.can_dlc = 8
	for j in range(8):
		msg.frame.data[j] = j
	zcanlib.Transmit(bus, msg, 1)
	
	# 接收数据
	msgs, r_num = self.zcanlib.Receive(bus, 1)
	if r_num:
		can_data = ""
		for byte in msgs[0].frame.data:
			can_data += "{:0>2X} ".format(byte)
		# 将报文处理为字符列表,8字节变为16个字符
        data_list = list(''.join(can_data.split()))
		print(data_list)

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值