在PLC的程序中,添加如下变量
intCount AT %Q*: DINT; 可读
intVarIn AT %I* : DINT:=0; 可写
PLCVar : DINT:=0; 可读可写
上位机HMI程序(参考InfoSys中的例子)
1.声明变量:
//===========================
long nErr, nPort;
AmsAddr Addr;
PAmsAddr pAddr;
ULONG lHdlVarR,lHdlVarW;
int nData;
CString strTmp;
ULONG hNotification;
AdsNotificationAttrib adsNotificationAttrib;
//===========================
2.初始化变量和属性
//========================================================
pAddr = &Addr;
nData = 0;
// Open communication port for local PLC (Run-time system 1)
nPort = AdsPortOpen();
nErr = AdsGetLocalAddress(pAddr); //获取本地的AmsNetId 和 Port
if (nErr)
{
MessageBox("Error: AdsGetLocalAddress: ");
return 0;
}
pAddr->port = AMSPORT_R0_PLC_RTS1; //Port为第一个PLC任务
// Specify attributes of the notification
adsNotificationAttrib.cbLength = 16; //读取数据长度
adsNotificationAttrib.nTransMode = ADSTRANS_SERVERONCHA; //当变化是响应回调函数
adsNotificationAttrib.nMaxDelay = 1000000; // 100ms
adsNotificationAttrib.nCycleTime = 1000000; // 100ms
3.获取变量的句柄
// Fetch handle for an <szVar> PLC variable
char szVarR[]= {"MAIN.intCount"}; //读
nErr = AdsSyncReadWriteReq(pAddr, ADSIGRP_SYM_HNDBYNAME, 0x0,
sizeof(lHdlVarR), &lHdlVarR, sizeof(szVarR), szVarR);
char szVarW[]= {"MAIN.intVarIn"}; //写
nErr = AdsSyncReadWriteReq(pAddr, ADSIGRP_SYM_HNDBYNAME, 0x0,
sizeof(lHdlVarW), &lHdlVarW, sizeof(szVarW), szVarW);
4.通过上述的句柄就可以实现对PLC中的数据进行读写 或 设置“事件驱动”的方式获取数据
4.1读数据
nErr = AdsSyncReadReq( pAddr, ADSIGRP_SYM_VALBYHND, lHdlVarR, sizeof(nData), &nData );
if (nErr)
MessageBox("Fehler: AdsSyncReadReq: ");
else
strTmp.Format("%d", nData) ;
m_strSysData="Fehler: AdsSyncReadReq: " + strTmp;
4.2写数据
UpdateData();
nData=atoi(m_strWriteData);
nErr = AdsSyncWriteReq(pAddr, ADSIGRP_SYM_VALBYHND, lHdlVarW, sizeof(nData), &nData);
if (nErr)
MessageBox("Error: AdsSyncWriteReq: ");
4.3启动“事件驱动”
1)声明回调函数
void __stdcall SymbolChanged(AmsAddr*, AdsNotificationHeader*, unsigned long);
2)启动“事件驱动”
nErr = AdsSyncAddDeviceNotificationReq(pAddr, ADSIGRP_SYM_VALBYHND,
lHdlVarR, &adsNotificationAttrib,
SymbolChanged, NULL, &hNotification);
if (nErr)
{
MessageBox("Error: AdsSyncAddDeviceNotificationReq: ");
return;
}
//================以下为回调函数部分========================
void __stdcall SymbolChanged(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser)
{
CString strDataFromNotify,strTmp;
CEx02Dlg *dlg=(CEx02Dlg *)AfxGetMainWnd();
strDataFromNotify=""; strTmp="";
// Output value of the variable
strTmp.Format("Value:%d/n", *(int *)pNotification->data); //data中的数据为地址
strDataFromNotify+=strTmp;
strTmp.Format("Notification:%d/n",pNotification->hNotification);
strDataFromNotify+=strTmp;
strTmp.Format("SampleSize:%d/n",pNotification->cbSampleSize);
strDataFromNotify+=strTmp;
strTmp.Format("hUser:%d/n",hUser);
strDataFromNotify+=strTmp;
dlg->m_strNtyData=strDataFromNotify;
dlg->SetDlgItemText(IDC_STATIC_Data2,strDataFromNotify); //更新CEX02类中的窗体
}
4.4关闭“事件驱动”
nErr = AdsSyncDelDeviceNotificationReq(pAddr, hNotification);
if (nErr)
{
MessageBox("Error: AdsSyncDelDeviceNotificationReq: ");
return;
}
5.关闭端口
nErr = AdsPortClose();
if (nErr)
MessageBox("Error: AdsPortClose: ");
以上是对int型变量进行读写的简单实验。