使用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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。