MFC动态库项目开发

这是一个关于MFC动态库项目的开发记录,包括读取配置文件(CAN和IO)、初始化CAN卡、设置AD及IO板卡、电源控制以及定时发送和接收CAN数据。主要涉及Excel文件读取、动态库导出函数的声明、设备初始化和数据通信等技术。
摘要由CSDN通过智能技术生成

第一个完整自己做的项目,记录一下

一、功能概述

通过调用DLL,可以读取配置文件的数据,定时发送CAN数据,实时接收CAN数据。实现2362、8602、8201的初始化,并可以通过参数控制某个通道的输入/输出。实现对电源的远程控制(程序控制)。

二、主要函数介绍

(1)Can_Read_excel(float temp[]);//读取can配置文件,参数是给dataname对应模型的值赋值。

(2)Io_Read_excel();//读取IO配置文件

(3)OninitCan1();//初始化Can1

(4)OninitCan2();//初始化Can2

(5)OninitAD_Io();//初始化所有AD、Io板卡

(6)SetIo2362(int IsPort_2362,int IsStatus_2362);//设置2362某管脚高低电平,参数:通道(0-47),状态0/1

(7)SetAD8201(int IsVolt_8201,int IsWritePort_8201);//模拟量输出,参数:电压(0-4095),输出通道(0-3)

(8)SetAD8602_1(int IsVolt_8602,int IsWritePort_8602,int IsReadPort_8602);//设置8602的输出通道及输出电压和采集的通道,参数:输出电压(0-4095),输出通道(0-3),采集通道(0-31)

(9)CTimer:定时器的回调函数,can数据发送的实现函数,实现定时发送can数据

(10)Rev_CAN_IO_thread():接收线程函数,实现实时接收数据

(11)Recv_Send();//用于启动接收线程和定时器,DLL供外部调用的接口

(12)Power(int Power_volt,int Power_curr,int com);电源控制函数,参数:设置电源电压值、电流值、与电源通信的串口。

三、具体实现

1.动态库的生成和使用

MFC->MFC DLL之后选择你需要的类型。

为了让dll导出函数,需要在每一个需要被导出的函数前面加上标识符:__declspec(dllexport)

在编译链接时,C++会按照自己的规则篡改函数的名称,这一过程称为“名字改编”。这会导致不同的编译器、不同的语言下调用dll发生问题。因此我们希望动态链接库文件在编译时,导出函数的名称不要发生变化。
为了实现这一目的,可以再定义导出函数时加上限定符:extern “C”,如

extern "C" { void __declspec(dllexport)__stdcall fun(){......}; }

2.全局变量

     //CAN配置文件变量

注:使用vector容器需包含头文件vector

     vector<CString>m_can_dataname;

 vector<CString>m_send_id;

     vector<CString>m_id;

 vector<int>m_cycle_time;

 vector<int>m_start_bit;

 vector<double>m_length;

 vector<double>m_factor;

 vector<CString>m_byte_order;

     vector<int>m_offset;

 vector<CString>m_type;

 vector<double>m_db_dataname_value;//存储can数据库的dataname列对应的模型中的值

 vector<int>m_db_flag;//存储can数据库的s/r列,表示can数据时发送还是接收

 

 //IO配置文件变量

 vector<CString>m_io_dataname;

 vector<int>m_io_flag;

 vector<long>m_io_port;

 vector<int>m_io_low_high;

 vector<long>m_io_usemanuval;

 

 CApplication ExcelApp;

 CWorkbooks books;

 CWorkbook book;

 CWorksheets sheets;

 CWorksheet sheet;

 CRange range;

 HANDLE m_hDevice2362;//PCI2362采集开句柄

 HANDLE m_hDevice8602;//PCI8602采集开句柄

 HANDLE m_hDevice8201;//PCI8201采集开句柄

 HANDLE m_hDevice8602_2;//PCI8602采集开句柄

 CCanCtr m_PCI9840_CAN;//PCI9840控制对象

 CCanCtr m_PCI9840_CAN_2;//PCI9840控制对象

 PCI2362Ctr m_PCI2362;//PCI2362控制对象

     PCI8602Ctr m_PCI8602_2; //PCI8602控制对象

 PCI8602Ctr m_PCI8602; //PCI8602控制对象

  PCI8201Ctr m_PCI8201; //PCI8201控制对象

3.读取配置文件

void __declspec(dllexport)__stdcall Can_Read_excel(float temp[])

{

if (!ExcelApp.CreateDispatch(_T("Excel.Application"), NULL))

{

AfxMessageBox(_T("启动Excel服务器失败!"));

exit(1);

}

ExcelApp.put_Visible(TRUE);//可见

ExcelApp.put_UserControl(FALSE);//用户可控制

 

LPDISPATCH lpDisp=NULL;

COleVariant vResult;

COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);

//清空vector数据

m_db_dataname_value.clear();

m_can_dataname.clear();

    m_id.clear();

   m_send_id.clear();

 m_cycle_time.clear();

 m_start_bit.clear();

 m_length.clear();

 m_factor.clear();

 m_byte_order.clear();

     m_offset.clear();

 m_type.clear();

 m_db_flag.clear();

/*得到工作簿容器*/

books.AttachDispatch(ExcelApp.get_Workbooks());

CString str=_T("E:\\canconfig1.xls");//打开配置文件的路径

lpDisp=books.Open(str,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional);

//得到workbook

book.AttachDispatch(lpDisp);//打开一个Workbook或者创建一个Workbook

//得到worksheets

sheets.AttachDispatch(book.get_Worksheets());

//得到当前活跃sheet  

//如果有单元格正处于编辑状态中,此操作不能返回,会一直等待  

lpDisp = book.get_ActiveSheet();

sheet.AttachDispatch(lpDisp);

//获得使用的区域Range(区域)

CRange usedRange;

usedRange.AttachDispatch(sheet.get_UsedRange());

range.AttachDispatch(usedRange.get_Rows());

//获得使用的行数

long rownum=0;

rownum=range.get_Count();

//获得使用的列数

long columnum=0;

range.AttachDispatch(usedRange.get_Columns());

columnum=range.get_Count();

CString str2;

CString str1;

CString str3;

int m_test1;

double m_test2;

for(int i=2;i<rownum+1;i++)

{

 

//第一列数据

m_db_dataname_value.push_back(0.0);//push_back在数组的最后添加一个数据0.0

range.AttachDispatch(sheet.get_Cells());

range.AttachDispatch(range.get_Item(COleVariant((long)(i)), COleVariant((long)1)).pdispVal);

vResult = range.get_Value2();

m_can_dataname.push_back(vResult.bstrVal);//将数据添加到0后头

//str1=vResult.bstrVa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值