The sample code provided by Zhou ligong Can PCI interface card is VC, VB and Delphi, without the example of C #. net. However, when using C # To call can APIs, these APIs are very strict in data type verification, so debugging is troublesome. After a while, I finally used C #2.0 vs.2008 to call the can API to send and receive data normally.
Now the API statement is provided as follows. If you have the same requirement, you can avoid a lot of detours.Public sealed class canapi <br/> {<br/> // interface card type definition <br/> Public Enum pcidevicetype <br/>{< br/> vci_pci5121 = 1, <br/> vci_pci9810 = 2, <br/> vci_usbcan1 = 3, <br/> vci_usbcan2 = 4, <br/> vci_pci9820 = 5, <br/> vci_can1_= 6, <br/> vci_pci5110 = 7, <br/> vci_canlite = 8, <br/> vci_isa9620 = 9, <br/> vci_isa5420 = 10, <br/> vci_pc104= can 11, <br/> vci_canete = 12, <br/> vci_dnp9810 = 13, <br/> vci_pci9840 = 14, <br/> vci_pc I9820i = 16 <br/>}</P> <p> // function call return status value <br/> Public static readonly int status_ OK = 1; <br/> Public static readonly int status_err = 0; </P> <p> Public Enum errortype <br/> {<br/> // can Error Code <br/> err_can_overflow = 0x0001, // CAN controller internal FIFO overflow <br/> err_can_erralarm = 0x0002, // CAN controller Error alert <br/> err_can_passive = 0x0004, // CAN controller negative error <br/> err_can_lose = 0x0008, // CAN controller arbitration loss <br/> err_can_buserr = 0x0010, // CAN controller bus error </P> <p> // Common error code <br/> err_deviceopened = 0x0100, // The device has been enabled <br/> err_deviceopen = 0x0200, // device startup error <br/> err_devicenotopen = 0x0400, // device not enabled <br/> err_bufferoverflow = 0x0800, // Buffer Overflow <br/> err_devicenotexist = 0x1000, // This device does not exist <br/> err_loadkerneldll = 0x2000, // failed to load dynamic library <br/> err_fail failed = 0X4000, // error code indicating failed Command Execution <br/> err_buffercreate = 0x8000 // insufficient memory </P> <p >}</P> <p> // 1. the data type of zlgcan interface card information. <Br/> [structlayout (layoutkind. sequential, charset = charset. ANSI)] <br/> public struct vci_board_info <br/> {<br/> Public ushort hw_version; <br/> Public ushort fw_version; <br/> Public ushort dr_version; <br/> Public ushort in_version; <br/> Public ushort irq_num; <br/> Public byte can_num; <br/> [system. runtime. interopservices. marshalasattribute (system. runtime. interopservices. unmanagedtype. byV Altstr, sizeconst = 20)] <br/> Public String str_serial_num; <br/> [system. runtime. interopservices. marshalasattribute (system. runtime. interopservices. unmanagedtype. byvaltstr, sizeconst = 40)] <br/> Public String str_hw_type; <br/> [system. runtime. interopservices. marshalasattribute (system. runtime. interopservices. unmanagedtype. byvalarray, sizeconst = 4, arraysubtype = system. runtime. interopservices. u Nmanagedtype. U2)] <br/> Public ushort [] reserved; <br/>}</P> <p> // 2. Define the Data Type of the CAN Information Frame. <Br/> [structlayout (layoutkind. sequential, charset = charset. ANSI)] <br/> public struct vci_can_obj <br/> {<br/> Public uint ID; <br/> Public uint timestamp; <br/> Public byte timeflag; <br/> Public byte sendtype; <br/> Public byte remoteflag; // whether it is a remote frame <br/> Public byte externflag; // whether it is an extended frame <br/> Public byte datalen; <br/> [financialas (unmanagedtype. byvalarray, sizeconst = 8, arraysubtype = unmanaged Type. i1)] <br/> Public byte [] data; <br/> [managed Alas (unmanagedtype. byvalarray, sizeconst = 3, arraysubtype = unmanagedtype. i1)] <br/> Public byte [] reserved; <br/>}</P> <p> // 3. defines the Data Type of the CAN controller status. <Br/> [structlayout (layoutkind. sequential, charset = charset. ANSI)] <br/> public struct vci_can_status <br/> {<br/> Public byte errinterrupt; <br/> Public byte regmode; <br/> Public byte regstatus; <br/> Public byte regalcapture; <br/> Public byte regeccapture; <br/> Public byte regewlimit; <br/> Public byte regrecounter; <br/> Public byte regtecounter; <br/> Public uint reserved; <br/>}</P> <p> // 4. Define the Data Type of the error message. <Br/> [structlayout (layoutkind. sequential, charset = charset. ANSI)] <br/> public struct vci_err_info <br/> {<br/> Public uint errcode; </P> <p> [system. runtime. interopservices. marshalasattribute (system. runtime. interopservices. unmanagedtype. byvalarray, sizeconst = 3, arraysubtype = system. runtime. interopservices. unmanagedtype. i1)] <br/> Public byte [] passive_errdata; </P> <p> Public byte arlost_errdata; <br/>}</P> <p> // 5. define the data type for can initialization <br/> [structlayout (layoutkind. sequential, charset = charset. ANSI)] <br/> public struct vci_init_config <br/> {<br/> Public uint acccode; <br/> Public uint accmask; <br/> Public uint reserved; <br/> Public byte filter; <br/> Public byte timing0; <br/> Public byte timing1; <br/> Public byte mode; <br/>}< br/> [structlayout (layoutkind. sequential, charset = charset. ANSI)] <br/> public struct chgdesipandport <br/> {<br/> [system. runtime. interopservices. marshalasattribute (system. runtime. interopservices. unmanagedtype. byvaltstr, sizeconst = 10)] <br/> Public String szpwd; </P> <p> [system. runtime. interopservices. marshalasattribute (system. runtime. interopservices. unmanagedtype. byvaltstr, sizeconst = 20)] <br/> Public String szdesip; </P> <p> Public int desport; <br/>}</P> <p> # region API function </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_opendevice ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_opendevice (uint devicetype, uint deviceind, uint reserved); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_closedevice ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_closedevice (uint devicetype, uint deviceind); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_initcan ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_initcan (uint devicetype, uint deviceind, uint canind, ref vci_init_config pinitconfig); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_readboardinfo ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_readboardinfo (uint devicetype, uint deviceind, ref vci_board_info pinfo); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_readerrinfo ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_readerrinfo (uint devicetype, uint deviceind, uint canind, ref vci_err_info perrinfo); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_readcanstatus ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_readcanstatus (uint devicetype, uint deviceind, uint canind, ref vci_can_status pcanstatus); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_getreference ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_getreference (uint devicetype, uint deviceind, uint canind, uint reftype, object pdata ); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_setreference ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_setreference (uint devicetype, uint deviceind, uint canind, uint reftype, object pdata ); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_getreceivenum ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_getreceivenum (uint devicetype, uint deviceind, uint canind); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_clearbuffer ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_clearbuffer (uint devicetype, uint deviceind, uint canind); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_startcan ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_startcan (uint devicetype, uint deviceind, uint canind); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_resetcan ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_resetcan (uint devicetype, uint deviceind, uint canind); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_transmit ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_transmit (uint devicetype, uint deviceind, uint canind, ref vci_can_obj psend, uint Len ); </P> <p> [dllimport ("controlcan. DLL ", entrypoint =" vci_receive ", charset = charset. ANSI, callingconvention = callingconvention. stdcall)] <br/> Public static extern uint vci_receive (uint devicetype, uint deviceind, uint canind, ref vci_can_obj preceive, uint Len, int waittime ); </P> <p> # endregion <br/>}
Note: during use, you must set controlcan. DLL and the kerneldlls folder and all the DLL files under it are added to the project, and the "Copy to output file" attribute of these files is set to "regular copy ".
Sending and receiving are prone to problems. The sample code is as follows:
Canapi. vci_can_obj [] frameinfo = new canapi. vci_can_obj [1]; <br/> frameinfo [0]. datalen = (byte) (ss. length); </P> <p> frameinfo [0]. data = data; <br/> frameinfo [0]. reserved = new byte [3]; </P> <p> frameinfo [0]. remoteflag = (byte) This. combframeformat. selectedindex; <br/> frameinfo [0]. externflag = (byte) This. combframetype. selectedindex; </P> <p> uint frameid = 0; <br/> If (! Uint.tryparse(this.txt frameid. text, system. globalization. numberstyles. allowhexspecifier, null, out frameid) <br/> frameid = 0; <br/> If (frameinfo [0]. externflag = 1) <br/>{< br/> frameinfo [0]. id = frameid; <br/>}< br/> else <br/> {<br/> frameinfo [0]. id = frameid | 0x0000ffff; <br/>}< br/> frameinfo [0]. sendtype = (byte) This. combsendformat. selectedindex; </P> <p> canapi. vci_transmit (this. mdevicetype, this. mdeviceindex, this. mcanindex, ref frameinfo [0], 1 );
Canapi. vci_can_obj [] frameinfos = new canapi. vci_can_obj [50]; <br/> Len = (INT) canapi. vci_receive (this. mdevicetype, this. mdeviceindex, this. mcanindex, ref frameinfos [0], 50,200); <br/> If (LEN <= 0) <br/>{< br/> // note: if no data is read, you must call this function to read the current error code. <br/> // do not omit this step (even if you do not want to know what the error code is) <br/> canapi. vci_readerrinfo (this. mdevicetype, this. mdeviceindex, this. mcanindex, ref errinfo); <br/>}< br/> else <br/> {... <br/>
Run the following command: