使用的设备是 usbcan-2e-u,以下是全部的封装代码
import os
from ctypes import *
# 配置结构体
class _VCI_INIT_CONFIG(Structure):
_fields_ = [('AccCode', c_ulong),
('AccMask', c_ulong),
('Reserved', c_ulong),
('Filter', c_ubyte),
('Timing0', c_ubyte),
('Timing1', c_ubyte),
('Mode', c_ubyte)]
# 发送帧结构体
class _VCI_CAN_OBJ(Structure):
_fields_ = [('ID', c_uint),
('TimeStamp', c_uint),
('TimeFlag', c_byte),
('SendType', c_byte),
('RemoteFlag', c_byte),
('ExternFlag', c_byte),
('DataLen', c_byte),
('Data', c_byte*8),
('Reserved', c_byte*3)]
# 接收帧结构体
class _RX_CAN_OBJ(Structure):
_fields_ = [('ID', c_uint),
('TimeStamp', c_uint),
('TimeFlag', c_byte),
('SendType', c_byte),
('RemoteFlag', c_byte),
('ExternFlag', c_byte),
('DataLen', c_byte),
('Data', c_byte*8),
('Reserved', c_byte*3)]
class USBCAN_2E_U:
def __init__(self):
root = os.path.dirname(os.path.realpath(__file__))
path = os.path.join(root, "lib\ControlCAN.dll")
self.canLib = windll.LoadLibrary(path)
self.nDeviceType = 21 # USBCAN-2E-U
self.nDeviceInd = 0 # 索引号0
self.nReserved = 0 # 保留
self.nCANInd = 1 # can通道号
# 初始化配置信息
self.vic = _VCI_INIT_CONFIG()
self.vic.AccCode = 0x00000000
self.vic.AccMask = 0xffffffff
self.vic.Filter = 0
self.vic.Timing0 = 0x01
self.vic.Timing1 = 0x1c
self.vic.Mode = 0
# 接收帧缓冲区
self.receivebuf = (_RX_CAN_OBJ * 100)()
# 初始化usbcan,同时开启双通道
self.init_device()
# 初始化并开启设备
def init_device(self):
print("下面执行操作返回“1”表示操作成功!")
print('打开设备: %d' % (self.canLib.VCI_OpenDevice(self.nDeviceType, self.nDeviceInd, self.nReserved)))
# 开启通道1
print('设置波特率: %d' % (self.canLib.VCI_SetReference(self.nDeviceType, self.nDeviceInd, self.nCANInd, 0, pointer(c_int(0x060003)))))
print('初始化: %d' % (self.canLib.VCI_InitCAN(self.nDeviceType, self.nDeviceInd, self.nCANInd, pointer(self.vic)))) # 注意,SetRefernce必须在InitCan之前
print('启动: %d' % (self.canLib.VCI_StartCAN(self.nDeviceType, self.nDeviceInd, self.nCANInd)))
print('清空缓冲区: %d' % (self.canLib.VCI_ClearBuffer(self.nDeviceType, self.nDeviceInd, self.nCANInd)))
# 开启通道0
print('设置波特率: %d' % (self.canLib.VCI_SetReference(self.nDeviceType, self.nDeviceInd, 0, 0, pointer(c_int(0x060003)))))
print('初始化: %d' % (self.canLib.VCI_InitCAN(self.nDeviceType, self.nDeviceInd, 0, pointer(self.vic)))) # 注意,SetRefernce必须在InitCan之前
print('启动: %d' % (self.canLib.VCI_StartCAN(self.nDeviceType, self.nDeviceInd, 0)))
print('清空缓冲区: %d' % (self.canLib.VCI_ClearBuffer(self.nDeviceType, self.nDeviceInd, 0)))
# 发送数据
def send_data(self, id, data):
# 发送帧
self.vco = _VCI_CAN_OBJ()
# self.vco.ID = 0x00000001
self.vco.ID = id
self.vco.SendType = 0
self.vco.RemoteFlag = 0
self.vco.ExternFlag = 0
self.vco.DataLen = 8
# vco.Data = (225, 2, 3, 4, 5, 6, 7, 8)
# data为元组,每个元素为0-255,表示一个字节的数据
self.vco.Data = data
ret = self.canLib.VCI_Transmit(self.nDeviceType, self.nDeviceInd, self.nCANInd, pointer(self.vco), 1)
print("transmit:", ret)
# # 接收数据
# ret = self.canLib.VCI_Receive(self.nDeviceType, self.nDeviceInd, 0, pointer(self.rxdata), 1, 0)
# print("receive:", ret)
# if ret > 0:
# print("数据: ", bytearray(self.rxdata.Data).hex())
# 接收数据
def receive_data(self):
num = self.canLib.GetReceiveNum(self.nDeviceType, self.nDeviceInd, 0)
if num>0:
ret = self.canLib.VCI_Receive(self.nDeviceType, self.nDeviceInd, 0, pointer(self.receivebuf), 100, 0)
print("receive:", ret)
if ret > 0:
return ret, self.receivebuf
# for i in ret:
# print("数据: ", bytearray(self.receivebuf[i].Data).hex())
# 关闭设备
def close_device(self):
status = self.canLib.VCI_CloseDevice(self.nDeviceType, self.nDeviceInd)
print('关闭:',status)
代码解析:
导入动态链接库
root = os.path.dirname(os.path.realpath(__file__))
path = os.path.join(root, "lib\ControlCAN.dll")
我存放的位置:
修改下面的数字可以更换设备型号,可以查阅官方文档得到设备号(USBCAN-E/2E-U 用户手册 (zlg.cn))
self.nDeviceType = 21 # USBCAN-2E-U