文章目录
本文以 USBCANFD200U CAN盒为例
一、周立功官网下载函数库和例程
二、周立功设备及通道的打开和关闭
import zlgcan
def main():
# 创建can实例
zcanlib = zlgcan.ZCAN()
# 打开CAN设备
canDriveHandle = zcanlib.OpenDevice(zlgcan.ZCAN_USBCANFD_200U, 0, 0)
if canDriveHandle == zlgcan.INVALID_DEVICE_HANDLE:
print("打开设备失败!")
else:
print("打开设备成功!")
# 初始化
chn_cfg = zlgcan.ZCAN_CHANNEL_INIT_CONFIG()
chn0_handle = zcanlib.InitCAN(canDriveHandle, 0, chn_cfg)
# 启动CAN通道
zcanlib.StartCAN(chn0_handle)
# 关闭CAN设备
zcanlib.CloseDevice(canDriveHandle)
if __name__ == '__main__':
main()
三、获取设备信息
import zlgcan
def main():
# 创建can实例
zcanlib = zlgcan.ZCAN()
# 打开CAN设备
canDriveHandle = zcanlib.OpenDevice(zlgcan.ZCAN_USBCANFD_200U, 0, 0)
if canDriveHandle == zlgcan.INVALID_DEVICE_HANDLE:
print("打开设备失败!")
else:
print("打开设备成功!")
# 获取设备信息
deviceInfo = zcanlib.GetDeviceInf(canDriveHandle)
print("获取 硬件版本号:", deviceInfo.hw_version)
print("获取 固件版本号:", deviceInfo.fw_version)
print("获取 驱动程序版本号:", deviceInfo.dr_version)
print("获取 接口库版本号:", deviceInfo.in_version)
print("获取 支持通道数量:", deviceInfo.can_num)
print("获取 板卡的序列号:", deviceInfo.serial)
print("获取 硬件类型:", deviceInfo.hw_type)
# 关闭CAN设备
zcanlib.CloseDevice(canDriveHandle)
if __name__ == '__main__':
main()
四、通道配置
import zlgcan
def main():
# 创建can实例
zcanlib = zlgcan.ZCAN()
# 打开CAN设备
canDriveHandle = zcanlib.OpenDevice(zlgcan.ZCAN_USBCANFD_200U, 0, 0)
if canDriveHandle == zlgcan.INVALID_DEVICE_HANDLE:
print("打开设备失败!")
else:
print("打开设备成功!")
'''
仲裁域波特率:
"50K":12696558,
"100K":4307950,
"125K":4304830,
"250K":110526,
"500K":104286,
"800K":101946,
"1M":101166
数据域波特率:
"1M":8487694,
"2M":4260362,
"4M":66058,
"5M":66055
'''
# 初始化
chn0_cfg = zlgcan.ZCAN_CHANNEL_INIT_CONFIG()
chn0_cfg.can_type = zlgcan.ZCAN_TYPE_CANFD # 设置为 CANFD 协议
chn0_cfg.config.canfd.abit_timing = 104286 # 设置仲裁域波特率 500K
chn0_cfg.config.canfd.dbit_timing = 4260362 # 设置数据域波特率 2M
chn0_handle = zcanlib.InitCAN(canDriveHandle, 0, chn0_cfg)
# 启动CAN通道
zcanlib.StartCAN(chn0_handle)
# 关闭CAN设备
zcanlib.CloseDevice(canDriveHandle)
if __name__ == '__main__':
main()
五、获取接收的报文数据
import zlgcan
import time
def main():
# 创建can实例
zcanlib = zlgcan.ZCAN()
# 打开CAN设备
canDriveHandle = zcanlib.OpenDevice(zlgcan.ZCAN_USBCANFD_200U, 0, 0)
if canDriveHandle == zlgcan.INVALID_DEVICE_HANDLE:
print("打开设备失败!")
else:
print("打开设备成功!")
'''
仲裁域波特率:
"50K":12696558,
"100K":4307950,
"125K":4304830,
"250K":110526,
"500K":104286,
"800K":101946,
"1M":101166
数据域波特率:
"1M":8487694,
"2M":4260362,
"4M":66058,
"5M":66055
'''
# 初始化
chn0_cfg = zlgcan.ZCAN_CHANNEL_INIT_CONFIG()
chn0_cfg.can_type = zlgcan.ZCAN_TYPE_CANFD # 设置为 CANFD 协议
chn0_cfg.config.canfd.abit_timing = 104286 # 设置仲裁域波特率 500K
chn0_cfg.config.canfd.dbit_timing = 4260362 # 设置数据域波特率 2M
chn0_handle = zcanlib.InitCAN(canDriveHandle, 0, chn0_cfg)
# 启动CAN通道
zcanlib.StartCAN(chn0_handle)
total_ReceiveNum = 0 # 总共接收到的报文数量
while(1):
can_num = zcanlib.GetReceiveNum(chn0_handle, zlgcan.ZCAN_TYPE_CAN) # 获取缓冲区 CAN 报文数量
canfd_num = zcanlib.GetReceiveNum(chn0_handle, zlgcan.ZCAN_TYPE_CANFD) # # 获取缓冲区 CANFD 报文数量
if can_num != 0 or canfd_num != 0:
while can_num >= 1:
read_cnt = 10 if can_num >= 10 else can_num # 若接收缓冲区的报文数量小于10,就以缓冲区内的数量进行读取
can_msgs, act_num = zcanlib.Receive(chn0_handle, read_cnt, 5) # 5 表示缓冲区无数据,函数阻塞等待时间,单位毫秒
for i in range(act_num):
#update data
total_ReceiveNum += 1
rev_Data = " "
print("接收到的报文数量:", total_ReceiveNum)
print("报文ID:", can_msgs[i].frame.can_id)
print("数据长度:", can_msgs[i].frame.can_dlc)
for j in range(can_msgs[i].frame.can_dlc):
rev_Data = rev_Data + str(can_msgs[i].frame.data[j]) + " "
print("数据:", rev_Data)
else:
break
can_num -= act_num
while canfd_num >= 1:
read_cnt = 10 if canfd_num >= 10 else canfd_num # 若接收缓冲区的报文数量小于10,就以缓冲区内的数量进行读取
canfd_msgs, act_num = zcanlib.ReceiveFD(chn0_handle, read_cnt, 5) # 5 表示缓冲区无数据,函数阻塞等待时间,单位毫秒
for i in range(act_num):
#update data
total_ReceiveNum += 1
rev_Data = " "
print("接收到的报文数量:", total_ReceiveNum)
print("报文ID:", canfd_msgs[i].frame.can_id)
print("数据长度:", canfd_msgs[i].frame.len)
for j in range(canfd_msgs[i].frame.len):
rev_Data = rev_Data + str(canfd_msgs[i].frame.data[j]) + " "
print("数据:", rev_Data)
else:
break
canfd_num -= act_num
else:
# print("can_num = ", can_num, "canfd_num = ", canfd_num)
time.sleep(0.002) #wait 2ms
# 关闭CAN设备
zcanlib.CloseDevice(canDriveHandle)
if __name__ == '__main__':
main()
# 六、报文发送
import zlgcan
import time
def main():
# 创建can实例
zcanlib = zlgcan.ZCAN()
# 打开CAN设备
canDriveHandle = zcanlib.OpenDevice(zlgcan.ZCAN_USBCANFD_200U, 0, 0)
if canDriveHandle == zlgcan.INVALID_DEVICE_HANDLE:
print("打开设备失败!")
else:
print("打开设备成功!")
'''
仲裁域波特率:
"50K":12696558,
"100K":4307950,
"125K":4304830,
"250K":110526,
"500K":104286,
"800K":101946,
"1M":101166
数据域波特率:
"1M":8487694,
"2M":4260362,
"4M":66058,
"5M":66055
'''
# 初始化
chn0_cfg = zlgcan.ZCAN_CHANNEL_INIT_CONFIG()
chn0_cfg.can_type = zlgcan.ZCAN_TYPE_CANFD # 设置为 CANFD 协议
chn0_cfg.config.canfd.abit_timing = 104286 # 设置仲裁域波特率 500K
chn0_cfg.config.canfd.dbit_timing = 4260362 # 设置数据域波特率 2M
chn0_handle = zcanlib.InitCAN(canDriveHandle, 0, chn0_cfg)
# 启动CAN通道
zcanlib.StartCAN(chn0_handle)
total_ReceiveNum = 0 # 总共接收到的报文数量
while(1):
send_data = [1,2,3,4,5,6,7,8,9,10,11,12]
# 发送 CAN 报文
msg_Can = zlgcan.ZCAN_Transmit_Data()
msg_Can.transmit_type = 1 # 发送方式, 0=正常发送, 1=单次发送, 2=自发自收, 3=单次自发自收。
msg_Can.frame.can_id = 25
msg_Can.frame.can_dlc = 8
for i in range(msg_Can.frame.can_dlc):
msg_Can.frame.data[i] = send_data[i]
zcanlib.Transmit(chn0_handle, msg_Can, 1) # 1 表示报文数目
time.sleep(0.5) #wait 500ms
# 发送 CANFD 报文
msg_Canfd = zlgcan.ZCAN_TransmitFD_Data()
msg_Canfd.frame.can_id = 45
msg_Canfd.frame.len = 12
for i in range(msg_Canfd.frame.len):
msg_Canfd.frame.data[i] = send_data[i]
zcanlib.TransmitFD(chn0_handle, msg_Canfd, 1) # 1 表示报文数目
time.sleep(0.5) #wait 500ms
# 关闭CAN设备
zcanlib.CloseDevice(canDriveHandle)
if __name__ == '__main__':
main()
提示:加载 zlgcan.dll 时报错 - OSError: [WinError 193] %1 不是有效的 Win32 应用程序
这通常是由于 Python 解释器的位数(32 位或 64 位)与 DLL 文件的位数不兼容导致的。
可以通过以下 Python 代码来确认 Python 解释器的位数:
import struct
print(struct.calcsize("P") * 8)
运行上述代码后,如果输出结果是 32,则表示你使用的是 32 位的 Python 解释器;如果输出结果是 64,则表示使用的是 64 位的 Python 解释器。
提示:无法打开设备
从下载的 demo 中,找到 kerneldlls
文件夹,将其放到 zlgcan.py
同一路径下