本博客在具体的工程中,实现 Visual Studio(简称“上位机”) 与 TwinCAT(简称“下位机”) 之间的 ADS通讯。通过ADS通讯完成上位机与下位机之间的数据传输功能。
摘要(ABSTRACY)
目录:
第一章 绪论
1.1 ADS通讯定义
1.2 ADS通讯实现
第二章 ADS通讯技术研究
2.1 引言
2.2 Visual Studio (上位机)
2.2.1 MFC
2.2.2 ADS_C_ProgramDlg.h
2.2.3 ADS_C_ProgramDlg.cpp
2.3 TwinCAT (下位机)
2.3.1定义变量
2.3.2编写程序
第三章 总结
附件
ADS(Advanced Design System)即先进设计系统,它为设备之间的通讯提供路由。在TwinCAT PC 和Beckhoff 的CX、BX、BC 系列控制器中都包含TwinCAT 信息路由器。因此各个ADS 设备之间都能够交换数据和信息。
ADS通讯的实现思想并无难处,你可以简单理解两步:
有一种“A传B, B传C”的感觉。理解这个理论后,你就已经掌握ADS通讯的80%了。ADS通讯需要上位机程序与下位机程序在同一台电脑中运行,并且所有的执行过程都在上位机中编写。
这里将编写两部分工程文件,分别是 Visual Studio(上位机) 和 TwinCAT(下位机) 。
首先,在 Visual C++ 模板下建立一个名为:ADS_C_Program 的 MFC应用程序文件。
然后,分别对下面三个文件进行编程
在做工程之前,需要明白两件事:我要做的什么?怎么实现?
第一个问题可以在MFC文件中解决,本工程要求两机实现变量、数组和结构体的传输。所以设定界面如下图所示:
将 ADS_C_ProgramDlg.h 文件的编程分成分成三个模块
1.头文件
在添加头文件之前,我们需要添加链接库,以便实现通讯中用到的各种函数的直接调用。我们在左侧找到我们所建立的项目处,点击右键—>Properties 开始添加链接库,如下图所示:
选择 Configuration Properties -> Linker -> General -> Additional Library Directories,点击右边的按钮进入Additional Library Directories界面。如下图所示,添加我们的程序的所在目录( C:\TwinCAT\ADS Api\TcAdsDll\Lib ),点击确定。(本路径是以安装TWINCAT时的默认路径配置的,若用户在安装时选择自定义路径,则请用户自行修改) 。
再选择Linker->input->Additional Dependencies,点击右边的按钮进入Additional Dependencies界面。如下图所示添加我们的.Lib文件的文件名(TcAdsDll.lib),点击确定。再次点击确定,链接库添加完成。如下图所示:
这里共引入五个头文件,如下所示:
#include //标准的输入输出流头文件
#include //控制台输入输出头文件
#include //windowsAPI的函数声明和宏
#include"TcAdsDef.h" //ADS函数的声明
#include"TcAdsAPI.h" //结构体和常量的声明
1)#include
2)#include
3)#include
4)#include"TcAdsDef.h" 是: ADS函数的声明
5)#include"TcAdsAPI.h" 是: 结构体和常量的声明
TcAdsDef.h 和 TcAdsAPI.h 需要研究员自行添加。方法:在 TwinCAT 文件夹中全局搜索这两个文件名,复制到你所做的工程下。然后,在解决方案的头文件文件夹中将添加两文件。最后,在程序中引用。
2.全局变量
//ADS通信变量
long nErr;
long nPort;
AmsAddr Addr;
PAmsAddr pAddr;
//全局变量
//bool 变量
bool writebool;
bool readbool;
//Int
short writeint;
short readint;
//long
long writelong;
long readlong;
//single
float writesingle;
float readsingle;
//double
double writedouble;
double readdouble;
//string
char writestring;
char readstring;
//struct 涉及到占位问题,因此添加几个Dummy占位,没有具体意义。
typedef struct teststruct
{
bool test1; //1
bool dummy1;
bool dummy2;
bool dummy3;
short test2; //2
short dummy4;
long test3;
float test4;
double test5;
};
teststruct writestruct;
teststruct readstruct;
short writearray[5];
short readarray[5];
3.消息映射函数
消息映射函数几乎都是由添加MFC工具时自动生成,也有一些为用户自行定义函数。本工程消息映射函数列表如下所示:
protected:
HICON m_hIcon;
ULONG testlHdlVar;
char testszVar;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnDestroy();
afx_msg void OnBnClickedButton3();
afx_msg void OnBnClickedButton4();
afx_msg void OnBnClickedButton5();
afx_msg void OnBnClickedButton6();
afx_msg void OnBnClickedButton7();
afx_msg void OnBnClickedButton8();
afx_msg void OnBnClickedButton9();
afx_msg void OnBnClickedButton10();
afx_msg void OnBnClickedButton11();
afx_msg void OnBnClickedButton12();
afx_msg void OnBnClickedButton15();
afx_msg void OnBnClickedButton16();
afx_msg void OnBnClickedButton13();
afx_msg void OnBnClickedButton14();
afx_msg void OnBnClickedButton17();
afx_msg void OnBnClickedButton18();
afx_msg void OnBnClickedopenthread();
afx_msg void OnBnClickedclosethread();
virtual void Run(void);
将 ADS_C_ProgramDlg.cpp 文件的编程分成分成两个模块
1.数据初始化
数据初始化包括:建立路由、获取NetID、设置PLC端口号、确定端口号、全局变量初始化。
本工程设定数据如下:
//建立路由、获取NetID、设置PLC端口号
pAddr = &Addr;
nPort = AdsPortOpen();
nErr = AdsGetLocalAddress(pAddr);
//确定端口号
pAddr->port =851;
//全局变量初始化
//bool 变量
writebool = 0;
readbool = 0;
//Int
writeint = 0;
readint = 0;
//long
writelong = 0;
readlong = 0;
//single
writesingle = 0;
readsingle = 0;
//double
writedouble = 0;
readdouble = 0;
writestruct.test1 = 0;
writestruct.dummy1 = 0;
writestruct.dummy2 = 0;
writestruct.dummy3 = 0;
writestruct.test2 = 0;
writestruct.dummy4 = 0;
writestruct.test3 = 0;
writestruct.test4 = 0;
writestruct.test5 = 0;
//数组初始化
int i;
for (i=0;i<5;i++)
{
writearray[i]=0;
readarray[i]=0;
}
2.ADS通讯
本工程的ADS通讯部分涉及两个内容,数据写入和数据读取。这里以Int型数据传输为例。
1)使用语句
①.定义句柄
ULONG lHdlVar;
②.获取下位机变量
char szVar[]={"MAIN.IntTest"};
③. 获得句柄
nErr = AdsSyncReadWriteReq(pAddr,ADSIGRP_SYM_HNDBYNAME,0x0,sizeof(lHdlVar),&lHdlVar,sizeof(szVar),szVar);
③. 写入值
nErr = AdsSyncWriteReq(pAddr,ADSIGRP_SYM_VALBYHND,lHdlVar,2,&writeint);
④. 读出值
nErr = AdsSyncReadReq(pAddr,ADSIGRP_SYM_VALBYHND,lHdlVar,2,&readint);
⑤. 释放句柄
nErr = AdsSyncWriteReq(pAddr,ADSIGRP_SYM_RELEASEHND,0,sizeof(lHdlVar),&lHdlVar);
2)完整代码
//WriteInt
void CADS_C_ProgramDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
ULONG lHdlVar;
char szVar[]={"MAIN.IntTest"};
CString str;
nErr = AdsSyncReadWriteReq(pAddr,ADSIGRP_SYM_HNDBYNAME,0x0,sizeof(lHdlVar),&lHdlVar,sizeof(szVar),szVar);
GetDlgItemText(IDC_EDIT7,str);
writeint=atoi(str);
nErr = AdsSyncWriteReq(pAddr,ADSIGRP_SYM_VALBYHND,lHdlVar,2,&writeint);
nErr = AdsSyncWriteReq(pAddr,ADSIGRP_SYM_RELEASEHND,0,sizeof(lHdlVar),&lHdlVar);
}
//ReadInt
void CADS_C_ProgramDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
ULONG lHdlVar;
char szVar [] = {"MAIN.IntTest"};
CString str;
nErr = AdsSyncReadWriteReq(pAddr,ADSIGRP_SYM_HNDBYNAME,0x0,sizeof(lHdlVar),&lHdlVar,sizeof(szVar),&szVar);
nErr = AdsSyncReadReq(pAddr,ADSIGRP_SYM_VALBYHND,lHdlVar,2,&readint);
nErr = AdsSyncWriteReq(pAddr,ADSIGRP_SYM_RELEASEHND,0,sizeof(lHdlVar),&lHdlVar);
str.Format("%d",readint);
SetDlgItemText(IDC_EDIT8,str);
}
在整个工程中,ADS通讯都是在上位机中编写的,这使得下位机变简单。
首先,在 TwinCAT Project 模板下建立一个名为:ADS_PLC_Program 的文件。然后,整个程序分成两部分:
1.在建立一个工程后,我们需要在MAIN(PRG)中的变量区定义变量。代码如下:
PROGRAM MAIN
VAR
BoolTest : BOOL; //布尔值测试
IntTest : INT; //整型测试
LongTest : DINT; //长整型测试
SingleTest : REAL; //单精度测试
DoubleTest : LREAL; //双精度测试
StringTest : STRING; //字符串测试
readstringlen : INT; //数组测试
plcstruc : plcstructure; //结构体测试
plcarraytest : ARRAY[1..5] OF INT; //五个整型
override : ARRAY[1..10] OF LREAL; //10个长实型
END_VAR
2.在DUTs建立新的数据单元(plcstructure)声明一个结构体。代码如下:
TYPE plcstructure :
STRUCT
plcs1 : BOOL;
dummy1:BOOL;
dummy2:BOOL;
dummy3:BOOL;
plcs2:INT;
dummy4:INT;
plcs3:DINT;
plcs4:REAL;
plcs5:LREAL;
END_STRUCT
END_TYPE
在本工程中,不需要下位机实现任何功能,所以随意写一句即可,如下图所示:
readstringlen:=LEN(StringTest);
现在同时运行上位机和下位机,就可以实现ADS的通讯了。
ADS通讯并无难点,有固定的编程思维和程序模板。值得注意是,上位机中两个ADS通讯头文件的添加有点复杂。学习完本教程后,最好做到知识与实践相结合。
小白将上述例程放在附件中,包含上位机、下位机和例程说明三部分,并且涉及到的知识点都做了详细的注释。例程只是辅助,若能通过上面的讲解独自实现功能,可称为学以成。
例程。链接:https://download.csdn.net/download/robot_starscream/10788998
功能包括: ADS通讯、多媒体定时器、线程的应用。训练技能以ADS通讯为主。