使用python来调用CAN通讯的DLL实现方法
由于工作上的需要,经常要与USBCAN打交道,但厂家一般不会提供PYTHON的例子,于是自己摸索地写一个例子出来,以便在工作上随时可以使用PYTHON来测试CAN的功能。这里的例子是使用珠海创芯科技有限公司的USBCAN接口卡,他们提供一个ControlCAN.dll,也提供了一个.h文件,如下:
#ifndefCONTROLCAN_H #defineCONTROLCAN_H ////文件版本:v2.0020150920 //#include//使用CVI平台开发,请使用该语句。 //接口卡类型定义 #defineVCI_USBCAN1 3 #defineVCI_USBCAN2 4 #defineVCI_USBCAN2A 4 #defineVCI_USBCAN_E_U 20 #defineVCI_USBCAN_2E_U 21 //函数调用返回状态值 #define STATUS_OK 1 #defineSTATUS_ERR 0 /*------------------------------------------------兼容ZLG的函数及数据类型------------------------------------------------*/ //1.ZLGCAN系列接口卡信息的数据类型。 typedefstruct_VCI_BOARD_INFO{ unsignedshort hw_Version; unsignedshort fw_Version; unsignedshort dr_Version; unsignedshort in_Version; unsignedshort irq_Num; unsignedchar can_Num; char str_Serial_Num[20]; char str_hw_Type[40]; unsignedshort Reserved[4]; }VCI_BOARD_INFO,*PVCI_BOARD_INFO; //2.定义CAN信息帧的数据类型。 typedefstruct_VCI_CAN_OBJ{ unsignedint ID; unsignedint TimeStamp; unsignedchar TimeFlag; unsignedchar SendType; unsignedchar RemoteFlag;//是否是远程帧 unsignedchar ExternFlag;//是否是扩展帧 unsignedchar DataLen; unsignedchar Data[8]; unsignedchar Reserved[3]; }VCI_CAN_OBJ,*PVCI_CAN_OBJ; //3.定义初始化CAN的数据类型 typedefstruct_VCI_INIT_CONFIG{ unsignedlong AccCode; unsignedlong AccMask; unsignedlong Reserved; unsignedchar Filter; unsignedchar Timing0; unsignedchar Timing1; unsignedchar Mode; }VCI_INIT_CONFIG,*PVCI_INIT_CONFIG; /////////newaddstructforfilter///////// typedefstruct_VCI_FILTER_RECORD{ unsignedlong ExtFrame; //是否为扩展帧 unsignedlong Start; unsignedlong End; }VCI_FILTER_RECORD,*PVCI_FILTER_RECORD; #defineEXTERNC extern"C" EXTERNCunsignedlong__stdcallVCI_OpenDevice(unsignedlongDeviceType,unsignedlongDeviceInd,unsignedlongReserved); EXTERNCunsignedlong__stdcallVCI_CloseDevice(unsignedlongDeviceType,unsignedlongDeviceInd); EXTERNCunsignedlong__stdcallVCI_InitCAN(unsignedlongDeviceType,unsignedlongDeviceInd,unsignedlongCANInd,PVCI_INIT_CONFIGpInitConfig); EXTERNCunsignedlong__stdcallVCI_ReadBoardInfo(unsignedlongDeviceType,unsignedlongDeviceInd,PVCI_BOARD_INFOpInfo); EXTERNCunsignedlong__stdcallVCI_SetReference(unsignedlongDeviceType,unsignedlongDeviceInd,unsignedlongCANInd,unsignedlongRefType,void*pData); EXTERNCunsignedlong__stdcallVCI_GetReceiveNum(unsignedlongDeviceType,unsignedlongDeviceInd,unsignedlongCANInd); EXTERNCunsignedlong__stdcallVCI_ClearBuffer(unsignedlongDeviceType,unsignedlongDeviceInd,unsignedlongCANInd); EXTERNCunsignedlong__stdcallVCI_StartCAN(unsignedlongDeviceType,unsignedlongDeviceInd,unsignedlongCANInd); EXTERNCunsignedlong__stdcallVCI_ResetCAN(unsignedlongDeviceType,unsignedlongDeviceInd,unsignedlongCANInd); EXTERNCunsignedlong__stdcallVCI_Transmit(unsignedlongDeviceType,unsignedlongDeviceInd,unsignedlongCANInd,PVCI_CAN_OBJpSend,unsignedlongLen); EXTERNCunsignedlong__stdcallVCI_Receive(unsignedlongDeviceType,unsignedlongDeviceInd,unsignedlongCANInd,PVCI_CAN_OBJpReceive,unsignedlongLen,intWaitTime); /*------------------------------------------------其他补充函数及数据结构描述------------------------------------------------*/ //USB-CAN总线适配器板卡信息的数据类型1,该类型为VCI_FindUsbDevice函数的返回参数。 typedefstruct_VCI_BOARD_INFO1{ unsignedlong hw_Version; unsignedlong fw_Version; unsignedlong dr_Version; unsignedlong in_Version; unsignedlong irq_Num; unsignedchar can_Num; unsignedchar Reserved; char str_Serial_Num[8]; char str_hw_Type[16]; char str_Usb_Serial[4][4]; }VCI_BOARD_INFO1,*PVCI_BOARD_INFO1; //USB-CAN总线适配器板卡信息的数据类型2,该类型为VCI_FindUsbDevice函数的返回参数。为扩展更多的设备 typedefstruct_VCI_BOARD_INFO2{ unsignedlong hw_Version; unsignedlong fw_Version; unsignedlong dr_Version; unsignedlong in_Version; unsignedlong irq_Num; unsignedchar can_Num; unsignedchar Reserved; char str_Serial_Num[8]; char str_hw_Type[16]; char str_Usb_Serial[10][4]; }VCI_BOARD_INFO2,*PVCI_BOARD_INFO2; #defineEXTERNC extern"C" EXTERNCunsignedlong__stdcallVCI_GetReference2(unsignedlongDevType,unsignedlongDevIndex,unsignedlongCANIndex,unsignedlongReserved,unsignedchar*pData); EXTERNCunsignedlong__stdcallVCI_SetReference2(unsignedlongDevType,unsignedlongDevIndex,unsignedlongCANIndex,unsignedlongRefType,unsignedchar*pData); EXTERNCunsignedlong__stdcallVCI_ConnectDevice(unsignedlongDevType,unsignedlongDevIndex); EXTERNCunsignedlong__stdcallVCI_UsbDeviceReset(unsignedlongDevType,unsignedlongDevIndex,unsignedlongReserved); EXTERNCunsignedlong__stdcallVCI_FindUsbDevice(PVCI_BOARD_INFO1pInfo); EXTERNCunsignedlong__stdcallVCI_FindUsbDevice2(PVCI_BOARD_INFO2pInfo); #endif
要调用这些函数才可以完成工作,下面就来创建一个例子,从CAN的通道0向通道1来发送一帧CAN数据,例子代码如下:
#python3.632位
#https://blog.csdn.net/caimouse/article/details/51749579
#开发人员:蔡军生(QQ:9073204)深圳2018-3-25
#
fromctypesimport*
VCI_USBCAN2A=4
STATUS_OK=1
classVCI_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)
]
classVCI_CAN_OBJ(Structure):
_fields_=[("ID",c_uint),
("TimeStamp",c_uint),
("TimeFlag",c_ubyte),
("SendType",c_ubyte),
("RemoteFlag",c_ubyte),
("ExternFlag",c_ubyte),
("DataLen",c_ubyte),
("Data",c_ubyte*8),
("Reserved",c_ubyte*3)
]
CanDLLName='ControlCAN.dll'#DLL是32位的,必须使用32位的PYTHON
canDLL=windll.LoadLibrary(CanDLLName)
print(CanDLLName)
ret=canDLL.VCI_OpenDevice(VCI_USBCAN2A,0,0)
print(ret)
ifret!=STATUS_OK:
print('调用VCI_OpenDevice出错\r\n')
#初始0通道
vci_initconfig=VCI_INIT_CONFIG(0x80000008,0xFFFFFFFF,0,
2,0x00,0x1C,0)
ret=canDLL.VCI_InitCAN(VCI_USBCAN2A,0,0,byref(vci_initconfig))
ifret!=STATUS_OK:
print('调用VCI_InitCAN出错\r\n')
ret=canDLL.VCI_StartCAN(VCI_USBCAN2A,0,0)
ifret!=STATUS_OK:
print('调用VCI_StartCAN出错\r\n')
#初始1通道
ret=canDLL.VCI_InitCAN(VCI_USBCAN2A,0,1,byref(vci_initconfig))
ifret!=STATUS_OK:
print('调用VCI_InitCAN1出错\r\n')
ret=canDLL.VCI_StartCAN(VCI_USBCAN2A,0,1)
ifret!=STATUS_OK:
print('调用VCI_StartCAN1出错\r\n')
#通道0发送数据
ubyte_array=c_ubyte*8
a=ubyte_array(1,2,3,4,5,6,7,64)
ubyte_3array=c_ubyte*3
b=ubyte_3array(0,0,0)
vci_can_obj=VCI_CAN_OBJ(0x0,0,0,1,0,0,8,a,b)
ret=canDLL.VCI_Transmit(VCI_USBCAN2A,0,0,byref(vci_can_obj),1)
ifret!=STATUS_OK:
print('调用VCI_Transmit出错\r\n')
#通道1接收数据
a=ubyte_array(0,0,0,0,0,0,0,0)
vci_can_obj=VCI_CAN_OBJ(0x0,0,0,1,0,0,8,a,b)
ret=canDLL.VCI_Receive(VCI_USBCAN2A,0,1,byref(vci_can_obj),1,0)
print(ret)
whileret<=0:
print('调用VCI_Receive出错\r\n')
ret=canDLL.VCI_Receive(VCI_USBCAN2A,0,1,byref(vci_can_obj),1,0)
ifret>0:
print(vci_can_obj.DataLen)
print(list(vci_can_obj.Data))
#关闭
canDLL.VCI_CloseDevice(VCI_USBCAN2A,0)
运行结果输出如下:
ControlCAN.dll
1
1
8
[1,2,3,4,5,6,7,64]
可以看到从通道1里收通道0发过来的数据,达到这个程序的目的。
以上这篇使用python来调用CAN通讯的DLL实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。