回复:intouch如何读取S7-200 V区中的数据

天枰

  • 帖子

    315
  • 精华

    10
  • 被关注

    15

论坛等级:侠士

注册时间:2007-08-09

普通 普通 如何晋级?

发布于 2008-05-28 13:43:40

0楼

//此程式适用于S7-200 CPU226CN,因没有加入设定PPI通讯协议及启停PLC命令,故需要你先把PLC中程序清空,然后随便监控一下PLC,再运行测试程式,..
//目前缺少一次写多个字节的命令格式,我自己根据监控数据构造的命令PLC不执行,有谁知道可以把数据帧贴出来...我用原程序交换
#include "stdafx.h"

#include "windows.h"
#include "stdlib.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#include "ppi.h"

void test(char* name,int bandrate,int addr)
{
CPPIComm ComPort;
char buf[1024];

if(ComPort.Open( name,bandrate))
{
memset(buf,0,sizeof(buf));
if(ComPort.ReadPLCInfo(buf,0,addr))
{
printf("\r\nPLC信息如下:\r\n\t");
printf(buf);
printf("\r\n");
}
else
{
printf("\r\n无法正确读取PLC信息..\r\n\t");
printf("程式退出...\r\n");
return;
}

/* memset(buf,0,sizeof(buf));
int n = ComPort.ReadByte(buf,0x83,//MB
2,//字节
0,//数据块号,读V区时应填1
0,//偏移
16,//数据数量
0,//本机地址
1);//PLC端口地址
if(n > 0 )
{
printf("\r\n读到以下数据:\r\n\t");
for(int i=0;i {
if((i%8 == 0)&&( i>0 ))
printf("\r\n\t");
printf("%4x",*(unsigned char*)(buf+i));
}
printf("\r\n");
}

int x;
printf( "Input a 16Bit Number:");
scanf( "%x",&x);
ComPort.WriteByte(x,0x83,0,0,0,1);

Sleep(1000);*/

ComPort.WriteWord(0xffff,0x82,0,0,0,addr);
Sleep(3000);
ComPort.WriteWord(0xff00,0x82,0,0,0,addr);
Sleep(1000);
ComPort.WriteLong(0x00ff,0x82,0,0,0,addr);
Sleep(1000);
ComPort.WriteLong(0,0x82,0,0,0,addr);
Sleep(2000);

for(int k = 0;k<16;k++)
{
ComPort.WriteWord(1< Sleep(500);
}

ComPort.WriteLong(0,0x82,0,0,0,addr);
Sleep(2000);

for(k = 0;k<16;k++)
{
ComPort.WriteWord(0x8000>>k,0x82,0,0,0,addr);
Sleep(500);
}

ComPort.WriteLong(0x5555,0x82,0,0,0,addr);
Sleep(1000);

for(k = 0;k<16;k++)
{
ComPort.WriteWord(0x5555< Sleep(500);
}
ComPort.WriteLong(0,0x82,0,0,0,addr);
Sleep(2000);
ComPort.WriteLong(0xaaaa,0x82,0,0,0,addr);
for(k = 0;k<16;k++)
{
ComPort.WriteWord(0xaaaa>>k,0x82,0,0,0,addr);
Sleep(500);
}
ComPort.WriteLong(0,0x82,0,0,0,addr);
Sleep(2000);
for(k = 0;k<16;k++)
{
ComPort.WriteWord(0xffff>>k,0x82,0,0,0,addr);
Sleep(500);
}
ComPort.WriteLong(0,0x82,0,0,0,addr);
Sleep(2000);
for(k = 0;k<16;k++)
{
ComPort.WriteWord(0xffff< Sleep(500);
}
ComPort.WriteWord(0,0x82,0,0,0,addr);

return;
}
printf("初始化失败!\n");
}

int main(int argc, char* argv[])
{

printf( "\r\n***************PC/PPI协议测试**************\r\n");
if(argc == 4)
{
test(argv[1],atoi(argv[2]),atoi(argv[3]));
return 0;
}
int addr;
printf( "\t合令行格式如下:\r\n");
printf( "\t%s COM1 19200 1\r\n\r\n",argv[0]);

printf( "\t请将PLC接入COM1\r\n");
printf( "\t请设定通讯速率为19200\r\n");
printf( "\t请输入PLC站点地址:");
scanf( "%x",&addr);
test("com1",19200,addr);
return -1;
}
//////////////////////////////////////////////////////////////////////
// CPPIComm Class
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#include "ppi.h"

CPPIComm::CPPIComm()
{
m_hComHandle = INVALID_HANDLE_VALUE;
memset(&m_strComName,0,sizeof(m_strComName));
m_lWaitTime = 40;
}

CPPIComm::~CPPIComm()
{

}


BOOL CPPIComm::Open(char *name,UINT BaudRate,UINT iParity,unsigned char DataBits,unsigned char StopBits)
{
if (NULL == name)
{
if(INVALID_HANDLE_VALUE != m_hComHandle)
{
CloseHandle(m_hComHandle);
}
return FALSE;
}
DCB dcb;
memset(&dcb, 0, sizeof(dcb));
dcb.DCBlength = sizeof(dcb);
dcb.BaudRate = BaudRate;
dcb.fBinary = TRUE;
......

}

int CPPIComm::WriteComm(char *buffer, int len)
{
if(INVALID_HANDLE_VALUE == m_hComHandle)
return 0;
PurgeComm(m_hComHandle,PURGE_TXCLEAR);
DWORD dwWriteLength = 0;
OVERLAPPED m_ovWriter;
memset(&m_ovWriter,0,sizeof(OVERLAPPED));
if (!WriteFile(m_hComHandle,buffer,len,&dwWriteLength,&m_ovWriter))
{
if (GetLastError() == ERROR_IO_PENDING)
GetOverlappedResult(m_hComHandle,&m_ovWriter,&dwWriteLength,TRUE);
}
EscapeCommFunction(m_hComHandle,CLRRTS);
PurgeComm(m_hComHandle,PURGE_RXCLEAR);
return dwWriteLength;
}

int CPPIComm::ReadComm(char *buffer)
{
Sleep(m_lWaitTime);
DWORD dwErrFlag;
COMSTAT comState;
ClearCommError(m_hComHandle,&dwErrFlag,&comState);
if (comState.cbInQue)
{
OVERLAPPED ovReader;
DWORD ReadLength = 0;
memset(&ovReader,0,sizeof(OVERLAPPED));
if (ReadFile(m_hComHandle,buffer,comState.cbInQue,&ReadLength,&ovReader))
return ReadLength;
else
return 0;
}
return 0;
}

bool CPPIComm::ReadPLCInfo(char *info,unsigned char addrsrc, unsigned char addrdes)
{......
}

int CPPIComm::ReadByte(char* buf,unsigned char memory_area,char DataLen,int DB_num,int Offset,int repetition_factor,unsigned char addrsrc,unsigned char addrdes)
{....
//构建读PLC数据区命令,略...
//计算校验和
BYTE FCS = 0;
for(int i = 4;i<=30;i++)
FCS+=cmd[i];
cmd[31] = FCS;
WriteComm(cmd,33);

char recvbuf[512];
memset(recvbuf,0,sizeof(recvbuf));
ReadComm(recvbuf);

//确认命令 {0x10,目标地址,源地址,0x5C,FCS,0x16};
char cmd_reqdata[] = {0x10,0x01,0x00,0x5C,0x5D,0x16};
cmd_reqdata[1] = addrdes;
cmd_reqdata[2] = addrsrc;

FCS = 0;
for(i = 1;i<=3;i++)
FCS+=cmd_reqdata[i];
cmd_reqdata[4] = FCS;
WriteComm(cmd_reqdata,6);

memset(recvbuf,0,sizeof(recvbuf));
int recvlen = ReadComm(recvbuf);
if(recvlen > 27)
{
for(i = 25;i buf[i-25] = recvbuf[i];
return recvlen-27;
}
return 0;
}


bool CPPIComm::WriteByte(char byte, unsigned char memory_area, int DB_num, int Offset, unsigned char addrsrc, unsigned char addrdes)
{
.....
}

bool CPPIComm::WriteLong(long n, unsigned char memory_area, int DB_num, int Offset, unsigned char addrsrc, unsigned char addrdes)
{
.......
}


bool CPPIComm::WriteWord(int word, unsigned char memory_area, int DB_num, int Offset, unsigned char addrsrc, unsigned char addrdes)
{
.....
}
评论
编辑推荐: 关闭

请填写推广理由:

本版热门话题

SIMATIC S7-200

共有33266条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

  • 分享

  • 只看
    楼主

top
X 图片
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。