//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
/*
下面是具体的调用动态库的做法,采用的是动态加载的方法,主要就是在程序初始化的
时候从动态库中取得各个函数的地址并保存起来,然后在需要的时候调用就可以了,最后在
程序退出的时候释放掉打开的动态库句柄就行。
*/
//首先定义需要用到的数据结构
//1.ZLGCAN系列接口卡信息的数据类型。
typedef struct _VCI_BOARD_INFO{
USHORT hw_Version;
USHORT fw_Version;
USHORT dr_Version;
USHORT in_Version;
USHORT irq_Num;
BYTE can_Num;
CHAR str_Serial_Num[20];
CHAR str_hw_Type[40];
USHORT Reserved[4];
} VCI_BOARD_INFO,*PVCI_BOARD_INFO;
//2.定义CAN信息帧的数据类型。
typedef struct _VCI_CAN_OBJ{
UINT ID;
UINT TimeStamp;
BYTE TimeFlag;
BYTE SendType;
BYTE RemoteFlag;//是否是远程帧
BYTE ExternFlag;//是否是扩展帧
BYTE DataLen;
BYTE Data[8];
BYTE Reserved[3];
}VCI_CAN_OBJ,*PVCI_CAN_OBJ;
//3.定义CAN控制器状态的数据类型。
typedef struct _VCI_CAN_STATUS{
UCHAR ErrInterrupt;
UCHAR regMode;
UCHAR regStatus;
UCHAR regALCapture;
UCHAR regECCapture;
UCHAR regEWLimit;
UCHAR regRECounter;
UCHAR regTECounter;
DWORD Reserved;
}VCI_CAN_STATUS,*PVCI_CAN_STATUS;
//4.定义错误信息的数据类型。
typedef struct _ERR_INFO{
UINT ErrCode;
BYTE Passive_ErrData[3];
BYTE ArLost_ErrData;
} VCI_ERR_INFO,*PVCI_ERR_INFO;
//5.定义初始化CAN的数据类型
typedef struct _INIT_CONFIG{
DWORD AccCode;
DWORD AccMask;
DWORD Reserved;
UCHAR Filter;
UCHAR Timing0;
UCHAR Timing1;
UCHAR Mode;
}VCI_INIT_CONFIG,*PVCI_INIT_CONFIG;
//接下来定义要导入的函数类型
//根据ControlCAN.h中的函数声明定义函数指针类型
//////////////////////////////////////////////////////////////////////////
typedef DWORD (CALLBACK* LPVCI_OpenDevice)(DWORD,DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_CloseDevice)(DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_InitCan)(DWORD,DWORD,DWORD,PVCI_INIT_CONFIG);
typedef DWORD (CALLBACK* LPVCI_ReadBoardInfo)(DWORD,DWORD,PVCI_BOARD_INFO);
typedef DWORD (CALLBACK* LPVCI_ReadErrInfo)(DWORD,DWORD,DWORD,PVCI_ERR_INFO);
typedef DWORD (CALLBACK* LPVCI_ReadCanStatus)(DWORD,DWORD,DWORD,PVCI_CAN_STATUS);
typedef DWORD (CALLBACK* LPVCI_GetReference)(DWORD,DWORD,DWORD,DWORD,PVOID);
typedef DWORD (CALLBACK* LPVCI_SetReference)(DWORD,DWORD,DWORD,DWORD,PVOID);
typedef ULONG (CALLBACK* LPVCI_GetReceiveNum)(DWORD,DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_ClearBuffer)(DWORD,DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_StartCAN)(DWORD,DWORD,DWORD);
typedef DWORD (CALLBACK* LPVCI_ResetCAN)(DWORD,DWORD,DWORD);
typedef ULONG (CALLBACK* LPVCI_Transmit)(DWORD,DWORD,DWORD,PVCI_CAN_OBJ,ULONG);
typedef ULONG (CALLBACK* LPVCI_Receive)(DWORD,DWORD,DWORD,PVCI_CAN_OBJ,ULONG,INT);
//////////////////////////////////////////////////////////////////////////
HANDLE m_hDLL;//用来保存打开的动态库句柄
//接口函数指针
LPVCI_OpenDevice VCI_OpenDevice;
LPVCI_CloseDevice VCI_CloseDevice;
LPVCI_InitCan VCI_InitCAN;
LPVCI_ReadBoardInfo VCI_ReadBoardInfo;
LPVCI_ReadErrInfo VCI_ReadErrInfo;
LPVCI_ReadCanStatus VCI_ReadCanStatus;
LPVCI_GetReference VCI_GetReference;
LPVCI_SetReference VCI_SetReference;
LPVCI_GetReceiveNum VCI_GetReceiveNum;
LPVCI_ClearBuffer VCI_ClearBuffer;
LPVCI_StartCAN VCI_StartCAN;
LPVCI_ResetCAN VCI_ResetCAN;
LPVCI_Transmit VCI_Transmit;
LPVCI_Receive VCI_Receive;
////////////////////////////////////////////////////////////////////////////
DWORD m_devtype=4;//USBCAN2类型号
DWORD m_devind=0;
DWORD m_cannum=0;
int m_connect=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
m_hDLL = LoadLibrary("ControlCAN.dll");//打开动态库
//取得函数地址
VCI_OpenDevice=(LPVCI_OpenDevice)GetProcAddress(m_hDLL,"VCI_OpenDevice");
VCI_CloseDevice=(LPVCI_CloseDevice)GetProcAddress(m_hDLL,"VCI_CloseDevice");
VCI_InitCAN=(LPVCI_InitCan)GetProcAddress(m_hDLL,"VCI_InitCAN");
VCI_ReadBoardInfo=(LPVCI_ReadBoardInfo)GetProcAddress(m_hDLL,"VCI_ReadBoardInfo");
VCI_ReadErrInfo=(LPVCI_ReadErrInfo)GetProcAddress(m_hDLL,"VCI_ReadErrInfo");
VCI_ReadCanStatus=(LPVCI_ReadCanStatus)GetProcAddress(m_hDLL,"VCI_ReadCANStatus");
VCI_GetReference=(LPVCI_GetReference)GetProcAddress(m_hDLL,"VCI_GetReference");
VCI_SetReference=(LPVCI_SetReference)GetProcAddress(m_hDLL,"VCI_SetReference");
VCI_GetReceiveNum=(LPVCI_GetReceiveNum)GetProcAddress(m_hDLL,"VCI_GetReceiveNum");
VCI_ClearBuffer=(LPVCI_ClearBuffer)GetProcAddress(m_hDLL,"VCI_ClearBuffer");
VCI_StartCAN=(LPVCI_StartCAN)GetProcAddress(m_hDLL,"VCI_StartCAN");
VCI_ResetCAN=(LPVCI_ResetCAN)GetProcAddress(m_hDLL,"VCI_ResetCAN");
VCI_Transmit=(LPVCI_Transmit)GetProcAddress(m_hDLL,"VCI_Transmit");
VCI_Receive=(LPVCI_Receive)GetProcAddress(m_hDLL,"VCI_Receive");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(m_connect==1)
{
m_connect=0;
WaitForSingleObject(m_readhandle,2000);
m_readhandle=NULL;
VCI_CloseDevice(m_devtype,m_devind);
}
FreeLibrary(m_hDLL);//释放动态库句柄
}
//---------------------------------------------------------------------------
void ReceiveThread(void *param)
{
TListBox *box=(TListBox*)param;
VCI_CAN_OBJ receivedata[50];
VCI_ERR_INFO errinfo;
int len,i;
AnsiString str,tmpstr;
while(1)
{
if(m_connect==0)
break;
Sleep(1);
len=VCI_Receive(m_devtype,m_devind,m_cannum,receivedata,50,200);
if(len<=0)
{
//注意:如果没有读到数据则必须调用此函数来读取出当前的错误码,
//千万不能省略这一步(即使你可能不想知道错误码是什么)
VCI_ReadErrInfo(m_devtype,m_devind,m_cannum,&errinfo);
}
else
{
for(i=0;i<len;i++)
{
str="接收到数据帧: ";
if(receivedata[i].TimeFlag==0)
tmpstr="时间标识:无 ";
else
tmpstr="时间标识:0x"+IntToHex((int)receivedata[i].TimeStamp,8)+" ";
str+=tmpstr;
tmpstr="帧ID:0x"+IntToHex((int)receivedata[i].ID,8)+" ";
str+=tmpstr;
str+="帧格式:";
if(receivedata[i].RemoteFlag==0)
tmpstr="数据帧 ";
else
tmpstr="远程帧 ";
str+=tmpstr;
str+="帧类型:";
if(receivedata[i].ExternFlag==0)
tmpstr="标准帧 ";
else
tmpstr="扩展帧 ";
str+=tmpstr;
box->Items->Add(str);
if(receivedata[i].RemoteFlag==0)
{
str="数据:";
if(receivedata[i].DataLen>8)
receivedata[i].DataLen=8;
for(int j=0;j<receivedata[i].DataLen;j++)
{
tmpstr=IntToHex((int)receivedata[i].Data[j],2)+" ";
str+=tmpstr;
}
box->Items->Add(str);
}
}
box->ItemIndex=box->Items->Count-1;
}
}
_endthread();
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(m_connect==1)
{
Button1->Caption ="连接";
m_connect=0;
WaitForSingleObject(m_readhandle,2000);
m_readhandle=NULL;
VCI_CloseDevice(m_devtype,m_devind);
return;
}
int index = ComboBox1->ItemIndex;
int cannum = ComboBox2->ItemIndex;
VCI_INIT_CONFIG initconfig;
initconfig.AccCode=StrToInt("0x"+Edit2->Text);
initconfig.AccMask=StrToInt("0x"+Edit3->Text);
initconfig.Timing0=StrToInt("0x"+Edit5->Text);
initconfig.Timing1=StrToInt

APei
- 粉丝: 96
最新资源
- 海康网络监控方案(可编辑修改word版).docx
- 物联网系统课程设计.doc
- 基于51单片机的超声波测距仪之倒车雷达作品设计毕业论文.doc
- 知之为知之不知为不知MicrosoftPowerPoint演示文稿.ppt
- 系统安全评价.pptx
- litemall-移动应用开发资源
- 基于sas软件以北大光华管理学院教学评估为例.pptx
- 中远集团电子商务发展战略.pptx
- 51单片机-单片机开发资源
- 企业信息化的规划与实施.doc
- 网络的安全教育主题班会国旗下讲话发言建议书.docx
- 广州市财政局计算机网络设备采购工程技术规范书.doc
- 如何撰写有吸引力的网络推广文案.docx
- 算法初步程序框图与算法的基本逻辑结构.pptx
- 物联网产业发展规划纲要.docx
- 微型计算机控制技术试卷.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


